diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1b0b7e038a94c..95baa57546b67d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,27 +10,11 @@ jobs: - uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/magic-nix-cache-action@main - run: nix build . --print-build-logs - - uses: actions/upload-artifact@v4 + - uses: cloudflare/pages-action@v1 with: - name: result - path: result/ - - - run: rm -f tools/wasm/vmlinux.wasm && cp result/vmlinux.wasm tools/wasm/ - - uses: actions/configure-pages@v4 - - uses: actions/upload-pages-artifact@v3 - with: - path: tools/wasm/ - - deploy: - runs-on: ubuntu-22.04 - needs: build - if: github.ref == 'refs/heads/wasm' - permissions: - pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - id: deployment - uses: actions/deploy-pages@v4 + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: 7d87194d9d4af2959fb81de343dd63d9 + projectName: linux + directory: result/ + gitHubToken: ${{ secrets.GITHUB_TOKEN }} + wranglerVersion: "3" diff --git a/arch/wasm/Kconfig b/arch/wasm/Kconfig index 247a55f7cf7bd1..4faa4e7de42713 100644 --- a/arch/wasm/Kconfig +++ b/arch/wasm/Kconfig @@ -11,7 +11,6 @@ config WASM select BUG select FLATMEM select GENERIC_ATOMIC64 - select GENERIC_BUG select GENERIC_CSUM select GENERIC_HWEIGHT select HAS_CURRENT_STACK_POINTER @@ -54,8 +53,7 @@ config PAGE_SIZE_64KB bool config GENERIC_BUG - def_bool y - depends on BUG + bool config GENERIC_HWEIGHT def_bool y diff --git a/arch/wasm/Makefile b/arch/wasm/Makefile index 1b11ffc0216ce7..93a13d8f956bb7 100644 --- a/arch/wasm/Makefile +++ b/arch/wasm/Makefile @@ -3,7 +3,7 @@ LD = wasm-ld WASM_FEATURES = -matomics -mbulk-memory -mexception-handling -mextended-const -mmultivalue -mmutable-globals -mnontrapping-fptoint -mreference-types -mrelaxed-simd -msign-ext -msimd128 cflags-y += -Wno-incompatible-library-redeclaration '-D__builtin_return_address=wasm_return_address' $(WASM_FEATURES) -ldflags-y += --import-memory +ldflags-y += --import-memory --shared-memory --max-memory=4294967296 --no-gc-sections KBUILD_CFLAGS += $(cflags-y) KBUILD_AFLAGS += $(aflags-y) @@ -16,6 +16,9 @@ arch/wasm/vmlinux.wasm: vmlinux $(Q)$(MAKE) vmlinux $(Q)cp vmlinux $@ +tools/wasm/vmlinux.wasm: vmlinux + $(Q)cp vmlinux $@ + define archhelp echo '* vmlinux.wasm - Kernel binary (arch/$(ARCH)/vmlinux.wasm)' endef diff --git a/arch/wasm/configs/defconfig b/arch/wasm/configs/defconfig index e69de29bb2d1d6..c0e558e2d67980 100644 --- a/arch/wasm/configs/defconfig +++ b/arch/wasm/configs/defconfig @@ -0,0 +1,34 @@ +# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +CONFIG_KERNEL_XZ=y +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +# CONFIG_SLAB is not set +# CONFIG_SLUB is not set +CONFIG_SLOB=y + +CONFIG_PRINTK=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_BUG=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_MISC=y +CONFIG_DEBUG_NOMMU_REGIONS=y +CONFIG_DEBUG_VM=y +CONFIG_EARLY_PRINTK=y +CONFIG_EMBEDDED=y +CONFIG_EXPERT=y +# CONFIG_KALLSYMS is not set +# CONFIG_MMU is not set +CONFIG_UACCESS_MEMCPY=y +CONFIG_PRINTK_TIME=y +CONFIG_EXT4_FS=y +CONFIG_NET=y + + +CONFIG_EMBEDDED=y \ No newline at end of file diff --git a/arch/wasm/include/asm/wasm_imports.h b/arch/wasm/include/asm/wasm_imports.h index cfaa76d41b1bb1..58f17207347f49 100644 --- a/arch/wasm/include/asm/wasm_imports.h +++ b/arch/wasm/include/asm/wasm_imports.h @@ -6,7 +6,8 @@ #define import(name) __attribute__((import_module("kernel"), import_name(name))) -import("print") void wasm_print(const char *msg, size_t len); +import("boot_console_write") void wasm_boot_console_write(const char *msg, size_t len); +import("boot_console_close") void wasm_boot_console_close(void); import("set_irq_enabled") void wasm_set_irq_enabled(int enabled); import("get_irq_enabled") int wasm_get_irq_enabled(void); @@ -21,6 +22,4 @@ import("get_now_nsec") unsigned long long wasm_get_now_nsec(void); #undef import -#define wasm_puts(msg) wasm_print(msg, strlen(msg)) - #endif diff --git a/arch/wasm/kernel/Makefile b/arch/wasm/kernel/Makefile index edfcc1eca16d87..278522c692e1c6 100644 --- a/arch/wasm/kernel/Makefile +++ b/arch/wasm/kernel/Makefile @@ -1,6 +1,7 @@ extra-y := vmlinux.lds obj-y += \ + cpuinfo.o \ early_printk.o \ irq.o \ process.o \ diff --git a/arch/wasm/kernel/cpuinfo.c b/arch/wasm/kernel/cpuinfo.c new file mode 100644 index 00000000000000..7e13209f4d4110 --- /dev/null +++ b/arch/wasm/kernel/cpuinfo.c @@ -0,0 +1,38 @@ +#include + +static void percpu_print(void *arg) +{ + struct seq_file *m = arg; + seq_printf(m, "processor : %d\n", smp_processor_id()); + seq_printf(m, "\n"); +} + +static int c_show(struct seq_file *m, void *v) +{ + int cpu; + + for_each_online_cpu(cpu) + smp_call_function_single(cpu, percpu_print, m, true); + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +static void c_stop(struct seq_file *m, void *v) {} + +const struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show, +}; diff --git a/arch/wasm/kernel/early_printk.c b/arch/wasm/kernel/early_printk.c index ca5f067d63e789..0a0d3905defd68 100644 --- a/arch/wasm/kernel/early_printk.c +++ b/arch/wasm/kernel/early_printk.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -8,12 +7,19 @@ static void early_console_write(struct console *con, const char *s, unsigned int n) { - wasm_print(s, n); + wasm_boot_console_write(s, n); +} + +static int early_console_exit(struct console *con) +{ + wasm_boot_console_close(); + return 0; } static struct console early_console_dev = { .name = "earlycon", .write = early_console_write, + .exit = early_console_exit, .flags = CON_BOOT, .index = -1, }; diff --git a/arch/wasm/kernel/irq.c b/arch/wasm/kernel/irq.c index 862b67832688ce..f8943faec39056 100644 --- a/arch/wasm/kernel/irq.c +++ b/arch/wasm/kernel/irq.c @@ -1,4 +1,15 @@ +#include +#include +#include + void init_IRQ(void) { - __builtin_trap(); + pr_info("init irq\n"); + irqchip_init(); +} + +int show_interrupts(struct seq_file *p, int prec) +{ + seq_printf(p, "nothing to see here\n"); + return 0; } diff --git a/arch/wasm/kernel/setup.c b/arch/wasm/kernel/setup.c index ebac3c79aab2a2..d484972dbd6556 100644 --- a/arch/wasm/kernel/setup.c +++ b/arch/wasm/kernel/setup.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -24,9 +25,19 @@ uintptr_t __stop___ex_table, __start___ex_table, __sched_class_highest, __per_cpu_load, __per_cpu_end, _stext, _etext, _sinittext, _einittext, __sched_text_start, __sched_text_end, __cpuidle_text_start, __cpuidle_text_end, __lock_text_start, __lock_text_end, __bss_start, - __bss_stop, _sdata, _edata, __reservedmem_of_table; + __bss_stop, _sdata, _edata, __reservedmem_of_table, __start_builtin_fw, + __end_builtin_fw; + +struct screen_info screen_info = {}; + +// https://github.com/llvm/llvm-project/blob/d2e4a725da5b4cbef8b5c1446f29fed1487aeab0/lld/wasm/Symbols.h#L515 void __init __wasm_call_ctors(void); +extern void __stack_low; +extern void __stack_high; +extern void __heap_base; +extern void __heap_end; + int __init setup_early_printk(char *buf); static char wasm_dt[1024]; @@ -36,10 +47,18 @@ void __init _start(void) __wasm_call_ctors(); setup_early_printk(NULL); + pr_info("heap: %zu->%zu=%zu\n", (uintptr_t)&__heap_base, + (uintptr_t)&__heap_end, + (uintptr_t)&__heap_end - (uintptr_t)&__heap_base); + pr_info("stack: %zu->%zu=%zu\n", (uintptr_t)&__stack_low, + (uintptr_t)&__stack_high, + (uintptr_t)&__stack_high - (uintptr_t)&__stack_low); wasm_get_dt(wasm_dt, ARRAY_SIZE(wasm_dt)); early_init_dt_scan(wasm_dt); + memblock_reserve(0, (phys_addr_t)&__heap_base); + start_kernel(); } @@ -49,16 +68,7 @@ void __init setup_arch(char **cmdline_p) strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start < initrd_end && - !mem_reserve(__pa(initrd_start), __pa(initrd_end))) - initrd_below_start_ok = 1; - else - initrd_start = 0; -#endif - parse_early_param(); - early_printk("hello!\n"); unflatten_device_tree(); @@ -66,6 +76,8 @@ void __init setup_arch(char **cmdline_p) smp_init_cpus(); #endif + memblock_dump_all(); + zones_init(); } @@ -77,17 +89,17 @@ void __init setup_arch(char **cmdline_p) void machine_restart(char *cmd) { - early_printk("restart: %s", cmd); + pr_info("restart: %s", cmd); __builtin_trap(); } void machine_halt(void) { - early_printk("halt"); + pr_info("halt"); __builtin_trap(); } void machine_power_off(void) { - early_printk("poweroff"); + pr_info("poweroff"); __builtin_trap(); } diff --git a/arch/wasm/mm/init.c b/arch/wasm/mm/init.c index 9b4db403ea0f4c..1ecb90bcdf5031 100644 --- a/arch/wasm/mm/init.c +++ b/arch/wasm/mm/init.c @@ -27,10 +27,10 @@ void __init mem_init(void) { void *alloc; - early_printk("mem_init\n"); + pr_info("mem_init\n"); memblock_free_all(); alloc = kmalloc(64, 0); - early_printk("malloc() = %p\n", alloc); + pr_info("malloc() = %p\n", alloc); } diff --git a/flake.nix b/flake.nix index db59d8ce51fe95..1d167171eb8bfa 100644 --- a/flake.nix +++ b/flake.nix @@ -38,11 +38,17 @@ lld libllvm wabt + esbuild ]; enableParallelBuilding = true; - buildPhase = "make -j$NIX_BUILD_CORES tinyconfig arch/wasm/vmlinux.wasm"; - installPhase = "mkdir $out && cp arch/wasm/vmlinux.wasm $out/"; + configurePhase = "make -j$NIX_BUILD_CORES tinyconfig debug.config"; + buildPhase = "make -j$NIX_BUILD_CORES arch/wasm/vmlinux.wasm tools/wasm"; + installPhase = '' + mkdir $out + cp -r tools/wasm/* $out/ + cp arch/wasm/vmlinux.wasm $out/ + ''; }; }); }; diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index db13bb620f527e..71419ae6abc4e3 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -7,6 +7,11 @@ #include #include +#ifdef CONFIG_WASM +extern void __global_base, __data_end; +extern void __stack_low, __stack_high; +extern void __heap_base, __heap_end; +#else /* * Usage guidelines: * _text, _data: architecture specific, don't use them in arch-independent code @@ -57,6 +62,7 @@ extern char __start_opd[], __end_opd[]; extern char __noinstr_text_start[], __noinstr_text_end[]; extern __visible const void __nosave_begin, __nosave_end; +#endif /* Function descriptor handling (if any). Override in asm/sections.h */ #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS @@ -127,7 +133,11 @@ static inline bool memory_intersects(void *begin, void *end, void *virt, */ static inline bool init_section_contains(void *virt, size_t size) { +#ifdef CONFIG_WASM + return false; +#else return memory_contains(__init_begin, __init_end, virt, size); +#endif } /** @@ -141,7 +151,11 @@ static inline bool init_section_contains(void *virt, size_t size) */ static inline bool init_section_intersects(void *virt, size_t size) { +#ifdef CONFIG_WASM + return false; +#else return memory_intersects(__init_begin, __init_end, virt, size); +#endif } /** @@ -156,12 +170,17 @@ static inline bool init_section_intersects(void *virt, size_t size) */ static inline bool is_kernel_core_data(unsigned long addr) { +#ifdef CONFIG_WASM + if (addr >= (unsigned long)&__global_base && addr < (unsigned long)&__data_end) + return true; +#else if (addr >= (unsigned long)_sdata && addr < (unsigned long)_edata) return true; if (addr >= (unsigned long)__bss_start && addr < (unsigned long)__bss_stop) return true; +#endif return false; } @@ -176,8 +195,12 @@ static inline bool is_kernel_core_data(unsigned long addr) */ static inline bool is_kernel_rodata(unsigned long addr) { +#ifdef CONFIG_WASM + return false; +#else return addr >= (unsigned long)__start_rodata && addr < (unsigned long)__end_rodata; +#endif } /** @@ -190,8 +213,12 @@ static inline bool is_kernel_rodata(unsigned long addr) */ static inline bool is_kernel_inittext(unsigned long addr) { +#ifdef CONFIG_WASM + return false; +#else return addr >= (unsigned long)_sinittext && addr < (unsigned long)_einittext; +#endif } /** @@ -205,8 +232,12 @@ static inline bool is_kernel_inittext(unsigned long addr) */ static inline bool __is_kernel_text(unsigned long addr) { +#ifdef CONFIG_WASM + return false; +#else return addr >= (unsigned long)_stext && addr < (unsigned long)_etext; +#endif } /** @@ -221,10 +252,14 @@ static inline bool __is_kernel_text(unsigned long addr) */ static inline bool __is_kernel(unsigned long addr) { +#ifdef CONFIG_WASM + return false; +#else return ((addr >= (unsigned long)_stext && addr < (unsigned long)_end) || (addr >= (unsigned long)__init_begin && addr < (unsigned long)__init_end)); +#endif } #endif /* _ASM_GENERIC_SECTIONS_H_ */ diff --git a/include/linux/slab.h b/include/linux/slab.h index f4229d5bcc845e..45efc6c553b826 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -561,7 +561,6 @@ static __always_inline __alloc_size(1) void *kmalloc(size_t size, gfp_t flags) #ifndef CONFIG_SLOB static __always_inline __alloc_size(1) void *kmalloc_node(size_t size, gfp_t flags, int node) { - early_printk("kmalloc_node(%zu, %#x, %d)\n", size, flags, node); if (__builtin_constant_p(size)) { unsigned int index; diff --git a/init/main.c b/init/main.c index d4323c7b66571a..376d48df143d05 100644 --- a/init/main.c +++ b/init/main.c @@ -1018,7 +1018,7 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) * timer interrupt). Full topology setup happens at smp_init() * time - but meanwhile we still have a functioning scheduler. */ - sched_init(); + // sched_init(); if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n")) @@ -1159,8 +1159,10 @@ static void __init do_ctors(void) * normal setup code as it's just a normal ELF binary, so we * cannot do it again - but we do need CONFIG_CONSTRUCTORS * even on UML for modules. + * Likewise, the WebAssembly linker combines all constructors + * into a single function which is called in the arch startup. */ -#if defined(CONFIG_CONSTRUCTORS) && !defined(CONFIG_UML) +#if defined(CONFIG_CONSTRUCTORS) && !defined(CONFIG_UML) && !defined(CONFIG_WASM) ctor_fn_t *fn = (ctor_fn_t *) __ctors_start; for (; fn < (ctor_fn_t *) __ctors_end; fn++) diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config index e8db8d93866177..62f7aff14aa875 100644 --- a/kernel/configs/debug.config +++ b/kernel/configs/debug.config @@ -9,7 +9,7 @@ # printk and dmesg options # CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DYNAMIC_DEBUG=y +CONFIG_PRINTK=y CONFIG_PRINTK_CALLER=y CONFIG_PRINTK_TIME=y CONFIG_SYMBOLIC_ERRNAME=y diff --git a/kernel/panic.c b/kernel/panic.c index ec0ccbc30f84a1..494773be566e19 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -37,10 +37,6 @@ #include #include -#ifdef CONFIG_WASM -#include -#endif - #define PANIC_TIMER_STEP 100 #define PANIC_BLINK_SPD 18 @@ -334,12 +330,6 @@ void panic(const char *fmt, ...) if (len && buf[len - 1] == '\n') buf[len - 1] = '\0'; - #ifdef CONFIG_WASM - // TODO(wasm): wire real printk to console - wasm_puts("Kernel panic - not syncing: "); - wasm_print(buf, len); - #endif - pr_emerg("Kernel panic - not syncing: %s\n", buf); #ifdef CONFIG_DEBUG_BUGVERBOSE /* @@ -739,7 +729,11 @@ EXPORT_SYMBOL(__warn_printk); static int clear_warn_once_set(void *data, u64 val) { generic_bug_clear_once(); +#ifdef CONFIG_WASM + pr_warn("Clearing warning state is unsupported\n"); +#else memset(__start_once, 0, __end_once - __start_once); +#endif return 0; } diff --git a/kernel/params.c b/kernel/params.c index 9fe5a1f4f86d44..2bcf21f27342ce 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -829,27 +830,28 @@ static void __init kernel_add_sysfs_param(const char *name, */ static void __init param_sysfs_builtin(void) { - const struct kernel_param *kp; - unsigned int name_len; - char modname[MODULE_NAME_LEN]; - - for (kp = __start___param; kp < __stop___param; kp++) { - char *dot; - - if (kp->perm == 0) - continue; - - dot = strchr(kp->name, '.'); - if (!dot) { - /* This happens for core_param() */ - strcpy(modname, "kernel"); - name_len = 0; - } else { - name_len = dot - kp->name + 1; - strlcpy(modname, kp->name, name_len); - } - kernel_add_sysfs_param(modname, kp, name_len); - } +#define X(kp) \ + do { \ + unsigned int name_len; \ + char modname[MODULE_NAME_LEN]; \ + char *dot; \ + \ + if (kp.perm == 0) \ + continue; \ + \ + dot = strchr(kp.name, '.'); \ + if (!dot) { \ + /* This happens for core_param() */ \ + strcpy(modname, "kernel"); \ + name_len = 0; \ + } else { \ + name_len = dot - kp.name + 1; \ + strlcpy(modname, kp.name, name_len); \ + } \ + kernel_add_sysfs_param(modname, &kp, name_len); \ + } while (0); + enumerate_param(X) +#undef X } ssize_t __modver_version_show(struct module_attribute *mattr, @@ -861,24 +863,22 @@ ssize_t __modver_version_show(struct module_attribute *mattr, return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version); } -extern const struct module_version_attribute __start___modver[]; -extern const struct module_version_attribute __stop___modver[]; - static void __init version_sysfs_builtin(void) { - const struct module_version_attribute *vattr; - struct module_kobject *mk; - int err; + pr_warn("version_sysfs_builtin is not implemented"); + // const struct module_version_attribute *vattr; + // struct module_kobject *mk; + // int err; - for (vattr = __start___modver; vattr < __stop___modver; vattr++) { - mk = locate_module_kobject(vattr->module_name); - if (mk) { - err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); - WARN_ON_ONCE(err); - kobject_uevent(&mk->kobj, KOBJ_ADD); - kobject_put(&mk->kobj); - } - } + // for (vattr = __start___modver; vattr < __stop___modver; vattr++) { + // mk = locate_module_kobject(vattr->module_name); + // if (mk) { + // err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); + // WARN_ON_ONCE(err); + // kobject_uevent(&mk->kobj, KOBJ_ADD); + // kobject_put(&mk->kobj); + // } + // } } /* module-related sysfs stuff */ @@ -958,6 +958,7 @@ struct kobj_type module_ktype = { */ static int __init param_sysfs_init(void) { + early_printk("param_sysfs_init"); module_kset = kset_create_and_add("module", &module_uevent_ops, NULL); if (!module_kset) { printk(KERN_WARNING "%s (%d): error creating kset\n", diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 4583f8a42d914b..03a8e72cccb3c5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -8519,6 +8519,22 @@ void __init mem_init_print_info(void) unsigned long init_code_size, init_data_size; physpages = get_num_physpages(); + +#ifdef CONFIG_WASM + pr_info("Memory: %luK/%luK available (%luK reserved, %luK cma-reserved" +#ifdef CONFIG_HIGHMEM + ", %luK highmem" +#endif + ")\n", + K(nr_free_pages()), K(physpages), + K(physpages - totalram_pages() - totalcma_pages), + K(totalcma_pages) +#ifdef CONFIG_HIGHMEM + , K(totalhigh_pages()) +#endif + ); + return; +#else codesize = _etext - _stext; datasize = _edata - _sdata; rosize = __end_rodata - __start_rodata; @@ -8547,6 +8563,7 @@ void __init mem_init_print_info(void) adj_init_size(_sdata, _edata, datasize, __start_rodata, rosize); #undef adj_init_size +#endif pr_info("Memory: %luK/%luK available (%luK kernel code, %luK rwdata, %luK rodata, %luK init, %luK bss, %luK reserved, %luK cma-reserved" #ifdef CONFIG_HIGHMEM diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index d8558b16dee221..9d4abee8209a29 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -47,7 +47,7 @@ objtool-args = $(vmlinux-objtool-args-y) --link quiet_cmd_ld_vmlinux.o = LD $@ ifdef CONFIG_LD_IS_WASMLD cmd_ld_vmlinux.o = \ - $(LD) ${KBUILD_LDFLAGS} -r -o $@ \ + $(LD) ${KBUILD_LDFLAGS} -o $@ \ $(addprefix -T , $(initcalls-lds)) \ --whole-archive vmlinux.a --no-whole-archive \ $(KBUILD_VMLINUX_LIBS) \ diff --git a/tools/Makefile b/tools/Makefile index e497875fc7e3fe..90fb3df2046a36 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -209,6 +209,9 @@ freefall_clean: build_clean: $(call descend,build,clean) +wasm: FORCE + $(call descend,wasm,dist/index.js) + clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_clean \ perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \ vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ diff --git a/tools/wasm/.gitignore b/tools/wasm/.gitignore new file mode 100644 index 00000000000000..d4888bcac3f10e --- /dev/null +++ b/tools/wasm/.gitignore @@ -0,0 +1,3 @@ +.wrangler +vmlinux.wasm +dist diff --git a/tools/wasm/404.html b/tools/wasm/404.html new file mode 100644 index 00000000000000..d3766146d232fd --- /dev/null +++ b/tools/wasm/404.html @@ -0,0 +1,17 @@ + + + + + + linux + + + +

