drivers now have kernels symbols resolved via a .ksymtab section of
data in the kernel
 - bss address explicit in boot_info
 - bss and ksym location added to various debug strings
 - dev/lib removed: drivers now use kernel libs
 - phys_to_virt and virt_to_phys: macros -> extern inline
 - moved atol from driver lib to kernel lib
 - kmon updated with "boot" and "ksym" commands
 - report undefined symbols by name
 - support> 1 SHT_NOBITS section - required for ppc
---
 boot/common/elf.c             |  161 ++++++++++++++++++++++++++++++-----------
 boot/common/main.c            |   11 ++--
 boot/include/boot.h           |    5 ++
 boot/include/bootinfo.h       |    3 +
 dev/Makefile                  |    3 +-
 dev/arch/arm/arm/start.S      |   95 ------------------------
 dev/arch/arm/gba/Makefile     |    2 +-
 dev/arch/arm/gba/dev.ld       |    2 +-
 dev/arch/i386/i386/start.S    |   95 ------------------------
 dev/arch/i386/nommu/Makefile  |    2 +-
 dev/arch/i386/nommu/dev.ld    |    2 +-
 dev/arch/i386/pc/Makefile     |    2 +-
 dev/arch/i386/pc/dev.ld       |    2 +-
 dev/include/bootinfo.h        |    3 +
 dev/lib/Makefile              |    4 -
 dev/lib/assert.c              |   46 ------------
 dev/lib/queue.c               |   79 --------------------
 dev/lib/stdlib.c              |   50 -------------
 dev/lib/string.c              |   94 ------------------------
 sys/arch/arm/gba/kernel.ld    |    8 ++
 sys/arch/i386/nommu/kernel.ld |    8 ++
 sys/arch/i386/pc/kernel.ld    |    8 ++
 sys/include/bootinfo.h        |    3 +
 sys/include/debug.h           |    3 +
 sys/include/kernel.h          |   18 +++++
 sys/include/page.h            |   11 +++-
 sys/include/stdlib.h          |   35 +++++++++
 sys/kern/debug.c              |    6 ++
 sys/kern/device.c             |  116 +++++++++++++++---------------
 sys/kern/task.c               |   32 +++++++-
 sys/lib/Makefile              |    2 +-
 sys/lib/stdlib.c              |   50 +++++++++++++
 sys/mem/page.c                |   12 +++
 user/bin/kmon/cmd.c           |   16 ++++
 user/include/prex/prex.h      |    2 +
 35 files changed, 408 insertions(+), 583 deletions(-)
 delete mode 100755 dev/arch/arm/arm/start.S
 delete mode 100755 dev/arch/i386/i386/start.S
 delete mode 100755 dev/lib/Makefile
 delete mode 100755 dev/lib/assert.c
 delete mode 100755 dev/lib/queue.c
 delete mode 100755 dev/lib/stdlib.c
 delete mode 100755 dev/lib/string.c
 create mode 100755 sys/include/stdlib.h
 create mode 100755 sys/lib/stdlib.c

diff --git a/boot/common/elf.c b/boot/common/elf.c
index b9abb71..2c1fbc3 100755
--- a/boot/common/elf.c
+++ b/boot/common/elf.c
@@ -45,13 +45,16 @@ extern int nr_img;          /* Number of images */
 
 #define SHF_VALID      (SHF_ALLOC | SHF_EXECINSTR | SHF_ALLOC | SHF_WRITE)
 
-
 static char *sect_addr[32];    /* Array of section address */
+static struct img_info *kinfo = NULL; /* kernel image info */
+int nr_kinfo = 0;               /* kernel image info */
 
 static int load_executable(char *img, struct img_info *info)
 {
        Elf32_Ehdr *ehdr;
        Elf32_Phdr *phdr;
+       Elf32_Shdr *shdrs, *shdr;
+       char *shstrtab;
        u_int phys_base;
        int i;
 
@@ -62,6 +65,20 @@ static int load_executable(char *img, struct img_info *info)
        phys_base = load_base;
        elf_dbg("phys addr=%x\n", phys_base);
 
+       /* find ksyms */
+       shdrs = (Elf32_Shdr *)((u_long)ehdr + ehdr->e_shoff);
+       shstrtab = img + shdrs[ehdr->e_shstrndx].sh_offset;
+       for (i = 0, shdr = shdrs; i < ehdr->e_shnum; i++, shdr++) {
+               if (shdr->sh_type == SHT_PROGBITS
+                   && (shdr->sh_flags & SHF_VALID) == SHF_ALLOC
+                   && strncmp(shstrtab + shdr->sh_name, ".ksymtab", 9) == 0)
+               {
+                       info->ksym = shdr->sh_addr;
+                       info->ksym_size = shdr->sh_size;
+                       break;
+               }
+       }
+
        for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
                if (phdr->p_type != PT_LOAD)
                        continue;
@@ -83,6 +100,7 @@ static int load_executable(char *img, struct img_info *info)
                        info->data = phdr->p_vaddr;
                        info->data_size = phdr->p_filesz;
                        info->bss_size = phdr->p_memsz - phdr->p_filesz;
+                       info->bss = info->data + info->data_size;
                        load_base = phys_base + (info->data - info->text);
                }
                if (phdr->p_filesz > 0) {
@@ -107,55 +125,96 @@ static int load_executable(char *img, struct img_info 
*info)
        return 0;
 }
 
