Revision: 406 Author: nieklinnenbank Date: Mon Oct 18 16:59:47 2010 Log: Implemented booting an image support in the kernel. It is now able to load all processes from the image, create a process for each entry and start scheduling them as unprivileged processes. Additionally, an idle process is created for each CPU detected on the system. http://code.google.com/p/freenos/source/detail?r=406 Modified: /branches/scratch/include/kernel/phys_memory.h /branches/scratch/include/x86/cpu.h /branches/scratch/site_scons/binary.py /branches/scratch/system/main.c /branches/scratch/system/phys_memory.c /branches/scratch/system/process.c /branches/scratch/system/x86/pc/config/kernel.ld /branches/scratch/system/x86/pc/smp.c ======================================= --- /branches/scratch/include/kernel/phys_memory.h Sun Oct 10 16:06:55 2010 +++ /branches/scratch/include/kernel/phys_memory.h Mon Oct 18 16:59:47 2010 @@ -61,6 +61,9 @@ /** Begin and end addresses of the kernel. */ extern addr_t kernel_start, kernel_end; +/** Begin and end addresses of the boot image. */ +extern addr_t boot_img_start, boot_img_end; + /** Total size of the in-memory kernel, including memory map. */ extern size_t kernel_size; ======================================= --- /branches/scratch/include/x86/cpu.h Sun Oct 10 16:06:55 2010 +++ /branches/scratch/include/x86/cpu.h Mon Oct 18 16:59:47 2010 @@ -36,12 +36,12 @@ #define CR4_TSD 0x00000004 /** Kernel Code Segment. */ -#define KERNEL_CS 1 -#define KERNEL_CS_SEL 0x8 +#define KERN_CS 1 +#define KERN_CS_SEL 0x8 /** System Data Segment. */ -#define KERNEL_DS 2 -#define KERNEL_DS_SEL 0x10 +#define KERN_DS 2 +#define KERN_DS_SEL 0x10 /** User Code Segment. */ #define USER_CS 3 @@ -51,9 +51,9 @@ #define USER_DS 4 #define USER_DS_SEL (0x20 | 3) -/** User TSS. */ -#define USER_TSS 5 -#define USER_TSS_SEL 0x28 +/** Task State Segment. */ +#define KERN_TSS 5 +#define KERN_TSS_SEL 0x28 /* The size of our stack (16KB). */ #define STACK_SIZE 0x4000 @@ -114,6 +114,16 @@ #define sti() \ __asm__ volatile("sti") +/** + * Loads the Task State Register (LTR) with the given segment. + * @param sel TSS segment selector. + */ +#define ltr(sel) \ +({ \ + u16 tr = sel; \ + __asm__ volatile ("ltr %0\n" :: "r"(tr)); \ +}) + typedef struct cpu_state { /* Segments. */ ======================================= --- /branches/scratch/site_scons/binary.py Sat Oct 16 19:56:53 2010 +++ /branches/scratch/site_scons/binary.py Mon Oct 18 16:59:47 2010 @@ -37,7 +37,9 @@ " * This file is auto-generated from " + str(source[0]) + "\n" + " */\n" "\n" - "unsigned char " + symbol + "[] = { ") + "unsigned char __attribute__((aligned(4096))) " + + "__attribute__((__section__(\".binary\"))) " + + symbol + "[] = { ") # Loop data. i = 0 ======================================= --- /branches/scratch/system/main.c Sat Oct 16 11:26:27 2010 +++ /branches/scratch/system/main.c Mon Oct 18 16:59:47 2010 @@ -25,21 +25,10 @@ #include <FreeNOS/process.h> #include <FreeNOS/types.h> #include <FreeNOS/version.h> - -void proc(void) -{ -/* for (;;){*/ - printk("PID %d: running on CPU#%d\r\n", - proc_lookup(smp_cpu()->proc), smp_id()); -/* proc_schedule();*/ -/* }*/ - for (;;); -} int main(void) { - int i; - smp_cpu()->flags |= SMP_ACTIVE; + arch_init_cpu(); if (smp_is_bootcpu()) { @@ -54,12 +43,7 @@ irq_init(); smp_init(); virt_memory_init(); - proc_table_init(); - for (i = 0; i < 8; i++) /* TODO: replace this with boot image ;-)*/ - { - proc_resume(proc_create((addr_t) proc)); - } arch_init_clock(); smp_boot_all(); } @@ -74,8 +58,5 @@ irq_enable(); proc_schedule(); - for(;;); - return 0; } - ======================================= --- /branches/scratch/system/phys_memory.c Sun Oct 10 16:06:55 2010 +++ /branches/scratch/system/phys_memory.c Mon Oct 18 16:59:47 2010 @@ -64,13 +64,17 @@ memory_avail = memory_size; kernel_start = (addr_t) &kernel_start; kernel_end = (addr_t) &kernel_end; - kernel_size = (kernel_end - kernel_start) + - (memory_map_end - memory_map); + boot_img_start = (addr_t) &boot_img_start; + boot_img_end = (addr_t) &boot_img_end; /* Allocate physical memory bitmap. */ memory_map = (u8 *)(kernel_end); memory_map_end = memory_map + (memory_size / PAGE_SIZE / 8); + /* Set kernel size. */ + kernel_size = (kernel_end - kernel_start) + + (memory_map_end - memory_map); + /* Clear memory map. */ memset(memory_map, 0, memory_size / PAGE_SIZE / 8); @@ -79,8 +83,10 @@ palloc_from(kernel_start, kernel_size); /* Output system memory. */ - printk("Memory: %dKB total, %dKB avail, %dKB kernel\r\n", - memory_size / 1024, memory_avail / 1024, kernel_size / 1024); + printk("Memory: %dKB total, %dKB avail, %dKB kernel, %dKB bootimg\r\n", + memory_size / 1024, memory_avail / 1024, + (kernel_size-(boot_img_end-boot_img_start)) / 1024, + (boot_img_end-boot_img_start) / 1024); } addr_t palloc(size_t sz) ======================================= --- /branches/scratch/system/process.c Sun Oct 10 16:06:55 2010 +++ /branches/scratch/system/process.c Mon Oct 18 16:59:47 2010 @@ -22,17 +22,76 @@ #include <FreeNOS/arch.h> #include <FreeNOS/smp.h> #include <FreeNOS/irq.h> +#include <FreeNOS/printk.h> #include <FreeNOS/phys_memory.h> #include <FreeNOS/virt_memory.h> +#include <libboot.h> #include <string.h> +extern boot_image_t boot_img; static process_t proc_table[PROC_MAX]; static spinlock_t proc_lock; void proc_table_init(void) { + boot_prog_t *prog; + boot_seg_t *seg; + process_t *proc; + pid_t pid; + int num = 0; + + printk("Boot image at %x\r\n", boot_img_start); + + /* Initialize process table lock. */ spinlock_init(&proc_lock); + + /* Clear table. */ memset(proc_table, 0, sizeof(proc_table)); + + /* Parse the boot image. */ + libboot_parse(&boot_img); + + /* + * Loop the boot image. + */ + while ((prog = libboot_getprog())) + { + printk("Loading `%s' ... ", prog->path); + + pid = proc_create(prog->entry); + proc = proc_find(pid); + virt_map_remote_dir(proc); + + printk(" PID %u ... ", pid); + + /* Map program memory segments. */ + while ((seg = libboot_getseg())) + { + printk("%x(%u) => %x ... ", + boot_img_start + seg->offset, seg->size, seg->virt_base); + virt_map(RDIR_VADDR, seg->virt_base, + boot_img_start + seg->offset, seg->size, + PAGE_PR|PAGE_WR|PAGE_USER); + } + virt_unmap_remote_dir(proc); + printk("\r\n"); + + /* Start a copy of idle program on each CPU. */ + if (prog->flags & BOOTPROG_ISIDLE) + { + cpus[num].idle = proc; + + if (num < cpus_total - 1) + { + libboot_repeat_prog(); + num++; + } + else + num = 0; + } + else + proc_resume(pid); + } } pid_t proc_create(addr_t entry) @@ -100,7 +159,9 @@ void proc_schedule(void) { static pid_t last_pid = 0; - process_t *old = smp_cpu()->proc; + process_t *old = smp_cpu()->proc; + process_t *new; + pid_t start = last_pid; /* No IRQ's allowed at this point. */ irq_disable(); @@ -111,21 +172,32 @@ { last_pid = (last_pid + 1) % PROC_MAX; + /* Fall back to the idle process if nobody ready. */ + if (last_pid == start) + { + new = smp_cpu()->idle; + break; + } + /* + * Try this process, if availble, + * ready and not already running. + */ if (proc_table[last_pid].flags & PROC_AVAIL && proc_table[last_pid].flags & PROC_READY && !(proc_table[last_pid].flags & PROC_RUNNING)) { - proc_table[last_pid].flags |= PROC_RUNNING; - smp_cpu()->proc = &proc_table[last_pid]; + new = &proc_table[last_pid]; break; } } + /* Mark the new process running. */ + new->flags |= PROC_RUNNING; + smp_cpu()->proc = new; spinlock_leave(&proc_lock); /* Continue execution of the chosen process. */ - arch_context_switch(old ? &old->stack : NULL, - old ? &old->flags : NULL, - smp_cpu()->proc->page_dir, - smp_cpu()->proc->stack); -} - + if (old != new) + { + arch_context_switch(old, new); + } +} =======================================--- /branches/scratch/system/x86/pc/config/kernel.ld Sun Oct 10 16:06:55 2010 +++ /branches/scratch/system/x86/pc/config/kernel.ld Mon Oct 18 16:59:47 2010
@@ -3,7 +3,7 @@ SECTIONS{ . = 0x01000000; - .text :{ + .text : { kernel_start = .; LONG(0) *(.boot) @@ -16,6 +16,10 @@ .data ALIGN (0x1000) : { *(.data) + . = ALIGN(0x1000); + boot_img_start = .; + *(.binary) + boot_img_end = .; } .bss : { @@ -25,4 +29,3 @@ LONG(0) } } - ======================================= --- /branches/scratch/system/x86/pc/smp.c Sun Oct 10 16:06:55 2010 +++ /branches/scratch/system/x86/pc/smp.c Mon Oct 18 16:59:47 2010 @@ -63,6 +63,7 @@ cpus[0].flags = SMP_EMPTY; cpus[0].stack = 0; cpus[0].proc = NULL; + cpus[0].idle = NULL; } /* Setup Application Processor entry code. */ memcpy((void *) MP_BOOTENTRY_ADDR, smp_entry, PAGE_SIZE);