404

+

go home

+ + diff --git a/tools/wasm/Makefile b/tools/wasm/Makefile new file mode 100644 index 00000000000000..d00da25d438004 --- /dev/null +++ b/tools/wasm/Makefile @@ -0,0 +1,2 @@ +dist/index.js: src/*.ts + esbuild --bundle src/index.ts src/worker.ts --outdir=dist --format=esm --splitting --define:self.BUNDLED=true --sourcemap \ No newline at end of file diff --git a/tools/wasm/_headers b/tools/wasm/_headers new file mode 100644 index 00000000000000..56949eb3ff9696 --- /dev/null +++ b/tools/wasm/_headers @@ -0,0 +1,5 @@ +/* + Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp + Cross-Origin-Resource-Policy: cross-origin + diff --git a/tools/wasm/devicetree.mjs b/tools/wasm/devicetree.mjs deleted file mode 100644 index 4bb95ccdcd72a5..00000000000000 --- a/tools/wasm/devicetree.mjs +++ /dev/null @@ -1,188 +0,0 @@ -const FDT_MAGIC = 0xd00dfeed; -const FDT_BEGIN_NODE = 0x00000001; -const FDT_END_NODE = 0x00000002; -const FDT_PROP = 0x00000003; -const FDT_END = 0x00000009; -const NODE_NAME_MAX_LEN = 31; -const PROPERTY_NAME_MAX_LEN = 31; - -function byteswap32(n) { - return ( - ((n & 0xff) << 24) | - ((n & 0xff00) << 8) | - ((n >> 8) & 0xff00) | - ((n >> 24) & 0xff) - ); -} - -export function devicetree( - tree, - reservations = [], - bootCpuId = 0, - maxSize = 1024, -) { - const arr = new Uint8Array(maxSize); - const dv = new DataView(arr.buffer); - let i = 0; - - function u8(n = 0x78) { - const j = i; - dv.setUint8(j, n); - i += 1; - return j; - } - function u32(n = 0x78787878) { - const j = i; - dv.setUint32(j, n); - i += 4; - return j; - } - function u64(n = 0x7878787878787878n) { - const j = i; - dv.setBigUint64(j, BigInt(n)); - i += 8; - return j; - } - function bytes(buf) { - const j = i; - if (!(buf instanceof ArrayBuffer)) { - throw new TypeError( - `Expected ArrayBuffer, got ${buf[Symbol.toStringTag]}`, - ); - } - arr.set(new Uint8Array(buf), i); - i += buf.byteLength; - return j; - } - function stringz(s) { - const j = bytes(new TextEncoder().encode(s).buffer); - u8(0); - return j; - } - function pad(align = 4) { - const offset = i % align; - if (offset !== 0) { - for (let j = 0; j < align - offset; j++) u8(0); - } - } - - try { - const strings = {}; - - u32(FDT_MAGIC); // magic - const totalsize = u32(); - const off_dt_struct = u32(); - const off_dt_strings = u32(); - const off_mem_rsvmap = u32(); - u32(17); // version - u32(16); // last compatible version - u32(bootCpuId); // boot cpuid phys - const size_dt_strings = u32(); - const size_dt_struct = u32(); - - pad(8); - dv.setUint32(off_mem_rsvmap, i); - for (const { address, size } of reservations) { - u64(address); - u64(size); - } - u64(0); - u64(0); - - const begin_dt_struct = i; - dv.setUint32(off_dt_struct, begin_dt_struct); - walkTree(tree, ""); - u32(FDT_END); - dv.setUint32(size_dt_struct, i - begin_dt_struct); - - function walkTree(node, name) { - const startOffset = i; - pad(); - u32(FDT_BEGIN_NODE); - - if (new TextEncoder().encode(name).byteLength > NODE_NAME_MAX_LEN) { - throw new Error("name too long"); - } - stringz(name); - pad(); - - const properties = Object.entries(node).filter( - ([, value]) => - typeof value !== "object" || value.constructor !== Object, - ); - const children = Object.entries(node).filter( - ([, value]) => - typeof value === "object" && value.constructor === Object, - ); - for (const [name, prop] of properties) { - pad(); - u32(FDT_PROP); - const len = u32(); - - if (new TextEncoder().encode(name).byteLength > PROPERTY_NAME_MAX_LEN) { - throw new Error("name too long"); - } - strings[name] ??= []; - strings[name].push(u32()); - - let value; - switch (typeof prop) { - case "number": - value = new Uint32Array([byteswap32(prop)]).buffer; - break; - case "bigint": - value = new BigUint64Array([prop]).buffer; - break; - case "string": - value = new TextEncoder().encode(`${prop}\0`).buffer; - break; - case "object": - switch (prop.constructor) { - case Array: - value = new Uint32Array(prop.map(byteswap32)).buffer; - break; - case Uint8Array: - case Uint16Array: - case Uint32Array: - case BigUint64Array: - value = prop.buffer; - break; - default: - throw new Error( - `unsupported prop type: ${prop.constructor.name}`, - ); - } - break; - case "undefined": - value = new Uint8Array().buffer; - break; - default: - throw new Error(`unsupported prop type: ${typeof prop}`); - } - dv.setUint32(len, value.byteLength); - bytes(value); - pad(); - } - for (const [name, child] of children) walkTree(child, name); - - pad(); - u32(FDT_END_NODE); - return i - startOffset; - } - - const begin_dt_strings = i; - dv.setUint32(off_dt_strings, begin_dt_strings); - for (const [str, refs] of Object.entries(strings)) { - const offset = stringz(str); - for (const ref of refs) dv.setUint32(ref, offset - begin_dt_strings); - } - dv.setUint32(size_dt_strings, i - begin_dt_strings); - - dv.setUint32(totalsize, i); - return arr.slice(0, i); - } catch (err) { - if (err instanceof RangeError) - return devicetree(tree, reservations, bootCpuId, maxSize * 2); - throw err; - } -} diff --git a/tools/wasm/index.html b/tools/wasm/index.html index 8f4a915bbbfe31..c3b23707308dac 100644 --- a/tools/wasm/index.html +++ b/tools/wasm/index.html @@ -4,9 +4,19 @@ linux - - - + + +