+static int resolve_symbol(const char *name)
+{
+       struct kernel_symbol *ksym;
+       struct img_info *info;
+       int i;
+
+       for (i = nr_kinfo, info = kinfo; i > 0; i--, info++) {
+               int nr_ksym = info->ksym_size / sizeof(struct kernel_symbol);
+               ksym = (struct kernel_symbol *)info->ksym;
+               for (; nr_ksym > 0; nr_ksym--, ksym++) {
+                        if (strncmp(name, ksym->name, 20) == 0)
+                                return ksym->value;
+                }
+        }
+        return 0;
+}
+
 static int relocate_section_rela(Elf32_Sym *sym_table, Elf32_Rela *rela,
-                       char *target_sect, int nr_reloc)
+                                char *target_sect,  const char *strtab,
+                                int nr_reloc)
 {
        Elf32_Sym *sym;
        Elf32_Addr sym_val;
        int i;
 
-       for (i = 0; i < nr_reloc; i++) {
+       for (i = 0; i < nr_reloc; i++, rela++) {
                sym = &sym_table[ELF32_R_SYM(rela->r_info)];
+
                if (sym->st_shndx != STN_UNDEF) {
                        sym_val = (Elf32_Addr)sect_addr[sym->st_shndx]
                                + sym->st_value;
-                       if (relocate_rela(rela, sym_val, target_sect) != 0)
-                               return -1;
-               } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
-                       printk("Undefined symbol for rela[%x]\n", i);
+               } else {
+                       sym_val = resolve_symbol(strtab + sym->st_name);
+
+                       if (sym_val)
+                               elf_dbg("Resolved symbol \"%s\": %x\n",
+                                      strtab + sym->st_name, sym_val);
+                       else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
+                               printk("Undefined symbol \"%s\"\n",
+                                      strtab + sym->st_name);
+                               return -1; /* fatal */
+                       } else {
+                               elf_dbg("Undefined weak symbol \"%s\"\n",
+                                       strtab + sym->st_name);
+                               continue; /* don't relocate */
+                       }
+               }
+               if (relocate_rela(rela, sym_val, target_sect) != 0)
                        return -1;
-               } else
-                       elf_dbg("Undefined weak symbol for rela[%x]\n", i);
-               rela++;
        }
        return 0;
 }
 
 static int relocate_section_rel(Elf32_Sym *sym_table, Elf32_Rel *rel,
-                       char *target_sect, int nr_reloc)
+                               char *target_sect,  const char *strtab,
+                               int nr_reloc)
 {
        Elf32_Sym *sym;
        Elf32_Addr sym_val;
        int i;
 
-       for (i = 0; i < nr_reloc; i++) {
+       for (i = 0; i < nr_reloc; i++, rel++) {
                sym = &sym_table[ELF32_R_SYM(rel->r_info)];
+
                if (sym->st_shndx != STN_UNDEF) {
                        sym_val = (Elf32_Addr)sect_addr[sym->st_shndx]
                                + sym->st_value;
-                       if (relocate_rel(rel, sym_val, target_sect) != 0)
-                               return -1;
-               } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
-                       printk("Undefined symbol for rel[%x] sym=%x\n", i, sym);
+               } else {
+                       sym_val = resolve_symbol(strtab + sym->st_name);
+
+                       if (sym_val)
+                               elf_dbg("Resolved symbol \"%s\": %x\n",
+                                      strtab + sym->st_name, sym_val);
+                       else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
+                               printk("Undefined symbol \"%s\"\n",
+                                      strtab + sym->st_name);
+                               return -1; /* fatal */
+                       } else {
+                               elf_dbg("Undefined weak symbol \"%s\"\n",
+                                       strtab + sym->st_name);
+                               continue; /* don't relocate */
+                       }
+               }
+               if (relocate_rel(rel, sym_val, target_sect) != 0)
                        return -1;
-               } else
-                       elf_dbg("Undefined weak symbol for rel[%x]\n", i);
-               rel++;
        }
        return 0;
 }
 
