[freenos] r406 committed - Implemented booting an image support in the kernel....

  • From: freenos@xxxxxxxxxxxxxx
  • To: freenos@xxxxxxxxxxxxx
  • Date: Tue, 19 Oct 2010 00:16:08 +0000

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);

Other related posts:

  • » [freenos] r406 committed - Implemented booting an image support in the kernel.... - freenos