Open6
WasmLinux: LKLのリンクエラーをなんとかする
とりあえず、 vmlinux.a
としてLinuxソースをひととおりコンパイルできたようなのでなんとかリンクしたい。LKL自体はCOFFでもリンクできるようだが、基本的にLinuxはELF前提なので色々と難しい。。
jiffies
とりあえず適当にリンカを実行すると:
$ ../_warp/bin/warp-cc -g -nostdlib -Wl,--no-entry -Wl,--export=init -Wl,--error-limit=0 -Wl,--verbose ../vmlinux.a hostwasm_main.c
大量のundefinedが出る。これらを解消していかないといけない。。
wasm-ld: error: ../vmlinux.a(mm/slub.o): undefined symbol: jiffies
jiffiesはリンカスクリプトでaliasされている。
というわけでaliasする必要がある。 ...というかアドレスを計算で埋めてるものはソリューションが無くない。。?
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 717fcb9fb14a..e33d1bfbbf41 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -59,6 +59,10 @@
__visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+#ifdef __wasm__
+extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data __attribute__((alias ("jiffies_64"))) jiffies;
+#endif
+
EXPORT_SYMBOL(jiffies_64);
/*
_ctype
wasm-ld: error: ../vmlinux.a(lib/kstrtox.o): undefined symbol: _ctype
うーん。。ビルドはされている。
$ llvm-nm ./lib/ctype.o
00000000 d .debug_abbrev
00000000 d .debug_line
00000000 d .debug_str
00000000 D _ctype
... ./lib/lib.a
ってのが別にあるのか。。これをリンクすればOKっぽい。
$ ../_warp/bin/warp-cc -g -nostdlib -Wl,--no-entry -Wl,--export=init -Wl,--error-limit=0 -Wl,--verbose -Wl,--Bstatic ../lib/lib.a ../vmlinux.a hostwasm_main.c
init_thread_union
と init_stack
これはリンカスクリプト内で定義される。
うーん。。とりあえず64KiB予約しとくか。。アドレスは同じでよいのでaliasで対応できる。
static char dummy_page[64*1024];
extern char* __attribute((alias ("dummy_page"))) init_thread_union;
extern char* __attribute((alias ("dummy_page"))) init_stack;
残件
見たところ、コンストラクタ系とメモリ空間系に大別されるな。。
コンストラクタ系?
コンストラクタ系はセクションを収集して1箇所にあつめる必要がある。 ...というのはWasmでは不可能なので、これを行っているところは手を入れる必要がある。
(init/main.o): undefined symbol: __initcall0_start
(init/main.o): undefined symbol: __initcall1_start
(init/main.o): undefined symbol: __initcall2_start
(init/main.o): undefined symbol: __initcall3_start
(init/main.o): undefined symbol: __initcall4_start
(init/main.o): undefined symbol: __initcall5_start
(init/main.o): undefined symbol: __initcall6_start
(init/main.o): undefined symbol: __initcall7_start
(init/main.o): undefined symbol: __initcall_end
(init/main.o): undefined symbol: __initcall_start
(init/main.o): undefined symbol: __setup_end
(init/main.o): undefined symbol: __setup_start
(kernel/params.o): undefined symbol: __start___param
(kernel/params.o): undefined symbol: __stop___param
(kernel/printk/printk.o): undefined symbol: __con_initcall_end
(kernel/printk/printk.o): undefined symbol: __con_initcall_start
(kernel/sched/core.o): undefined symbol: __sched_class_highest
(kernel/sched/core.o): undefined symbol: __sched_class_lowest
メモリ空間系?
これらはstubしてしまって良いはず。つまり extable(exception table)はそもそもWasmではハンドルできないし、page関連もLKLでは使われない。
(kernel/extable.o): undefined symbol: __start___ex_table
(kernel/extable.o): undefined symbol: __stop___ex_table
(kernel/extable.o): undefined symbol: _etext
(kernel/kallsyms.o): undefined symbol: __init_begin
(kernel/kallsyms.o): undefined symbol: __init_end
(kernel/kallsyms.o): undefined symbol: _einittext
(kernel/kallsyms.o): undefined symbol: _end
(kernel/kallsyms.o): undefined symbol: _sinittext
(kernel/kallsyms.o): undefined symbol: _stext
(mm/page_alloc.o): undefined symbol: __bss_start
(mm/page_alloc.o): undefined symbol: __bss_stop
(mm/page_alloc.o): undefined symbol: _edata
(mm/page_alloc.o): undefined symbol: _sdata
(mm/util.o): undefined symbol: __end_rodata
(mm/util.o): undefined symbol: __start_rodata
(kernel/stacktrace.o): undefined symbol: __irqentry_text_end
(kernel/stacktrace.o): undefined symbol: __irqentry_text_start
(kernel/stacktrace.o): undefined symbol: __softirqentry_text_end
(kernel/stacktrace.o): undefined symbol: __softirqentry_text_start
とりあえずリンクはできた
とりあえずリンカスクリプトで書いているものはゼロを埋めておいて、リンクだけ通しておいた。
$ ../_warp/bin/warp-cc -g -nostdlib -Wl,--no-entry -Wl,--export=init -Wl,--error-limit=0 \
-Wl,--verbose -Wl,--Map=out.map ../lib/lib.a ../vmlinux.a hostwasm_main.c