-static int relocate_section(char *img, Elf32_Shdr *shdr)
+static int relocate_section(char *img, Elf32_Shdr *shdr, const char *strtab)
 {
        Elf32_Sym *sym_table;
        char *target_sect;
@@ -173,15 +232,17 @@ static int relocate_section(char *img, Elf32_Shdr *shdr)
        nr_reloc = shdr->sh_size / shdr->sh_entsize;
        switch (shdr->sh_type) {
        case SHT_REL:
-               return relocate_section_rel(sym_table,
-                                   (Elf32_Rel *)(img + shdr->sh_offset),
-                                   target_sect, nr_reloc);
+               return relocate_section_rel(
+                       sym_table,
+                       (Elf32_Rel *)(img + shdr->sh_offset),
+                       target_sect, strtab, nr_reloc);
                break;
 
        case SHT_RELA:
-               return relocate_section_rela(sym_table,
-                                    (Elf32_Rela *)(img + shdr->sh_offset),
-                                    target_sect, nr_reloc);
+               return relocate_section_rela(
+                       sym_table,
+                       (Elf32_Rela *)(img + shdr->sh_offset),
+                       target_sect, strtab, nr_reloc);
                break;
 
        default:
@@ -193,19 +254,24 @@ static int relocate_section(char *img, Elf32_Shdr *shdr)
 static int load_relocatable(char *img, struct img_info *info)
 {
        Elf32_Ehdr *ehdr;
-       Elf32_Shdr *shdr;
-       u_long sect_base, bss_base;
+       Elf32_Shdr *shdr, *shdrs;
+       u_long sect_base;
+       char *strtab = NULL, *shstrtab;
        int i;
 
        ehdr = (Elf32_Ehdr *)img;
-       shdr = (Elf32_Shdr *)((u_long)ehdr + ehdr->e_shoff);
-       bss_base = 0;
+       shdrs = (Elf32_Shdr *)((u_long)ehdr + ehdr->e_shoff);
        info->phys = load_base;
        elf_dbg("phys addr=%x\n", load_base);
 
+       shstrtab = img + shdrs[ehdr->e_shstrndx].sh_offset;
+
        /* Copy sections */
-       for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+       for (i = 0, shdr = shdrs; i < ehdr->e_shnum; i++, shdr++) {
                sect_addr[i] = 0;
+               if (shdr->sh_size == 0)
+                       continue;
+
                if (shdr->sh_type == SHT_PROGBITS) {
 
                        elf_dbg("sh_addr=%x\n", shdr->sh_addr);
@@ -225,8 +291,15 @@ static int load_relocatable(char *img, struct img_info 
*info)
                                                (u_long)phys_to_virt(load_base 
+ shdr->sh_addr);
                                break;
                        case SHF_ALLOC:
-                               /* rodata */
+                               /* rodata & kstrtab */
                                /* Note: rodata is treated as text. */
+                               if (strncmp(shstrtab + shdr->sh_name,
+                                           ".ksymtab", 9) == 0)
+                               {
+                                       info->ksym =
+                                               (u_long)phys_to_virt(load_base 
+ shdr->sh_addr);
+                                       info->ksym_size = shdr->sh_size;
+                               }
                                break;
                        default:
                                continue;
@@ -239,24 +312,28 @@ static int load_relocatable(char *img, struct img_info 
*info)
 
                        sect_addr[i] = (char *)sect_base;
                } else if (shdr->sh_type == SHT_NOBITS) {
-                       /* BSS */
-                       info->bss_size = shdr->sh_size;
+                       /* BSS, SBSS, etc. */
                        sect_base = load_base + shdr->sh_addr;
-                       bss_base = sect_base;
+                       if (info->bss == 0) {
+                               info->bss = sect_base;
+                               info->bss_size = shdr->sh_size;
+                       } else
+                               info->bss_size += shdr->sh_size;
 
-                       /* Zero fill BSS */
+                       /* Zero fill uninitialised sections */
                        memset((char *)sect_base, 0, shdr->sh_size);
 
                        sect_addr[i] = (char *)sect_base;
                } else if (shdr->sh_type == SHT_SYMTAB) {
                        /* Symbol table */
                        sect_addr[i] = img + shdr->sh_offset;
+                       strtab = img + shdrs[shdr->sh_link].sh_offset;
                }
        }
        info->text_size = info->data - info->text;
-       info->data_size = bss_base - info->data;
+       info->data_size = info->bss - info->data;
 
-       load_base = bss_base + info->bss_size;
+       load_base = info->bss + info->bss_size;
        load_base = PAGE_ALIGN(load_base);
 
        elf_dbg("info load_base=%x info->text=%x\n",
@@ -266,10 +343,9 @@ static int load_relocatable(char *img, struct img_info 
*info)
        elf_dbg("info size=%x entry=%x\n", info->size, info->entry);
 
        /* Process relocation */
-       shdr = (Elf32_Shdr *)((u_long)ehdr + ehdr->e_shoff);
-       for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+       for (i = 0, shdr = shdrs; i < ehdr->e_shnum; i++, shdr++) {
                if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
-                       if (relocate_section(img, shdr) != 0)
+                       if (relocate_section(img, shdr, strtab) != 0)
                                return -1;
                }
        }
@@ -305,6 +381,7 @@ int elf_load(char *img, struct img_info *info)
                        return -1;
                elf_dbg("kernel base=%x\n", load_base);
                load_start = load_base;
+               kinfo = info;   /* REVISIT: bit of a hack */
        }
        else if (nr_img == 1) {
                /*  Second image => Driver */
@@ -329,5 +406,7 @@ int elf_load(char *img, struct img_info *info)
                return -1;
        }
        nr_img++;
+       if (info->ksym != 0)
+               nr_kinfo = nr_img;
        return 0;
 }
diff --git a/boot/common/main.c b/boot/common/main.c
index a9ec299..a898059 100755
--- a/boot/common/main.c
+++ b/boot/common/main.c
@@ -201,11 +201,12 @@ static void setup_image(void)
 #ifdef DEBUG_BOOT
 static void dump_image(struct img_info *img)
 {
-       printk
-           ("%s: entry=%x phys=%x size=%x text=%x data=%x textsz=%x datasz=%x 
bss=%x\n",
-            img->name, (int)img->entry, (int)img->phys, (int)img->size,
-            (int)img->text, (int)img->data, (int)img->text_size,
-            (int)img->data_size, (int)img->bss_size);
+       printk("%s: entry=%x phys=%x size=%x text=%x data=%x bss=%x ksym=%x "
+              "textsz=%x datasz=%x bsssz=%x ksymsz=%x\n",
+              img->name, (int)img->entry, (int)img->phys, (int)img->size,
+              (int)img->text, (int)img->data, (int)img->bss, (int)img->ksym,
+              (int)img->text_size, (int)img->data_size, (int)img->bss_size,
+              (int)img->ksym_size);
 }
 
 static void dump_bootinfo(void)
diff --git a/boot/include/boot.h b/boot/include/boot.h
index dde65c0..f7785e4 100755
--- a/boot/include/boot.h
+++ b/boot/include/boot.h
@@ -80,4 +80,9 @@ extern int elf_load(char *img, struct img_info *info);
 /* main */
 extern void reserve_memory(u_long start, size_t size);
 
+struct kernel_symbol
+{
+       u_long value;
+       const char *name;
+};
 #endif /* !_BOOT_H */
diff --git a/boot/include/bootinfo.h b/boot/include/bootinfo.h
index f65090a..698f711 100755
--- a/boot/include/bootinfo.h
+++ b/boot/include/bootinfo.h
@@ -54,9 +54,12 @@ struct img_info
        u_long  entry;          /* Entry address */
        u_long  text;           /* Text address */
        u_long  data;           /* Data address */
+       u_long  bss;            /* Bss address */
+       u_long  ksym;           /* Ksymtab address */
        size_t  text_size;      /* Text size */
        size_t  data_size;      /* Data size */
        size_t  bss_size;       /* Bss size */
+       size_t  ksym_size;      /* Ksymtab size */
 };
 
 /*
diff --git a/dev/Makefile b/dev/Makefile
index 4fbee57..bc92034 100755
--- a/dev/Makefile
+++ b/dev/Makefile
@@ -1,12 +1,11 @@
 TARGET = dev.ko
 TYPE   = DRIVER
-SUBDIRS = lib arch core gen power
+SUBDIRS = arch core gen power
 OBJS   = \
        ./arch/$(PREX_ARCH)/$(PREX_PLATFORM)/dev.o \
        ./core/core.o \
        ./gen/gen.o \
        ./power/power.o
-LIBS   = ./lib/libdev.a
 #DISASM        = dev.lst
 #MAP   = dev.map
 LD_SCRIPT = ./arch/$(PREX_ARCH)/$(PREX_PLATFORM)/dev.ld
diff --git a/dev/arch/arm/arm/start.S b/dev/arch/arm/arm/start.S
deleted file mode 100755
index 90da043..0000000
--- a/dev/arch/arm/arm/start.S
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2005, Kohsuke Ohtani
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors 
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * start.S - driver start up routine
- */
-#define ENTRY(x) .global x; .align; x##:
-
-.data
-
-drv_serv:      .word   0
-
-
-.text
-
-/*
- * Entry point which called by kernel
- */
-ENTRY(driver_start)
-       ldr     r1, =drv_serv
-       str     r0, [r1]
-       b       driver_main
-
-/*
- * Stub to call kernel device interface
- */
-#define STUB(index, func) .global func;\
-ENTRY(func) \
-       ldr     ip, =drv_serv   ; \
-       ldr     ip, [ip]        ; \
-       ldr     ip, [ip, #(index*4)]    ; \
-       mov     pc, ip
-
-STUB( 0, device_create)
-STUB( 1, device_delete)
-STUB( 2, device_broadcast)
-STUB( 3, umem_copyin)
-STUB( 4, umem_copyout)
-STUB( 5, umem_strnlen)
-STUB( 6, kmem_alloc)
-STUB( 7, kmem_free)
-STUB( 8, kmem_map)
-STUB( 9, page_alloc)
-STUB(10, page_free)
-STUB(11, page_reserve)
-STUB(12, irq_attach)
-STUB(13, irq_detach)
-STUB(14, irq_lock)
-STUB(15, irq_unlock)
-STUB(16, timer_timeout)
-STUB(17, timer_stop)
-STUB(18, timer_delay)
-STUB(19, timer_count)
-STUB(20, timer_hook)
-STUB(21, timer_unhook)
-STUB(22, sched_lock)
-STUB(23, sched_unlock)
-STUB(24, sched_tsleep)
-STUB(25, sched_wakeup)
-STUB(26, sched_dpc)
-STUB(27, printk)
-STUB(28, panic)
-STUB(29, system_reset)
-STUB(30, kernel_dump)
-STUB(31, debug_attach)
-STUB(32, task_capable)
-STUB(33, system_bootinfo)
-STUB(34, phys_to_virt)
-STUB(35, virt_to_phys)
diff --git a/dev/arch/arm/gba/Makefile b/dev/arch/arm/gba/Makefile
index e3822f1..5ce78ac 100755
--- a/dev/arch/arm/gba/Makefile
+++ b/dev/arch/arm/gba/Makefile
@@ -1,4 +1,4 @@
 TARGET = dev.o
 TYPE   = OBJECT
-OBJS   = ../arm/start.o platform.o keypad.o console.o swkbd.o
+OBJS   = platform.o keypad.o console.o swkbd.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/arch/arm/gba/dev.ld b/dev/arch/arm/gba/dev.ld
index 4a7e2bf..6cab458 100755
--- a/dev/arch/arm/gba/dev.ld
+++ b/dev/arch/arm/gba/dev.ld
@@ -1,7 +1,7 @@
 /* Linker script for driver */
 OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
 OUTPUT_ARCH(arm)
-ENTRY(driver_start)
+ENTRY(driver_main)
 PHDRS
 {
        text PT_LOAD FILEHDR PHDRS;
diff --git a/dev/arch/i386/i386/start.S b/dev/arch/i386/i386/start.S
deleted file mode 100755
index a7300f5..0000000
--- a/dev/arch/i386/i386/start.S
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2005, Kohsuke Ohtani
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors 
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * start.S - driver start up routine
- */
-#define ENTRY(x) .global x; .align 4,0x90; x##:
-
-.data
-
-drv_serv:
-.long  0
-
-
-.text
-
-/*
- * Entry point which called by kernel
- */
-ENTRY(driver_start)
-       movl    0x04(%esp), %eax
-       movl    %eax, drv_serv
-       jmp     driver_main
-
-/*
- * Stub to call kernel device interface
- */
-#define STUB(index, func) .global func;\
-ENTRY(func) \
-       movl    drv_serv, %eax; \
-       add     $(index * 4), %eax; \
-       jmp     *(%eax);
-
-STUB( 0, device_create)
-STUB( 1, device_delete)
-STUB( 2, device_broadcast)
-STUB( 3, umem_copyin)
-STUB( 4, umem_copyout)
-STUB( 5, umem_strnlen)
-STUB( 6, kmem_alloc)
-STUB( 7, kmem_free)
-STUB( 8, kmem_map)
-STUB( 9, page_alloc)
-STUB(10, page_free)
-STUB(11, page_reserve)
-STUB(12, irq_attach)
-STUB(13, irq_detach)
-STUB(14, irq_lock)
-STUB(15, irq_unlock)
-STUB(16, timer_timeout)
-STUB(17, timer_stop)
-STUB(18, timer_delay)
-STUB(19, timer_count)
-STUB(20, timer_hook)
-STUB(21, timer_unhook)
-STUB(22, sched_lock)
-STUB(23, sched_unlock)
-STUB(24, sched_tsleep)
-STUB(25, sched_wakeup)
-STUB(26, sched_dpc)
-STUB(27, printk)
-STUB(28, panic)
-STUB(29, system_reset)
-STUB(30, kernel_dump)
-STUB(31, debug_attach)
-STUB(32, task_capable)
-STUB(33, system_bootinfo)
-STUB(34, phys_to_virt)
-STUB(35, virt_to_phys)
diff --git a/dev/arch/i386/nommu/Makefile b/dev/arch/i386/nommu/Makefile
index d58e5bc..59478e0 100755
--- a/dev/arch/i386/nommu/Makefile
+++ b/dev/arch/i386/nommu/Makefile
@@ -1,5 +1,5 @@
 TARGET = dev.o
 TYPE   = OBJECT
-OBJS   = ../i386/start.o ../pc/dma.o ../pc/rtc.o ../pc/kbd.o ../pc/console.o \
+OBJS   = ../pc/dma.o ../pc/rtc.o ../pc/kbd.o ../pc/console.o \
        ../pc/fdd.o ../pc/mouse.o ../i386/cpu.o ../pc/platform.o ../i386/delay.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/arch/i386/nommu/dev.ld b/dev/arch/i386/nommu/dev.ld
index 075197f..f7a286c 100755
--- a/dev/arch/i386/nommu/dev.ld
+++ b/dev/arch/i386/nommu/dev.ld
@@ -1,7 +1,7 @@
 /* Linker script for driver */
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
-ENTRY(driver_start)
+ENTRY(driver_main)
 PHDRS
 {
        text PT_LOAD FILEHDR PHDRS;
diff --git a/dev/arch/i386/pc/Makefile b/dev/arch/i386/pc/Makefile
index 6c63d12..be566f1 100755
--- a/dev/arch/i386/pc/Makefile
+++ b/dev/arch/i386/pc/Makefile
@@ -1,5 +1,5 @@
 TARGET = dev.o
 TYPE   = OBJECT
-OBJS   = ../i386/start.o dma.o rtc.o kbd.o console.o fdd.o mouse.o \
+OBJS   = dma.o rtc.o kbd.o console.o fdd.o mouse.o \
        ../i386/cpu.o platform.o ../i386/delay.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/arch/i386/pc/dev.ld b/dev/arch/i386/pc/dev.ld
index 075197f..f7a286c 100755
--- a/dev/arch/i386/pc/dev.ld
+++ b/dev/arch/i386/pc/dev.ld
@@ -1,7 +1,7 @@
 /* Linker script for driver */
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
-ENTRY(driver_start)
+ENTRY(driver_main)
 PHDRS
 {
        text PT_LOAD FILEHDR PHDRS;
diff --git a/dev/include/bootinfo.h b/dev/include/bootinfo.h
index ebee151..0618254 100755
--- a/dev/include/bootinfo.h
+++ b/dev/include/bootinfo.h
@@ -49,9 +49,12 @@ struct img_info
        u_long  entry;          /* Entry address */
        u_long  text;           /* Text address */
        u_long  data;           /* Data address */
+       u_long  bss;            /* Bss address */
+       u_long  ksym;           /* Ksymtab address */
        size_t  text_size;      /* Text size */
        size_t  data_size;      /* Data size */
        size_t  bss_size;       /* Bss size */
+       size_t  ksym_size;      /* Ksymtab size */
 };
 
 /*
diff --git a/dev/lib/Makefile b/dev/lib/Makefile
deleted file mode 100755
index f703129..0000000
--- a/dev/lib/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-TARGET = libdev.a
-TYPE   = LIBRARY
-OBJS   = stdlib.o string.o queue.o assert.o
-include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/lib/assert.c b/dev/lib/assert.c
deleted file mode 100755
index cc22263..0000000
--- a/dev/lib/assert.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 2005, Kohsuke Ohtani
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors 
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * assert.c - assertion routine
- */
-#include <driver.h>
-
-/*
- * Assertion routine
- *
- * Do not call this routine, but use ASSERT() macro.
- * assert() is called only when the expression is
- * false in ASSERT() macro.
- */
-void assert(const char *file, int line, const char *exp)
-{
-       irq_lock();
-       panic("\nAssertion fail!: %s line:%d '%s'\n", file, line, exp);
-}
diff --git a/dev/lib/queue.c b/dev/lib/queue.c
deleted file mode 100755
index cd4ae98..0000000
--- a/dev/lib/queue.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 2005, Kohsuke Ohtani
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors 
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * queue.c - generic queue management library
- */
-#include <queue.h>
-
-/*
- * Insert element at tail of queue
- */
-void enqueue(queue_t head, queue_t item)
-{
-       item->next = head;
-       item->prev = head->prev;
-       item->prev->next = item;
-       head->prev = item;
-}
-
-/*
- * Remove and return element of head of queue
- */
-queue_t dequeue(queue_t head)
-{
-       queue_t item;
-
-       if (head->next == head)
-               return ((queue_t)0);
-       item = head->next;
-       item->next->prev = head;
-       head->next = item->next;
-       return item;
-}
-
-/*
- * Insert element after specified element
- */
-void queue_insert(queue_t prev, queue_t item)
-{
-       item->prev = prev;
-       item->next = prev->next;
-       prev->next->prev = item;
-       prev->next = item;
-}
-
-/*
- * Remove specified element from queue
- */
-void queue_remove(queue_t item)
-{
-       item->prev->next = item->next;
-       item->next->prev = item->prev;
-}
diff --git a/dev/lib/stdlib.c b/dev/lib/stdlib.c
deleted file mode 100755
index e7f85a5..0000000
--- a/dev/lib/stdlib.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 2005, Kohsuke Ohtani
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors 
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * stdlib.c - minimum standard library
- */
-
-/*
- * Convert string to long interger
- * This version does not support minus value.
- */
-long atol(const char *str)
-{
-       long val = 0;
-
-       while (*str == ' ')
-               str++;
-       while (*str >= '0' && *str <= '9') {
-               val *= 10;
-               val += (*str - '0');
-               str++;
-       }
-       return val;
-}
diff --git a/dev/lib/string.c b/dev/lib/string.c
deleted file mode 100755
index 9acfa58..0000000
--- a/dev/lib/string.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*-
- * Copyright (c) 2005, Kohsuke Ohtani
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the names of any co-contributors 
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * string.c - minimum string library
- */
-
-#include <types.h>
-
-char *strncpy(char *dest, const char *src, size_t count)
-{
-       char *tmp = dest;
-
-       while (count-- && (*dest++ = *src++) != '\0');
-       return tmp;
-}
-
-/* Safer version of strncpy */
-size_t strlcpy(char *dest, const char *src, size_t count)
-{
-       const char *p = src;
-
-       while (count-- && (*dest++ = *src++) != '\0');
-
-       if (count == 0) {
-               *dest = '\0';
-               while (*src++);
-       }
-       return (size_t)(src - p - 1); /* count does not include NULL */
-}
-
-int strncmp(const char *src, const char *tgt, size_t count)
-{
-       signed char res = 0;
-
-       while (count) {
-               if ((res = *src - *tgt++) != 0 || !*src++)
-                       break;
-               count--;
-       }
-       return res;
-}
-
-size_t strnlen(const char *str, size_t count)
-{
-       const char *tmp;
-
-       for (tmp = str; count-- && *tmp != '\0'; ++tmp);
-       return (size_t)(tmp - str);
-}
-
-void *memcpy(void *dest, const void *src, size_t count)
-{
-       char *tmp = (char *)dest, *s = (char *)src;
-
-       while (count--)
-               *tmp++ = *s++;
-       return dest;
-}
-
-void *memset(void *dest, int ch, size_t count)
-{
-       char *p = (char *)dest;
-
-       while (count--)
-               *p++ = (char)ch;
-       return dest;
-}
diff --git a/sys/arch/arm/gba/kernel.ld b/sys/arch/arm/gba/kernel.ld
index 514bfb3..a684582 100755
--- a/sys/arch/arm/gba/kernel.ld
+++ b/sys/arch/arm/gba/kernel.ld
@@ -24,6 +24,14 @@ SECTIONS
                *(.rodata.*)
        } : text
 
+       .kstrtab : {
+               *(.kstrtab)
+       } : text
+
+       .ksymtab ALIGN(4) : {
+               *(.ksymtab)
+       } : text
+
        .data ALIGN(4) : {
                *(.data)
        } : data = 0xff
diff --git a/sys/arch/i386/nommu/kernel.ld b/sys/arch/i386/nommu/kernel.ld
index 6f6d2e6..20385b0 100755
--- a/sys/arch/i386/nommu/kernel.ld
+++ b/sys/arch/i386/nommu/kernel.ld
@@ -25,6 +25,14 @@ SECTIONS
                *(.rodata.*)
        } : text
 
+       .kstrtab : {
+               *(.kstrtab)
+       } : text
+
+       .ksymtab ALIGN(4) : {
+               *(.ksymtab)
+       } : text
+
        . = ALIGN(32);
        .data : {
                *(.data)
diff --git a/sys/arch/i386/pc/kernel.ld b/sys/arch/i386/pc/kernel.ld
index a7120d9..9ef79c6 100755
--- a/sys/arch/i386/pc/kernel.ld
+++ b/sys/arch/i386/pc/kernel.ld
@@ -25,6 +25,14 @@ SECTIONS
                *(.rodata.*)
        } : text
 
+       .kstrtab : {
+               *(.kstrtab)
+       } : text
+
+       .ksymtab ALIGN(4) : {
+               *(.ksymtab)
+       } : text
+
        . = ALIGN(32);
        .data : {
                *(.data)
diff --git a/sys/include/bootinfo.h b/sys/include/bootinfo.h
index ebee151..0618254 100755
--- a/sys/include/bootinfo.h
+++ b/sys/include/bootinfo.h
@@ -49,9 +49,12 @@ struct img_info
        u_long  entry;          /* Entry address */
        u_long  text;           /* Text address */
        u_long  data;           /* Data address */
+       u_long  bss;            /* Bss address */
+       u_long  ksym;           /* Ksymtab address */
        size_t  text_size;      /* Text size */
        size_t  data_size;      /* Data size */
        size_t  bss_size;       /* Bss size */
+       size_t  ksym_size;      /* Ksymtab size */
 };
 
 /*
diff --git a/sys/include/debug.h b/sys/include/debug.h
index 16e28e9..6fad4a4 100755
--- a/sys/include/debug.h
+++ b/sys/include/debug.h
@@ -135,6 +135,8 @@ struct trace_entry {
 #define DUMP_VM                7
 #define DUMP_MSGLOG    8
 #define DUMP_TRACE     9
+#define DUMP_BOOT      10
+#define DUMP_KSYM      11
 
 #ifdef DEBUG
 extern void thread_dump();
@@ -148,6 +150,7 @@ extern void kmem_dump();
 extern void vm_dump();
 
 extern void boot_dump();
+extern void ksym_dump();
 extern void memory_dump(void *phys, size_t size);
 #endif /* !DEBUG */
 
diff --git a/sys/include/kernel.h b/sys/include/kernel.h
index 8762ac4..2ab1246 100755
--- a/sys/include/kernel.h
+++ b/sys/include/kernel.h
@@ -73,4 +73,22 @@ extern void *memset(void *dest, int ch, size_t count);
 
 extern int vsprintf(char *, const char *, va_list);
 
+/* Export symbols for drivers. Place the symbol name in .kstrtab and a
+ * struct kernel_symbol in the .ksymtab. The elf loader will use this
+ * information to resolve these symbols in driver modules */
+struct kernel_symbol
+{
+       u_long value;
+       const char *name;
+};
+
+#define EXPORT_SYMBOL(sym)                                             \
+       static const char __kstrtab_##sym[]                             \
+       __attribute__((section(".kstrtab")))                            \
+               = #sym;                                                 \
+       static const struct kernel_symbol __ksymtab_##sym               \
+       __attribute__((__used__))                                       \
+               __attribute__((section(".ksymtab"), unused))            \
+               = { .value = (u_long)&sym, .name = __kstrtab_##sym }
+
 #endif /* !_KERNEL_H */
diff --git a/sys/include/page.h b/sys/include/page.h
index 4ece749..81b3d9b 100755
--- a/sys/include/page.h
+++ b/sys/include/page.h
@@ -40,8 +40,15 @@
 /*
  * Page mapping
  */
-#define phys_to_virt(p_addr)   (void *)((u_long)(p_addr) + PAGE_OFFSET)
-#define virt_to_phys(v_addr)   (void *)((u_long)(v_addr) - PAGE_OFFSET)
+extern inline void *phys_to_virt(void *p_addr)
+{
+       return p_addr + PAGE_OFFSET;
+}
+
+extern inline void *virt_to_phys(void *v_addr)
+{
+       return v_addr - PAGE_OFFSET;
+}
 
 extern void page_init(void);
 extern void *page_alloc(size_t size);
diff --git a/sys/include/stdlib.h b/sys/include/stdlib.h
new file mode 100755
index 0000000..bff61c3
--- /dev/null
+++ b/sys/include/stdlib.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005, Kohsuke Ohtani
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors 
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+extern long atol(char *nptr);
+
+#endif /* !_STDLIB_H */
diff --git a/sys/kern/debug.c b/sys/kern/debug.c
index 235bf3f..96ed1a6 100755
--- a/sys/kern/debug.c
+++ b/sys/kern/debug.c
@@ -343,6 +343,12 @@ int kernel_dump(int item)
                trace_dump();
 #endif
                break;
+       case DUMP_BOOT:
+               boot_dump();
+               break;
+       case DUMP_KSYM:
+               ksym_dump();
+               break;
 
        default:
                err = 1;
diff --git a/sys/kern/device.c b/sys/kern/device.c
index d376156..6c262ca 100755
--- a/sys/kern/device.c
+++ b/sys/kern/device.c
@@ -52,6 +52,7 @@
 #include <timer.h>
 #include <sched.h>
 #include <vm.h>
+#include <stdlib.h>
 #include <device.h>
 #include <system.h>
 
@@ -60,12 +61,6 @@ static device_t device_create(const devio_t io, const char 
*name);
 static int device_delete(device_t dev);
 static int device_broadcast(int event, int force);
 static void system_bootinfo(struct boot_info **info);
-static void *_phys_to_virt(void *p_addr);
-static void *_virt_to_phys(void *v_addr);
-
-/* Driver-Kernel function */
-typedef void (*dki_func_t)(void);
-#define DKIENT(func)   (dki_func_t)(func)
 
 #ifndef DEBUG
 static void null_func(void);
@@ -74,52 +69,65 @@ static void null_func(void);
 
 #undef panic
 #define panic system_reset
+
+#define assert null_func
 #endif
 
 /* List of device objects */
 static struct list device_list = LIST_INIT(device_list);
 
-/*
- * Driver-Kernel Interface (DKI)
- */
-static const dki_func_t driver_service[] = {
-       DKIENT(device_create),          /* 0 */
-       DKIENT(device_delete),
-       DKIENT(device_broadcast),
-       DKIENT(umem_copyin),
-       DKIENT(umem_copyout),
-       DKIENT(umem_strnlen),
-       DKIENT(kmem_alloc),
-       DKIENT(kmem_free),
-       DKIENT(kmem_map),
-       DKIENT(page_alloc),
-       DKIENT(page_free),              /* 10 */
-       DKIENT(page_reserve),
-       DKIENT(irq_attach),
-       DKIENT(irq_detach),
-       DKIENT(irq_lock),
-       DKIENT(irq_unlock),
-       DKIENT(timer_timeout),
-       DKIENT(timer_stop),
-       DKIENT(timer_delay),
-       DKIENT(timer_count),
-       DKIENT(timer_hook),             /* 20 */
-       DKIENT(timer_unhook),
-       DKIENT(sched_lock),
-       DKIENT(sched_unlock),
-       DKIENT(sched_tsleep),
-       DKIENT(sched_wakeup),
-       DKIENT(sched_dpc),
-       DKIENT(printk),
-       DKIENT(panic),
-       DKIENT(system_reset),
-       DKIENT(kernel_dump),            /* 30 */
-       DKIENT(debug_attach),
-       DKIENT(__task_capable),
-       DKIENT(system_bootinfo),
-       DKIENT(_phys_to_virt),
-       DKIENT(_virt_to_phys),
-};
+/* export the functions used by drivers */
+EXPORT_SYMBOL(device_create);
+EXPORT_SYMBOL(device_delete);
+EXPORT_SYMBOL(device_broadcast);
+EXPORT_SYMBOL(umem_copyin);
+EXPORT_SYMBOL(umem_copyout);
+EXPORT_SYMBOL(umem_strnlen);
+EXPORT_SYMBOL(kmem_alloc);
+EXPORT_SYMBOL(kmem_free);
+EXPORT_SYMBOL(kmem_map);
+EXPORT_SYMBOL(page_alloc);
+EXPORT_SYMBOL(page_free);
+EXPORT_SYMBOL(page_reserve);
+EXPORT_SYMBOL(irq_attach);
+EXPORT_SYMBOL(irq_detach);
+EXPORT_SYMBOL(irq_lock);
+EXPORT_SYMBOL(irq_unlock);
+EXPORT_SYMBOL(timer_timeout);
+EXPORT_SYMBOL(timer_stop);
+EXPORT_SYMBOL(timer_delay);
+EXPORT_SYMBOL(timer_count);
+EXPORT_SYMBOL(timer_hook);
+EXPORT_SYMBOL(timer_unhook);
+EXPORT_SYMBOL(sched_lock);
+EXPORT_SYMBOL(sched_unlock);
+EXPORT_SYMBOL(sched_tsleep);
+EXPORT_SYMBOL(sched_wakeup);
+EXPORT_SYMBOL(sched_dpc);
+EXPORT_SYMBOL(printk);
+EXPORT_SYMBOL(panic);
+EXPORT_SYMBOL(system_reset);
+EXPORT_SYMBOL(kernel_dump);
+EXPORT_SYMBOL(debug_attach);
+EXPORT_SYMBOL(__task_capable);
+EXPORT_SYMBOL(system_bootinfo);
+EXPORT_SYMBOL(phys_to_virt);
+EXPORT_SYMBOL(virt_to_phys);
+
+EXPORT_SYMBOL(assert);          /* assert.c */
+
+EXPORT_SYMBOL(strlcpy);         /* string.c */
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+
+EXPORT_SYMBOL(enqueue);         /* queue.c */
+EXPORT_SYMBOL(dequeue);
+EXPORT_SYMBOL(queue_insert);
+EXPORT_SYMBOL(queue_remove);
+
+EXPORT_SYMBOL(atol);            /* stdlib.c */
 
 /*
  * Increment reference count on an active device.
@@ -513,23 +521,13 @@ static void system_bootinfo(struct boot_info **info)
        return;
 }
 
-static void *_phys_to_virt(void *p_addr)
-{
-       return phys_to_virt(p_addr);
-}
-
-static void *_virt_to_phys(void *v_addr)
-{
-       return virt_to_phys(v_addr);
-}
-
 /*
  * Initialize device driver module.
  */
 void device_init(void)
 {
        struct img_info *img;
-       void (*drv_entry)(const dki_func_t *);
+       void (*drv_entry)(void);
 
        img = &boot_info->driver;
        if (img == NULL)
@@ -541,5 +539,5 @@ void device_init(void)
        /*
         * Call driver module and initialize all device drivers.
         */
-       drv_entry(driver_service);
+       drv_entry();
 }
diff --git a/sys/kern/task.c b/sys/kern/task.c
index 425fd81..cc63a46 100755
--- a/sys/kern/task.c
+++ b/sys/kern/task.c
@@ -561,17 +561,41 @@ void boot_dump(void)
        struct img_info *img;
        int i;
 
-       printk(" text base data base text size data size bss size   task 
name\n");
-       printk(" --------- --------- --------- --------- ---------- 
----------\n");
+       printk(" text base data base  bss base "
+              "text size data size bss size   task name\n");
+       printk(" --------- --------- --------- "
+              "--------- --------- ---------- ----------\n");
 
        img = &boot_info->tasks[0];
        for (i = 0; i < boot_info->nr_tasks; i++, img++) {
-               printk("  %8x  %8x  %8d  %8d  %8d  %s\n",
-                      img->text, img->data,
+               printk("  %8x  %8x  %8x  %8d  %8d  %8d  %s\n",
+                      img->text, img->data, img->bss,
                       img->text_size, img->data_size, img->bss_size,
                       img->name);
        }
 }
+
+void ksym_dump(void)
+{
+       struct img_info *img;
+       int i;
+
+       printk(" ksym addr name                  task name\n");
+       printk(" --------- --------------------- ----------\n");
+
+       img = &boot_info->kernel;
+       for (i = 0; i < 2; i++, img++) {
+               struct kernel_symbol *ksym, *ksym_end;
+               if (img->ksym == 0 || img->ksym_size == 0)
+                       continue;
+
+               ksym_end = (void *)(img->ksym + img->ksym_size);
+               for (ksym = (void *)img->ksym; ksym < ksym_end; ksym++) {
+                       printk("  %8x  %20s  %s\n",
+                              ksym->value, ksym->name, img->name);
+               }
+       }
+}
 #endif
 
 void task_init(void)
diff --git a/sys/lib/Makefile b/sys/lib/Makefile
index c9e0fad..986b91c 100755
--- a/sys/lib/Makefile
+++ b/sys/lib/Makefile
@@ -1,4 +1,4 @@
 TARGET = libkern.a
 TYPE   = LIBRARY
-OBJS   = string.o queue.o vsprintf.o
+OBJS   = string.o queue.o vsprintf.o stdlib.o
 include $(PREX_SRC)/mk/sys.mk
diff --git a/sys/lib/stdlib.c b/sys/lib/stdlib.c
new file mode 100755
index 0000000..e7f85a5
--- /dev/null
+++ b/sys/lib/stdlib.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2005, Kohsuke Ohtani
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors 
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * stdlib.c - minimum standard library
+ */
+
+/*
+ * Convert string to long interger
+ * This version does not support minus value.
+ */
+long atol(const char *str)
+{
+       long val = 0;
+
+       while (*str == ' ')
+               str++;
+       while (*str >= '0' && *str <= '9') {
+               val *= 10;
+               val += (*str - '0');
+               str++;
+       }
+       return val;
+}
diff --git a/sys/mem/page.c b/sys/mem/page.c
index 84b37df..e1e9625 100755
--- a/sys/mem/page.c
+++ b/sys/mem/page.c
@@ -70,6 +70,18 @@ static struct page_block page_head;  /* first free block */
 static size_t total_bytes;
 static size_t used_bytes;
 
+/* normal versions of extern inline function */
+void *phys_to_virt(void *p_addr)
+{
+       return p_addr + PAGE_OFFSET; /* (void *) size = 1 in gcc */
+}
+
+/* normal versions of extern inline function */
+void *virt_to_phys(void *v_addr)
+{
+       return v_addr - PAGE_OFFSET;
+}
+
 /*
  * Allocate continuous pages of the specified size.
  * This routine returns the physical address of a new free
diff --git a/user/bin/kmon/cmd.c b/user/bin/kmon/cmd.c
index 5f7f912..1105b8b 100755
--- a/user/bin/kmon/cmd.c
+++ b/user/bin/kmon/cmd.c
@@ -56,6 +56,8 @@ int cmd_irq(int argc, char **argv);
 int cmd_device(int argc, char **argv);
 int cmd_vm(int argc, char **argv);
 int cmd_dmesg(int argc, char **argv);
+int cmd_boot(int argc, char **argv);
+int cmd_ksym(int argc, char **argv);
 #endif
 int cmd_reboot(int argc, char **argv);
 int cmd_shutdown(int argc, char **argv);
@@ -87,6 +89,8 @@ static struct cmd_entry cmd_table[] = {
        { "device"      ,cmd_device     ,"device   - Dump devices" },
        { "vm"          ,cmd_vm         ,"vm       - Dump virtual memory 
information" },
        { "dmesg"       ,cmd_dmesg      ,"dmesg    - Dump kernel message log" },
+       { "boot"        ,cmd_boot       ,"boot     - Dump boot image 
information" },
+       { "ksym"        ,cmd_ksym       ,"ksym     - Dump kernel symbol 
information" },
 #endif
        { "reboot"      ,cmd_reboot     ,"reboot   - Reboot system" },
        { "shutdown"    ,cmd_shutdown   ,"shutdown - Shutdown system" },
@@ -200,6 +204,18 @@ int cmd_dmesg(int argc, char **argv)
        return 0;
 }
 
+int cmd_boot(int argc, char **argv)
+{
+       sys_debug(DBGCMD_DUMP, DUMP_BOOT);
+       return 0;
+}
+
+int cmd_ksym(int argc, char **argv)
+{
+       sys_debug(DBGCMD_DUMP, DUMP_KSYM);
+       return 0;
+}
+
 #endif /* DEBUG */
 
 int cmd_reboot(int argc, char **argv)
diff --git a/user/include/prex/prex.h b/user/include/prex/prex.h
index e7a51d0..59aa64d 100755
--- a/user/include/prex/prex.h
+++ b/user/include/prex/prex.h
@@ -288,5 +288,7 @@ struct info_device {
 #define DUMP_VM                7
 #define DUMP_MSGLOG    8
 #define DUMP_TRACE     9
+#define DUMP_BOOT      10
+#define DUMP_KSYM      11
 
 #endif /* !_PREX_H */
-- 
1.5.0.3.GIT




-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Prex-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/prex-devel

Reply via email to