diff --git a/Makefile b/Makefile index 5e8c93171f8f4663be45cd1d3015de76c87f27e2..b28f52b4cfcb48e7376a0fad915627de7c082522 100644 --- a/Makefile +++ b/Makefile @@ -307,7 +307,8 @@ export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_ve # Files to ignore in find ... statements export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o \ - -name CVS -o -name .pc -o -name .hg -o -name .git \) \ + -name CVS -o -name .pc -o -name .hg -o -name .git \ + -o -name sysroot \) \ -prune -o export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \ --exclude CVS --exclude .pc --exclude .hg --exclude .git @@ -587,6 +588,7 @@ core-y := arch/$(SRCARCH)/ kernel-y := kernel/ init-y := init/ libs-y := lib/ +xentium-y := dsp/ # this should be CONFIG_XENTIUM_WHATEVER -include arch/$(ARCH)/Makefile @@ -594,7 +596,8 @@ leanos-dirs := $(patsubst %/,%,$(filter %/, \ $(init-y) \ $(core-y) \ $(kernel-y) \ - $(libs-y))) + $(libs-y)) \ + $(xentium-y)) # leanos-core := $(patsubst %/, %/built-in.o, $(core-y)) leanos-kernel := $(patsubst %/, %/built-in.o, $(kernel-y)) diff --git a/dsp/Kbuild b/dsp/Kbuild new file mode 100644 index 0000000000000000000000000000000000000000..17577dca6794bd748735190445e1af8b52c74aee --- /dev/null +++ b/dsp/Kbuild @@ -0,0 +1 @@ +obj-y += xentium/ diff --git a/dsp/xentium/Makefile b/dsp/xentium/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d0d66f8195a1b25f05042c480d9a8b4a76b2f600 --- /dev/null +++ b/dsp/xentium/Makefile @@ -0,0 +1,50 @@ +# we just hijack the host build system because it's the easiest way... +# +# Xentium kernels are built as executables, with library functions +# explicitly listed as object dependencies. The executables are later collected +# in scripts/link-leanos.sh and added to the embedded AR image. +# +# The address of the .text section for the first xentium kernel is determined +# by the confiuration in dsp/xentium/sysroot/lib/default.ld, all subsequent +# programs will start after the _end symbol of the previous +# +# To achieve this, list dsp kernel targets in hostprogs-y and configure targets +# so that the next target depends on the finalised previous target and take +# the value of the _end symbol as the new .text start +# +# This isn't a pretty solution, but that's what you get for not supporting +# relocations. It works for now and it is at least slightly more comfortable +# than configuring all text base addresses by hand +# + + +obj- := dummy.o + + +HOSTCC := xentium-clang +HOSTLD := xentium-ld + +HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -Idsp/xentium + +HOSTLDFLAGS += -Tdsp/xentium/sysroot/lib/default.ld +HOSTLDFLAGS += --sysroot=dsp/xentium/sysroot + + +hostprogs-y := testkernel.xen +hostprogs-y += otherkernel.xen + + + +testkernelkernel.xen : +HOSTLOADLIBES_testkernel.xen := +testkernel.xen-objs := testkernel.o xen_printf.o + + +otherkernel.xen : testkernel.xen +HOSTLOADLIBES_otherkernel.xen := -Ttext $$(readelf -s dsp/xentium/testkernel.xen|grep -w _end |awk '{print $$2}') +otherkernel.xen-objs := testkernel.o xen_printf.o + + + + +always := $(hostprogs-y) diff --git a/dsp/xentium/README b/dsp/xentium/README new file mode 100644 index 0000000000000000000000000000000000000000..bd108042b6453018a1f374b983b88c0ab79d1627 --- /dev/null +++ b/dsp/xentium/README @@ -0,0 +1,4 @@ + +WARNING + +the LD script is likely fucking us with the set up of the stack pointer, need to address this... diff --git a/dsp/xentium/sysroot/lib/crt0.o b/dsp/xentium/sysroot/lib/crt0.o new file mode 100755 index 0000000000000000000000000000000000000000..ae40b61eda71a5b802dc71cbd418a3cfde22ba17 Binary files /dev/null and b/dsp/xentium/sysroot/lib/crt0.o differ diff --git a/dsp/xentium/sysroot/lib/default.ld b/dsp/xentium/sysroot/lib/default.ld new file mode 100755 index 0000000000000000000000000000000000000000..eff9376464fba92f18bfdc967876c1db126287b6 --- /dev/null +++ b/dsp/xentium/sysroot/lib/default.ld @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011, Recore Systems B.V., The Netherlands, + * web: www.recoresystems.com, email: info@recoresystems.com + * + * Any reproduction in whole or in parts is prohibited + * without the written consent of the copyright owner. + * + * All Rights Reserved. + */ + +STARTUP(crt0.o) +INPUT(-lc -lcompiler_rt) + +OUTPUT_FORMAT("elf32-xentium") +OUTPUT_ARCH(xentium) +ENTRY(_start) + +_MINIMUM_STACK_SIZE = 1K; + +MEMORY +{ + dbank0 : ORIGIN = 0x00000000, LENGTH = 8K + dbank1 : ORIGIN = 0x00002000, LENGTH = 8K + dbank2 : ORIGIN = 0x00004000, LENGTH = 8K + dbank3 : ORIGIN = 0x00006000, LENGTH = 8K + ram : ORIGIN = 0x50000000, LENGTH = 256M +} + +PHDRS +{ + code PT_LOAD; + data PT_LOAD; + tcm PT_LOAD; +} + +SECTIONS +{ + /* RAM code and data */ + .text : { + *(.text) + . = ALIGN(16*4) ; /* Align to the next cache line boundary */ + } > ram : code + .rodata ALIGN(0x40) : { + *(.rodata .rodata.*) + . = ALIGN(4) ; + } > ram : data + .data ALIGN(0x40) : { + *(.data) + . = ALIGN(4) ; + } > ram : data + .bss ALIGN(0x40) : { + __bss_start = .; + *(.bss) + . = ALIGN(4) ; + } > ram : data + _end = __bss_start + SIZEOF(.bss); + + /* TCM */ + .dbank0 ORIGIN(dbank0) : { *(.dbank0) } > dbank0 : tcm + .dbank0_noinit ALIGN(0x4) (NOLOAD) : { *(.dbank0_noinit) } > dbank0 : tcm + .dbank1 ORIGIN(dbank1) : { *(.dbank1) } > dbank1 : tcm + .dbank1_noinit ALIGN(0x4) (NOLOAD) : { *(.dbank1_noinit) } > dbank1 : tcm + .dbank2 ORIGIN(dbank2) : { *(.dbank2) } > dbank2 : tcm + .dbank2_noinit ALIGN(0x4) (NOLOAD) : { *(.dbank2_noinit) } > dbank2 : tcm + .dbank3 ORIGIN(dbank3) : { *(.dbank3) } > dbank3 : tcm + .dbank3_noinit ALIGN(0x4) (NOLOAD) : { *(.dbank3_noinit) } > dbank3 : tcm + + /* + * Set the stack pointer to top of data bank 3 or top of the RAM depending on + * the available space in data bank 3. + */ + _remaining_db3 = (LENGTH(dbank3) - SIZEOF(.dbank3) - SIZEOF(.dbank3_noinit)); + _top_db3 = ORIGIN(dbank3)+LENGTH(dbank3); + _top_ram = ORIGIN(ram)+LENGTH(ram); + _stack = (_remaining_db3 > _MINIMUM_STACK_SIZE) ? _top_db3 : _top_ram; + + /* Check that there is enough space in the RAM for the stack */ + _remaining_ram = (LENGTH(ram) - (_end - _start)); + ASSERT(_remaining_ram > 0, "The stack does not fit in ram") +} diff --git a/dsp/xentium/sysroot/lib/libc.a b/dsp/xentium/sysroot/lib/libc.a new file mode 100755 index 0000000000000000000000000000000000000000..febfa931cba74a4777b9dd441881099201fccd51 Binary files /dev/null and b/dsp/xentium/sysroot/lib/libc.a differ diff --git a/dsp/xentium/sysroot/src/crt0.s b/dsp/xentium/sysroot/src/crt0.s new file mode 100755 index 0000000000000000000000000000000000000000..e722bc29a46891b34fc05f481b1c008de3e24029 --- /dev/null +++ b/dsp/xentium/sysroot/src/crt0.s @@ -0,0 +1,118 @@ +%define SYS_argvlen 12 +%define SYS_argv 13 + + .file "crt0.s" + .text + .globl _start + .align 4 + .type _start,@function +_start: + ; Start by setting up a stack. + A0 OR 0, hi16(_stack) ; The linker script specifies the address + ; where the stack should start with the + ; _stack symbol. Get the high part of it + ; on A0X... + + A0 OR A0X, lo16(_stack) ; or in the low part... + + RA14 = A0X ; and assign it to the stack pointer register + ; (RA14). + + ; Now that we have a stack we can start using function calls if needed. + + A0 ADD RA14, -4 ; Decrement stack pointer. + C0 LINK ; Get return address. + + RA14 = A0X + E0 STW A0X[0], C0X ; Store return address in the stack. + + ; Zero the memory in the .bss section. + A0 OR 0, hi16(__bss_start) ; The linker script specifies the address + ; where the .bss section should start with + ; the __bss_start symbol. Get the high part + ; of it on A0X. + S0 OR 0, hi16(_end) ; The linker script specifies the address + ; where the .bss section should end with + ; the _end symbol. Get the high part + ; of it on S0X. + + A0 OR A0X, lo16(__bss_start) ; Or the low part of the address of the + ; __bss_start symbol into the high part + ; already on A0X. + S0 OR S0X, lo16(_end) ; Or the low part of the address of the + ; _end symbol into the high part already on + ; S0X. + +; This commented out section of code uses the memset function to do the actual +; zeroing of the .bss section. If we have an optimized implementation of the +; memset function we might want to use this instead of the code below. +; Currently however it just makes the executable bigger. +; +; RA6 = A0X ; The first parameter of the memset function +; ; is the pointer to the block of memory to +; ; fill. Set it to the address the .bss +; ; section (__bss_start). +; A0 SUB S0X, A0X ; Calculate the size of the .bss section +; ; (_end - __bss_start) +; +; RB6 = 0 ; The second parameter of the memset function +; ; is the value the block of memory should be +; ; set to. Set it to 0. +; RC6 = A0X ; The third parameter of the memset function +; ; is the number of bytes to set. Set it to +; ; the size of the .bss section we just +; ; calculated. +; +; C0 BR memset ; Call the memset function to do the actual +; ; zeroing. +; +; NOP 2 +; + + P0 CMPLTU A0X, S0X ; Check if current address in .bss, + ; __bss_start, (A0X) is less than _end (S0X). + + C0 BRZ P0X, .L2 ; If it is not, the size of .bss is 0, so no + ; need to initialize .bss. Jump over the + ; .bss initialization loop. + + NOP 2 + + ; Begin .bss initialization loop +.L1: + E0 STB A0X[0], 0 ; Write 0 to current address in .bss. + A0 ADD A0X, 1 ; Increment current address in .bss + + P0 CMPLTU A0X, S0X ; Check if new current address in .bss is + ; still less than _end. + + C0 BRNZ P0X, .L1 ; If it is jump back to the beginning of the + ; .bss initialization loop. + + NOP 2 + + ; End .bss initialization loop/ + + ; Initialisation for calls to main with arguments + ; from the command line +.L2: + C0 TRAP SYS_argvlen + + C0 TRAP SYS_argv + +.L3: + C0 BR main ; Call the main function. + + NOP 2 + + E0 LDW RA14[0] + A0 ADD RA14, +4 + + RA14 = A0X + + C0 BRA E0X ; Jump back to the MPPB Xentium bootloader. + + NOP 2 + +.Ltmp0: + .size _start, .Ltmp0-_start diff --git a/include/kernel/ar.h b/include/kernel/ar.h index 44fe2bcf376ece7a7d8eb54d0c5c47f29889832d..cb37e4bd107f1db02e532745aa05e428f3f41f11 100644 --- a/include/kernel/ar.h +++ b/include/kernel/ar.h @@ -44,8 +44,11 @@ struct archive { }; -void ar_list_files(struct archive *a); -void ar_list_symbols(struct archive *a); +void ar_print_files(struct archive *a); +void ar_print_symbols(struct archive *a); + +char *ar_get_file_list(struct archive *a); + void *ar_find_file(struct archive *a, const char *name); void *ar_find_symbol(struct archive *a, const char *name); void ar_free(struct archive *a); diff --git a/include/kernel/string.h b/include/kernel/string.h index c006b7815c56af586d206b8664da10cff88b5661..26825fae3082717b1b1876ce62a8564ecaa43e2c 100644 --- a/include/kernel/string.h +++ b/include/kernel/string.h @@ -12,7 +12,11 @@ int sprintf(char *str, const char *format, ...); int strcmp(const char *s1, const char *s2); char *strpbrk(const char *s, const char *accept); char *strsep(char **stringp, const char *delim); +char *strdup(const char *s); + +char *strstr(const char *haystack, const char *needle); size_t strlen(const char *s); +int memcmp(const void *s1, const void *s2, size_t n); void *memcpy(void *dest, const void *src, size_t n); char *strcpy(char *dest, const char *src); diff --git a/init/main.c b/init/main.c index 5a31e988cc44901605a037d4f74e098469838620..6819227e57f7dfcfd95ed1168e51410029caafb2 100644 --- a/init/main.c +++ b/init/main.c @@ -16,7 +16,6 @@ #include <kernel/sbrk.h> #include <kernel/sysctl.h> -#include <kernel/xentium.h> #define MSG "MAIN: " @@ -24,6 +23,7 @@ void module_image_load_embedded(void); void *module_lookup_embedded(char *mod_name); void *module_lookup_symbol_embedded(char *sym_name); void *module_read_embedded(char *mod_name); +void module_load_xen_kernels(void); static void kernel_init(void) { @@ -40,7 +40,6 @@ int main(void) { void *addr; struct elf_module m; - struct xen_kernel x; kernel_init(); @@ -65,14 +64,8 @@ int main(void) /* addr = module_lookup_symbol_embedded("somefunction"); */ /* XXX the image is not necessary aligned properly, so we can't access * it directly, until we have a MNA trap */ -#if 1 - addr = module_read_embedded("testkernel.ko"); - printk(MSG "testkernel module address is %p\n", addr); - if (addr) - xentium_kernel_load(&x, addr); -#endif #if 0 addr = module_read_embedded("noc_dma.ko"); @@ -86,6 +79,10 @@ int main(void) #if 0 modules_list_loaded(); #endif + + /* load all available Xentium kernels from the embedded modules image */ + module_load_xen_kernels(); + return 0; } diff --git a/init/modules-image.c b/init/modules-image.c index e00937b47968bdcdcb459ebaf1ad739f38fcfee6..5633f429898d920c608be3c912c415dc352b2fb1 100644 --- a/init/modules-image.c +++ b/init/modules-image.c @@ -5,6 +5,11 @@ #include <kernel/printk.h> #include <kernel/ar.h> #include <kernel/kmem.h> +#include <kernel/string.h> +#include <kernel/xentium.h> + +#define MSG "MODIMG: " + extern unsigned char _binary_modules_image_start __attribute__((weak)); extern unsigned char _binary_modules_image_end __attribute__((weak)); @@ -19,8 +24,8 @@ void module_image_load_embedded(void) (unsigned int)&_binary_modules_image_size, &mod_ar); #if 0 - ar_list_files(&mod_ar); - ar_list_symbols(&mod_ar); + ar_print_files(&mod_ar); + ar_print_symbols(&mod_ar); #endif } @@ -54,3 +59,49 @@ void *module_read_embedded(char *mod_name) return ptr; } + + +/** + * @brief try to load all xentium kernels found in the embedded image + * + * @note assumes all files with suffix ".xen" are a kernel + */ + +void module_load_xen_kernels(void) +{ + char *list; + char *fname; + void *file; + + struct xen_kernel x; + + + list = ar_get_file_list(&mod_ar); + + if (!list) + return; + + + while (1) { + fname = strsep(&list, " "); + if (!fname) + break; + + if (!strstr(fname, ".xen")) + continue; + + pr_info(MSG "Loading Xentium kernel %s\n", fname); + + file = module_read_embedded(fname); + if (!file) + pr_err(MSG "Failed to read file %s\n", fname); + + if (!xentium_kernel_load(&x, file)) + pr_err(MSG "Error loading Xentium kernel %s\n", fname); + + kfree(file); + + } + + kfree(list); +} diff --git a/kernel/xentium.c b/kernel/xentium.c index e1b09bacdf73918c5aafa0bb39e6e8f2f902520a..5ed29cd231fa9afefaa99a9386d4d604237abdb8 100644 --- a/kernel/xentium.c +++ b/kernel/xentium.c @@ -16,6 +16,50 @@ +#define BANK_SIZE ( 8*1024 ) +#define TCM_SIZE ( 32*1024 ) +#define XEN_MAILBOX_OFFSET ( 512*1024 ) + +//============================================================= +// XENTIUM structure +//============================================================= +typedef struct { + // TCM + unsigned int tcm[TCM_SIZE/4]; + unsigned int dummy[(XEN_MAILBOX_OFFSET-TCM_SIZE)/4]; + // Status bits + control registers + unsigned int mlbx[4]; //0x00080000 .. 0x0008000C + unsigned int signal[8]; //0x00080010 .. 0x0008002C + unsigned int dma; //0x00080030 .. 0x00080030 + unsigned int dummy1; //0x00080034 .. 0x00080034 + unsigned int timer[2]; //0x00080038 .. 0x0008003C + unsigned int irq; //0x00080040 .. 0x00080040 + unsigned int dummy2; //0x00080044 .. 0x00080044 + unsigned int status; //0x00080048 .. 0x00080048 + unsigned int pc; //0x0008004C .. 0x0008004C + unsigned int fsm_state; //0x00080050 .. 0x00080050 +} volatile S_xen; + +typedef struct S_xdev{ + /* Status bits + control registers */ + volatile unsigned int mlbx[4]; //0x00080000 .. 0x0008000C + volatile unsigned int signal[8]; //0x00080010 .. 0x0008002C + volatile unsigned int dma; //0x00080030 .. 0x00080030 + volatile unsigned int dummy1; //0x00080034 .. 0x00080034 + volatile unsigned int timer[2]; //0x00080038 .. 0x0008003C + volatile unsigned int irq; //0x00080040 .. 0x00080040 + volatile unsigned int dummy2; //0x00080044 .. 0x00080044 + volatile unsigned int status; //0x00080048 .. 0x00080048 + volatile unsigned int pc; //0x0008004C .. 0x0008004C + volatile unsigned int fsm_state; //0x00080050 .. 0x00080050 +} S_xdev; + +typedef volatile unsigned int S_tcm; +S_xen* p_xen0 = (S_xen*) (0x20000000); +S_xen* p_xen1 = (S_xen*) (0x20100000); + + + @@ -278,6 +322,8 @@ int xentium_kernel_load(struct xen_kernel *x, void *p) if (xentium_load_kernel(x)) goto cleanup; + p_xen0->mlbx[0] = 0x30000000; +// p_xen1->mlbx[0] = 0x30000000; if (_xen.cnt == _xen.sz) { diff --git a/lib/ar.c b/lib/ar.c index af50ca1ec7b17040cd3abdb90c863f10589bc178..ec81d89525fc349840e612ef91ef2aec095b02c4 100644 --- a/lib/ar.c +++ b/lib/ar.c @@ -382,15 +382,12 @@ static unsigned int ar_get_filecount(char *p, struct archive *a) /** - * @brief print symbols in the archive + * @brief print list of symbols in the archive * * @param a a struct archive - * @param name the file name to search for - * - * @return a pointer or NULL if not found */ -void ar_list_symbols(struct archive *a) +void ar_print_symbols(struct archive *a) { unsigned long i; @@ -421,15 +418,12 @@ void ar_list_symbols(struct archive *a) /** - * @brief print files in the archive + * @brief print list of files in the archive * * @param a a struct archive - * @param name the file name to search for - * - * @return a pointer or NULL if not found */ -void ar_list_files(struct archive *a) +void ar_print_files(struct archive *a) { unsigned long i; @@ -459,6 +453,57 @@ void ar_list_files(struct archive *a) } +/** + * @brief get a space-separated list of file names in the archive + * + * @param a a struct archive + * + * @return a pointer or NULL if not found + */ + +char *ar_get_file_list(struct archive *a) +{ + unsigned long i; + + size_t sz = 0; + + char *files = NULL; + + + if (!a) + goto exit; + + if (!a->fname) + goto exit; + + if (!a->fnamesz) + goto exit; + + for (i = 0; i < a->n_file; i++) + sz += a->fnamesz[i] + 1; + + if (!sz) + goto exit; + + files = (char *) kzalloc(sz); + + if (!files) + goto exit; + + sz = 0; + for (i = 0; i < a->n_file; i++) { + memcpy(&files[sz], a->fname[i], a->fnamesz[i]); + sz += a->fnamesz[i]; + files[sz++] = ' '; + } + + /* terminate end of string */ + files[sz - 1] = '\0'; + +exit: + return files; +} + /** * @brief return a pointer to an archive file diff --git a/lib/string.c b/lib/string.c index 3f08b9d7fe0987c9d08cff4d608a55c485521ff5..905e3b4df1d55deb5c538e537c4dd68c55fcb359 100644 --- a/lib/string.c +++ b/lib/string.c @@ -7,8 +7,10 @@ */ +#include <kernel/kmem.h> #include <kernel/export.h> #include <kernel/types.h> +#include <kernel/string.h> /** @@ -90,8 +92,8 @@ char *strsep(char **stringp, const char *delim) end = strpbrk(start, delim); if (end) { - (*end)++; (*end) = '\0'; + end++; } *stringp = end; @@ -101,6 +103,34 @@ char *strsep(char **stringp, const char *delim) EXPORT_SYMBOL(strsep); +/** + * @brief return a pointer to a new string which is a duplicate of string s + * + * @parm s the string to duplicate + * + * @note the pointer is allocated using kmalloc() and may be freed with kfree() + */ + +char *strdup(const char *s) +{ + size_t len; + + char *dup; + + if (!s) + return NULL; + + len = strlen(s) + 1; + dup = kzalloc(len); + + if (dup) + memcpy(dup, s, len); + + return dup; +} +EXPORT_SYMBOL(strdup); + + /** * @brief calculate the length of a string * @@ -121,6 +151,82 @@ size_t strlen(const char *s) EXPORT_SYMBOL(strlen); +/** + * @brief finds the first occurrence of the substring needle in the string + * haystack + * + * @param haystack the string to be searched + * @param needle the string to search for + * + * @returns a pointer to the beginning of a substring or NULL if not found + */ + +char *strstr(const char *haystack, const char *needle) +{ + size_t len_h; + size_t len_n; + + + len_n = strlen(needle); + + if (!len_n) + return (char *) haystack; + + len_h = strlen(haystack); + + for ( ; len_h >= len_n; len_h--) { + + if (!memcmp(haystack, needle, len_n)) + return (char *) haystack; + + haystack++; + } + + return NULL; +} +EXPORT_SYMBOL(strstr); + +/** + * @brief compares the first n bytes of the memory areas s1 and s2 + * + * @param s1 the first string + * @param s2 the second string + * @param n the number of bytes to compare + * + * @returns <0, 0 or > 0 if s1 is the first n bytes are found of s1 are found to + * be less than, to match or be greater than s2 + * + * @note s1 and s2 are interpreted as unsigned char + */ + +int memcmp(const void *s1, const void *s2, size_t n) +{ + const unsigned char *su1, *su2; + + int res = 0; + + su1 = (const unsigned char *) s1; + su2 = (const unsigned char *) s2; + + while (n) { + + if ((*su1) != (*su2)) { + if ((*su1) < (*su2)) + return -1; + else + return 1; + } + + su1++; + su2++; + n--; + } + + return 0; +} +EXPORT_SYMBOL(memcmp); + + /** * @brief copy a memory area * @@ -168,12 +274,12 @@ EXPORT_SYMBOL(memcpy); char *strcpy(char *dest, const char *src) { char *tmp; - - + + tmp = dest; while ((*dest++ = *src++) != '\0'); - + return tmp; } EXPORT_SYMBOL(strcpy); @@ -251,13 +357,13 @@ int isspace(int c) { if (c == ' ') return 1; - + if (c == '\t') return 1; if (c == '\n') return 1; - + if (c == '\v') return 1; @@ -301,7 +407,7 @@ int atoi(const char *nptr) d = (*nptr) - '0'; if (d > 9) - break; + break; res = res * 10 + (int) d; nptr++; diff --git a/scripts/link-leanos.sh b/scripts/link-leanos.sh index 242da1062cf120bcde4c100781a5db2b8bd24cbc..807131caf9a612432ab07ab25b6dbf86259637a1 100755 --- a/scripts/link-leanos.sh +++ b/scripts/link-leanos.sh @@ -294,18 +294,21 @@ fi # this is a 3rd pass option, we need modules.order beforehand if [ "$1" = "embed" ]; then - if [ ! -s ${srctree}/modules.order ]; then - echo >&2 - echo >&2 modules.order empty or nonexistant, cannot embed image. - echo >&2 Maybe you have no loadable modules configured? - echo >&2 Kernel image unchanged. - echo >&2 - exit - fi +# if [ ! -s ${srctree}/modules.order ]; then +# echo >&2 +# echo >&2 modules.order empty or nonexistant, cannot embed image. +# echo >&2 Maybe you have no loadable modules configured? +# echo >&2 Kernel image unchanged. +# echo >&2 +# exit +# fi embedflags="-Wl,--format=binary -Wl,modules.image -Wl,--format=default" rm -f modules.image - ${AR} rcs ${srctree}/modules.image $(tr '\n' ' ' < ${srctree}/modules.order) + ${AR} rcs ${srctree}/modules.image \ + $(tr '\n' ' ' < ${srctree}/modules.order) \ + $(find dsp/xentium -name *.xen) + leanos_link "${kallsymso}" leanos "${embedflags}" exit fi