SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/main.c (Article 9.5) and /sos/main.c (Article 6)


001 /* Copyright (C) 2004  The SOS Team               001 /* Copyright (C) 2004  The SOS Team
                                                   >> 002    Copyright (C) 1999  Free Software Foundation, Inc.
002                                                   003 
003    This program is free software; you can redi    004    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    005    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    006    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    007    of the License, or (at your option) any later version.
007                                                   008    
008    This program is distributed in the hope tha    009    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     010    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    012    GNU General Public License for more details.
012                                                   013    
013    You should have received a copy of the GNU     014    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    015    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    016    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           017    USA. 
017 */                                                018 */
018                                                   019 
019 #include <sos/errno.h>                         << 
020                                                << 
021 /* Include definitions of the multiboot standa    020 /* Include definitions of the multiboot standard */
022 #include <bootstrap/multiboot.h>                  021 #include <bootstrap/multiboot.h>
023 #include <hwcore/idt.h>                           022 #include <hwcore/idt.h>
024 #include <hwcore/gdt.h>                           023 #include <hwcore/gdt.h>
025 #include <hwcore/irq.h>                           024 #include <hwcore/irq.h>
026 #include <hwcore/exception.h>                     025 #include <hwcore/exception.h>
027 #include <hwcore/i8254.h>                         026 #include <hwcore/i8254.h>
028 #include <sos/list.h>                             027 #include <sos/list.h>
029 #include <sos/physmem.h>                          028 #include <sos/physmem.h>
030 #include <hwcore/paging.h>                        029 #include <hwcore/paging.h>
031 #include <hwcore/mm_context.h>                 << 
032 #include <hwcore/swintr.h>                     << 
033 #include <sos/kmem_vmm.h>                         030 #include <sos/kmem_vmm.h>
034 #include <sos/kmalloc.h>                          031 #include <sos/kmalloc.h>
035 #include <sos/time.h>                          << 
036 #include <sos/thread.h>                        << 
037 #include <sos/process.h>                       << 
038 #include <sos/umem_vmm.h>                      << 
039 #include <sos/klibc.h>                            032 #include <sos/klibc.h>
040 #include <sos/assert.h>                           033 #include <sos/assert.h>
041 #include <drivers/x86_videomem.h>                 034 #include <drivers/x86_videomem.h>
042 #include <drivers/bochs.h>                        035 #include <drivers/bochs.h>
043 #include <sos/calcload.h>                      !! 036 
044 #include <sos/umem_vmm.h>                      << 
045 #include <sos/binfmt_elf32.h>                  << 
046 #include <drivers/zero.h>                      << 
047 #include <sos/fs.h>                            << 
048 #include <drivers/fs_virtfs.h>                 << 
049 #include <drivers/devices.h>                   << 
050 #include <drivers/mem.h>                       << 
051 #include <drivers/tty.h>                       << 
052 #include <drivers/console.h>                   << 
053 #include <drivers/serial.h>                    << 
054 #include <sos/blkdev.h>                        << 
055 #include <sos/fs_pagecache.h>                  << 
056 #include <drivers/ide.h>                       << 
057                                                   037 
058 /* Helper function to display each bits of a 3    038 /* Helper function to display each bits of a 32bits integer on the
059    screen as dark or light carrets */             039    screen as dark or light carrets */
060 void display_bits(unsigned char row, unsigned     040 void display_bits(unsigned char row, unsigned char col,
061                   unsigned char attribute,        041                   unsigned char attribute,
062                   sos_ui32_t integer)             042                   sos_ui32_t integer)
063 {                                                 043 {
064   int i;                                          044   int i;
065   /* Scan each bit of the integer, MSb first *    045   /* Scan each bit of the integer, MSb first */
066   for (i = 31 ; i >= 0 ; i--)                     046   for (i = 31 ; i >= 0 ; i--)
067     {                                             047     {
068       /* Test if bit i of 'integer' is set */     048       /* Test if bit i of 'integer' is set */
069       int bit_i = (integer & (1 << i));           049       int bit_i = (integer & (1 << i));
070       /* Ascii 219 => dark carret, Ascii 177 =    050       /* Ascii 219 => dark carret, Ascii 177 => light carret */
071       unsigned char ascii_code = bit_i?219:177    051       unsigned char ascii_code = bit_i?219:177;
072       sos_x86_videomem_putchar(row, col++,        052       sos_x86_videomem_putchar(row, col++,
073                                attribute,         053                                attribute,
074                                ascii_code);       054                                ascii_code);
075     }                                             055     }
076 }                                                 056 }
077                                                   057 
                                                   >> 058 
078 /* Clock IRQ handler */                           059 /* Clock IRQ handler */
079 static void clk_it(int intid)                  !! 060 static void clk_it(int intid,
                                                   >> 061                    const struct sos_cpu_kstate *cpu_kstate)
080 {                                                 062 {
081   static sos_ui32_t clock_count = 0;              063   static sos_ui32_t clock_count = 0;
082                                                   064 
083   display_bits(0, 48,                             065   display_bits(0, 48,
084                SOS_X86_VIDEO_FG_LTGREEN | SOS_    066                SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
085                clock_count);                      067                clock_count);
086   clock_count++;                                  068   clock_count++;
087                                                << 
088   /* Execute the expired timeout actions (if a << 
089   sos_time_do_tick();                          << 
090                                                << 
091   /* Update scheduler statistics and status */ << 
092   sos_sched_do_timer_tick();                   << 
093 }                                                 069 }
094                                                   070 
095                                                   071 
096 /* ===========================================    072 /* ======================================================================
097  * Page fault exception handling                  073  * Page fault exception handling
098  */                                               074  */
099                                                   075 
                                                   >> 076 /* Helper function to dump a backtrace on bochs and/or the console */
                                                   >> 077 static void dump_backtrace(const struct sos_cpu_kstate *cpu_kstate,
                                                   >> 078                            sos_vaddr_t stack_bottom,
                                                   >> 079                            sos_size_t  stack_size,
                                                   >> 080                            sos_bool_t on_console,
                                                   >> 081                            sos_bool_t on_bochs)
                                                   >> 082 {
                                                   >> 083   static void backtracer(sos_vaddr_t PC,
                                                   >> 084                          sos_vaddr_t params,
                                                   >> 085                          sos_ui32_t depth,
                                                   >> 086                          void *custom_arg)
                                                   >> 087     {
                                                   >> 088       sos_ui32_t invalid = 0xffffffff, *arg1, *arg2, *arg3, *arg4;
                                                   >> 089 
                                                   >> 090       /* Get the address of the first 3 arguments from the
                                                   >> 091          frame. Among these arguments, 0, 1, 2, 3 arguments might be
                                                   >> 092          meaningful (depending on how many arguments the function may
                                                   >> 093          take). */
                                                   >> 094       arg1 = (sos_ui32_t*)params;
                                                   >> 095       arg2 = (sos_ui32_t*)(params+4);
                                                   >> 096       arg3 = (sos_ui32_t*)(params+8);
                                                   >> 097       arg4 = (sos_ui32_t*)(params+12);
                                                   >> 098 
                                                   >> 099       /* Make sure the addresses of these arguments fit inside the
                                                   >> 100          stack boundaries */
                                                   >> 101 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vaddr_t)(v)) \
                                                   >> 102                              && ((sos_vaddr_t)(v) < (u)) )
                                                   >> 103       if (!INTERVAL_OK(stack_bottom, arg1, stack_bottom + stack_size))
                                                   >> 104         arg1 = &invalid;
                                                   >> 105       if (!INTERVAL_OK(stack_bottom, arg2, stack_bottom + stack_size))
                                                   >> 106         arg2 = &invalid;
                                                   >> 107       if (!INTERVAL_OK(stack_bottom, arg3, stack_bottom + stack_size))
                                                   >> 108         arg3 = &invalid;
                                                   >> 109       if (!INTERVAL_OK(stack_bottom, arg4, stack_bottom + stack_size))
                                                   >> 110         arg4 = &invalid;
                                                   >> 111 
                                                   >> 112       /* Print the function context for this frame */
                                                   >> 113       if (on_bochs)
                                                   >> 114         sos_bochs_printf("[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n",
                                                   >> 115                          (unsigned)depth, (unsigned)PC,
                                                   >> 116                          (unsigned)*arg1, (unsigned)*arg2,
                                                   >> 117                          (unsigned)*arg3);
                                                   >> 118 
                                                   >> 119       if (on_console)
                                                   >> 120         sos_x86_videomem_printf(23-depth, 3,
                                                   >> 121                                 SOS_X86_VIDEO_BG_BLUE
                                                   >> 122                                   | SOS_X86_VIDEO_FG_LTGREEN,
                                                   >> 123                                 "[%d] PC=0x%x arg1=0x%x arg2=0x%x arg3=0x%x arg4=0x%x",
                                                   >> 124                                 (unsigned)depth, PC,
                                                   >> 125                                 (unsigned)*arg1, (unsigned)*arg2,
                                                   >> 126                                 (unsigned)*arg3, (unsigned)*arg4);
                                                   >> 127       
                                                   >> 128     }
                                                   >> 129 
                                                   >> 130   sos_backtrace(cpu_kstate, 15, stack_bottom, stack_size, backtracer, NULL);
                                                   >> 131 }
                                                   >> 132 
100                                                   133 
101 /* Page fault exception handler with demand pa    134 /* Page fault exception handler with demand paging for the kernel */
102 static void pgflt_ex(int intid, struct sos_cpu !! 135 static void pgflt_ex(int intid, const struct sos_cpu_kstate *ctxt)
103 {                                                 136 {
104   static sos_ui32_t demand_paging_count = 0;      137   static sos_ui32_t demand_paging_count = 0;
105   struct sos_thread * cur_thr = sos_thread_get !! 138   sos_vaddr_t faulting_vaddr = sos_cpu_kstate_get_EX_faulting_vaddr(ctxt);
106   sos_vaddr_t faulting_vaddr  = sos_cpu_contex << 
107   sos_paddr_t ppage_paddr;                        139   sos_paddr_t ppage_paddr;
108                                                   140 
109   if (sos_cpu_context_is_in_user_mode(ctxt)    << 
110       || (cur_thr->fixup_uaccess.return_vaddr) << 
111     {                                          << 
112       __label__ unforce_address_space;         << 
113       sos_bool_t need_to_setup_mmu;            << 
114       sos_ui32_t errcode = sos_cpu_context_get << 
115                                                << 
116       /* Make sure to always stay in the inter << 
117          configuration */                      << 
118       need_to_setup_mmu = (cur_thr->squatted_m << 
119                            != sos_process_get_ << 
120       if (need_to_setup_mmu)                   << 
121         sos_thread_prepare_user_space_access(N << 
122                                                << 
123       if (SOS_OK ==                            << 
124           sos_umem_vmm_try_resolve_page_fault( << 
125                                                << 
126                                                << 
127         goto unforce_address_space;            << 
128                                                << 
129       /* If the page fault occured in kernel m << 
130          the fixup address */                  << 
131       if (! sos_cpu_context_is_in_user_mode(ct << 
132         {                                      << 
133           cur_thr->fixup_uaccess.faulted_uaddr << 
134           sos_cpu_context_set_EX_return_addres << 
135                                                << 
136           goto unforce_address_space;          << 
137         }                                      << 
138                                                << 
139       if (need_to_setup_mmu)                   << 
140         sos_thread_end_user_space_access();    << 
141                                                << 
142       sos_bochs_printf("\e[35mTHR %p: Unresolv << 
143                        (void*)sos_thread_get_c << 
144                        sos_cpu_context_get_PC( << 
145                        (unsigned)faulting_vadd << 
146                        (unsigned)sos_cpu_conte << 
147       sos_bochs_printf("Terminating User threa << 
148       sos_thread_exit();                       << 
149                                                << 
150     unforce_address_space:                     << 
151       if (need_to_setup_mmu)                   << 
152         sos_thread_end_user_space_access();    << 
153       return;                                  << 
154     }                                          << 
155                                                << 
156   /* Check if address is covered by any VMM ra    141   /* Check if address is covered by any VMM range */
157   if (! sos_kmem_vmm_is_valid_vaddr(faulting_v    142   if (! sos_kmem_vmm_is_valid_vaddr(faulting_vaddr))
158     {                                             143     {
159       /* No: The page fault is out of any kern    144       /* No: The page fault is out of any kernel virtual region. For
160          the moment, we don't handle this. */     145          the moment, we don't handle this. */
161       sos_display_fatal_error("Unresolved page !! 146       dump_backtrace(ctxt,
162                               sos_cpu_context_ !! 147                      bootstrap_stack_bottom,
                                                   >> 148                      bootstrap_stack_size,
                                                   >> 149                      TRUE, TRUE);
                                                   >> 150       sos_display_fatal_error("Unresolved page Fault on access to address 0x%x (info=%x)!",
163                               (unsigned)faulti    151                               (unsigned)faulting_vaddr,
164                               (unsigned)sos_cp !! 152                               (unsigned)sos_cpu_kstate_get_EX_info(ctxt));
165       SOS_ASSERT_FATAL(! "Got page fault (note    153       SOS_ASSERT_FATAL(! "Got page fault (note: demand paging is disabled)");
166     }                                             154     }
167                                                   155 
168                                                   156 
169   /*                                              157   /*
170    * Demand paging in kernel space             !! 158    * Demand paging
171    */                                             159    */
172                                                   160  
173   /* Update the number of demand paging reques    161   /* Update the number of demand paging requests handled */
174   demand_paging_count ++;                         162   demand_paging_count ++;
175   display_bits(0, 0,                              163   display_bits(0, 0,
176                SOS_X86_VIDEO_FG_LTRED | SOS_X8    164                SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE,
177                demand_paging_count);              165                demand_paging_count);
178                                                   166 
179   /* Allocate a new page for the virtual addre    167   /* Allocate a new page for the virtual address */
180   ppage_paddr = sos_physmem_ref_physpage_new(F    168   ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
181   if (! ppage_paddr)                              169   if (! ppage_paddr)
182     SOS_ASSERT_FATAL(! "TODO: implement swap.     170     SOS_ASSERT_FATAL(! "TODO: implement swap. (Out of mem in demand paging because no swap for kernel yet !)");
183   SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp    171   SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(ppage_paddr,
184                                             SO    172                                             SOS_PAGE_ALIGN_INF(faulting_vaddr),
185                                             FA    173                                             FALSE,
186                                             SO    174                                             SOS_VM_MAP_PROT_READ
187                                             |     175                                             | SOS_VM_MAP_PROT_WRITE
188                                             |     176                                             | SOS_VM_MAP_ATOMIC));
189   sos_physmem_unref_physpage(ppage_paddr);        177   sos_physmem_unref_physpage(ppage_paddr);
190                                                   178 
191   /* Ok, we can now return to interrupted cont    179   /* Ok, we can now return to interrupted context */
192 }                                                 180 }
193                                                   181 
194                                                   182 
195                                                   183 
196 /* ===========================================    184 /* ======================================================================
197  * An operating system MUST always have a read !! 185  * Demonstrate the use of the CPU kernet context management API:
198  * what would the CPU have to execute ?!       !! 186  *  - A coroutine prints "Hlowrd" and switches to the other after each
                                                   >> 187  *    letter
                                                   >> 188  *  - A coroutine prints "el ol\n" and switches back to the other after
                                                   >> 189  *    each letter.
                                                   >> 190  * The first to reach the '\n' returns back to main.
199  */                                               191  */
200 static void idle_thread(void* unused) __attrib !! 192 struct sos_cpu_kstate *ctxt_hello1;
201 static void idle_thread(void* unused)          !! 193 struct sos_cpu_kstate *ctxt_hello2;
                                                   >> 194 struct sos_cpu_kstate *ctxt_main;
                                                   >> 195 sos_vaddr_t hello1_stack, hello2_stack;
                                                   >> 196 
                                                   >> 197 static void reclaim_stack(sos_vaddr_t stack_vaddr)
202 {                                                 198 {
203   sos_ui32_t idle_twiddle = 0;                 !! 199   sos_kfree(stack_vaddr);
                                                   >> 200 }
                                                   >> 201 
204                                                   202 
205   while (1)                                    !! 203 static void exit_hello12(sos_vaddr_t stack_vaddr)
                                                   >> 204 {
                                                   >> 205   sos_cpu_kstate_exit_to(ctxt_main,
                                                   >> 206                          (sos_cpu_kstate_function_arg1_t*) reclaim_stack,
                                                   >> 207                          stack_vaddr);
                                                   >> 208 }
                                                   >> 209 
                                                   >> 210 
                                                   >> 211 static void hello1 (char *str)
                                                   >> 212 {
                                                   >> 213   for ( ; *str != '\n' ; str++)
206     {                                             214     {
207       /* Remove this instruction if you get an !! 215       sos_bochs_printf("hello1: %c\n", *str);
208          exception (old 80386 CPU) */          !! 216       sos_cpu_kstate_switch(& ctxt_hello1, ctxt_hello2);
209       asm("hlt\n");                            !! 217     }
210                                                   218 
211       idle_twiddle ++;                         !! 219   /* You can uncomment this in case you explicitly want to exit
212       display_bits(0, 0, SOS_X86_VIDEO_FG_GREE !! 220      now. But returning from the function will do the same */
213                    idle_twiddle);              !! 221   /* sos_cpu_kstate_exit_to(ctxt_main,
214                                                !! 222                          (sos_cpu_kstate_function_arg1_t*) reclaim_stack,
215       /* Lend the CPU to some other thread */  !! 223                          hello1_stack); */
216       sos_thread_yield();                      !! 224 }
                                                   >> 225 
                                                   >> 226 
                                                   >> 227 static void hello2 (char *str)
                                                   >> 228 {
                                                   >> 229   for ( ; *str != '\n' ; str++)
                                                   >> 230     {
                                                   >> 231       sos_bochs_printf("hello2: %c\n", *str);
                                                   >> 232       sos_cpu_kstate_switch(& ctxt_hello2, ctxt_hello1);
217     }                                             233     }
                                                   >> 234 
                                                   >> 235   /* You can uncomment this in case you explicitly want to exit
                                                   >> 236      now. But returning from the function will do the same */
                                                   >> 237   /* sos_cpu_kstate_exit_to(ctxt_main,
                                                   >> 238                          (sos_cpu_kstate_function_arg1_t*) reclaim_stack,
                                                   >> 239                          hello2_stack); */
                                                   >> 240 }
                                                   >> 241 
                                                   >> 242 
                                                   >> 243 void print_hello_world ()
                                                   >> 244 {
                                                   >> 245 #define DEMO_STACK_SIZE 1024
                                                   >> 246   /* Allocate the stacks */
                                                   >> 247   hello1_stack = sos_kmalloc(DEMO_STACK_SIZE, 0);
                                                   >> 248   hello2_stack = sos_kmalloc(DEMO_STACK_SIZE, 0);
                                                   >> 249 
                                                   >> 250   /* Initialize the coroutines' contexts */
                                                   >> 251   sos_cpu_kstate_init(&ctxt_hello1,
                                                   >> 252                       (sos_cpu_kstate_function_arg1_t*) hello1,
                                                   >> 253                       (sos_ui32_t) "Hlowrd",
                                                   >> 254                       (sos_vaddr_t) hello1_stack, DEMO_STACK_SIZE,
                                                   >> 255                       (sos_cpu_kstate_function_arg1_t*) exit_hello12,
                                                   >> 256                       (sos_ui32_t) hello1_stack);
                                                   >> 257   sos_cpu_kstate_init(&ctxt_hello2,
                                                   >> 258                       (sos_cpu_kstate_function_arg1_t*) hello2,
                                                   >> 259                       (sos_ui32_t) "el ol\n",
                                                   >> 260                       (sos_vaddr_t) hello2_stack, DEMO_STACK_SIZE,
                                                   >> 261                       (sos_cpu_kstate_function_arg1_t*) exit_hello12,
                                                   >> 262                       (sos_ui32_t) hello2_stack);
                                                   >> 263 
                                                   >> 264   /* Go to first coroutine */
                                                   >> 265   sos_bochs_printf("Printing Hello World\\n...\n");
                                                   >> 266   sos_cpu_kstate_switch(& ctxt_main, ctxt_hello1);
                                                   >> 267 
                                                   >> 268   /* The first coroutine to reach the '\n' switched back to us */
                                                   >> 269   sos_bochs_printf("Back in main !\n");
218 }                                                 270 }
219                                                   271 
220                                                   272 
221 /* ===========================================    273 /* ======================================================================
222  * Kernel thread showing some CPU usage statis !! 274  * Generate page faults on an unmapped but allocated kernel virtual
                                                   >> 275  * region, which results in a series of physical memory mappings for the
                                                   >> 276  * faulted pages.
223  */                                               277  */
224 #define LOAD_DISPLAY_BASELINE  4               !! 278 static void test_demand_paging(int nb_alloc_vpages, int nb_alloc_ppages)
225 #define LOAD_DISPLAY_STARTROW 34               !! 279 {
226 static void stat_thread(void * unused) __attri !! 280   int i;
227 static void stat_thread(void * unused)         !! 281   sos_vaddr_t base_vaddr;
228 {                                              !! 282 
229   while (1)                                    !! 283   sos_x86_videomem_printf(10, 0,
230     {                                          !! 284                           SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
231       sos_ui32_t flags;                        !! 285                           "Demand paging test (alloc %dMB of VMM, test %dkB RAM)",
232       sos_ui32_t load1, load5, load15;         !! 286                           nb_alloc_vpages >> 8, nb_alloc_ppages << 2);
233       char str1[11], str5[11], str15[11];      !! 287   
234       struct sos_time t;                       !! 288   /* Allocate virtual memory */
235       t.sec = 1;                               !! 289   base_vaddr = sos_kmem_vmm_alloc(nb_alloc_vpages, 0);
236       t.nanosec = 0;                           !! 290 
237                                                !! 291   SOS_ASSERT_FATAL(base_vaddr != (sos_vaddr_t)NULL);
238       sos_thread_sleep(& t);                   !! 292   sos_x86_videomem_printf(11, 0,
239                                                !! 293                           SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
240       sos_disable_IRQs(flags);                 !! 294                           "Allocated virtual region [0x%x, 0x%x[",
241                                                !! 295                           base_vaddr,
242       /* The IDLE task is EXcluded in the foll !! 296                           base_vaddr + nb_alloc_vpages*SOS_PAGE_SIZE);
243       sos_load_get_sload(&load1, &load5, &load !! 297 
244       sos_load_to_string(str1, load1);         !! 298   /* Now use part of it in physical memory */
245       sos_load_to_string(str5, load5);         !! 299   for (i = 0 ; (i < nb_alloc_ppages) && (i < nb_alloc_vpages) ; i++)
246       sos_load_to_string(str15, load15);       !! 300     {
247       sos_x86_videomem_printf(LOAD_DISPLAY_BAS !! 301       /* Compute an address inside the range */
248                               SOS_X86_VIDEO_FG !! 302       sos_ui32_t *value, j;
249                               "Kernel (- Idle) !! 303       sos_vaddr_t vaddr = base_vaddr;
250                               str1, str5, str1 !! 304       vaddr += (nb_alloc_vpages - (i + 1))*SOS_PAGE_SIZE;
251                                                !! 305       vaddr += 2345;
252       sos_load_get_uload(&load1, &load5, &load !! 306 
253       sos_load_to_string(str1, load1);         !! 307       sos_x86_videomem_printf(12, 0,
254       sos_load_to_string(str5, load5);         !! 308                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
255       sos_load_to_string(str15, load15);       !! 309                               "Writing %d at virtual address 0x%x...",
256       sos_x86_videomem_printf(LOAD_DISPLAY_BAS !! 310                               i, vaddr);
257                               SOS_X86_VIDEO_FG !! 311 
258                               "User: %s %s %s  !! 312       /* Write at this address */
259                               str1, str5, str1 !! 313       value = (sos_ui32_t*)vaddr;
260                                                !! 314       *value = i;
261       sos_load_get_uratio(&load1, &load5, &loa !! 315 
262       sos_load_to_string(str1, load1);         !! 316       /* Yep ! A new page should normally have been allocated for us */
263       sos_load_to_string(str5, load5);         !! 317       sos_x86_videomem_printf(13, 0,
264       sos_load_to_string(str15, load15);       !! 318                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
265       sos_x86_videomem_printf(LOAD_DISPLAY_BAS !! 319                               "Value read at address 0x%x = %d",
266                               SOS_X86_VIDEO_FG !! 320                               vaddr, (unsigned)*value);
267                               "User CPU %%: %s << 
268                               str1, str5, str1 << 
269                                                << 
270       /* The IDLE task is INcluded in the foll << 
271       sos_load_get_sratio(&load1, &load5, &loa << 
272       sos_load_to_string(str1, load1);         << 
273       sos_load_to_string(str5, load5);         << 
274       sos_load_to_string(str15, load15);       << 
275       sos_x86_videomem_printf(LOAD_DISPLAY_BAS << 
276                               SOS_X86_VIDEO_FG << 
277                               "Kernel CPU %% ( << 
278                               str1, str5, str1 << 
279       sos_restore_IRQs(flags);                 << 
280     }                                             321     }
                                                   >> 322 
                                                   >> 323   SOS_ASSERT_FATAL(SOS_OK == sos_kmem_vmm_free(base_vaddr));
                                                   >> 324   /* Yep ! A new page should normally have been allocated for us */
                                                   >> 325   sos_x86_videomem_printf(14, 0,
                                                   >> 326                           SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
                                                   >> 327                           "Done (area un-allocated)");
281 }                                                 328 }
282                                                   329 
283                                                   330 
                                                   >> 331 
284 /* ===========================================    332 /* ======================================================================
285  * Start the "init" (userland) process         !! 333  * Shows how the backtrace stuff works
286  */                                               334  */
287 static sos_ret_t                               !! 335 
288 start_init(struct sos_fs_manager_instance * ro !! 336 /* Recursive function. Print the backtrace from the innermost function */
                                                   >> 337 static void test_backtrace(int i, int magic, sos_vaddr_t stack_bottom,
                                                   >> 338                            sos_size_t  stack_size)
289 {                                                 339 {
290   sos_ret_t retval;                            !! 340   if (i <= 0)
291   struct sos_umem_vmm_as *as_init;             !! 341     {
292   struct sos_process *proc_init;               !! 342       /* The page fault exception handler will print the backtrace of
293   struct sos_thread *new_thr;                  !! 343          this function, because address 0x42 is not mapped */
294   sos_uaddr_t ustack, start_uaddr;             !! 344       *((char*)0x42) = 12;
295   struct sos_fs_opened_file * init_root, * ini << 
296                                                   345 
297   /* Create the new process */                 !! 346       /* More direct variant: */
298   proc_init = sos_process_create("init", FALSE !! 347       /* dump_backtrace(NULL, stack_bottom, stack_size, TRUE, TRUE); */
299   if (! proc_init)                             !! 348     }
300     return -SOS_ENOMEM;                        !! 349   else
301   as_init = sos_process_get_address_space(proc !! 350     test_backtrace(i-1, magic, stack_bottom, stack_size);
                                                   >> 351 }
302                                                   352 
303                                                   353 
304   /*                                           !! 354 /* ======================================================================
305    * Setup the root and CWD directories of the !! 355  * Parsing of Mathematical expressions
306    * this process will correspond to the "glob !! 356  *
307    * system since all the future processes wil !! 357  * This is a recursive lexer/parser/evaluator for arithmetical
308    */                                          !! 358  * expressions. Supports both binary +/-* and unary +- operators, as
309   retval = sos_fs_new_opened_file(proc_init, r !! 359  * well as parentheses.
310                                   SOS_FS_OPEN_ !! 360  *
311                                   & init_root) !! 361  * Terminal tokens (Lexer):
312   if (SOS_OK != retval)                        !! 362  *  - Number: positive integer number
                                                   >> 363  *  - Variable: ascii name (regexp: [a-zA-Z]+)
                                                   >> 364  *  - Operator: +*-/
                                                   >> 365  *  - Opening/closing parentheses
                                                   >> 366  *
                                                   >> 367  * Grammar (Parser):
                                                   >> 368  *  Expression ::= Term E'
                                                   >> 369  *  Expr_lr    ::= + Term Expr_lr | - Term Expr_lr | Nothing
                                                   >> 370  *  Term       ::= Factor Term_lr
                                                   >> 371  *  Term_lr    ::= * Factor Term_lr | / Factor Term_lr | Nothing
                                                   >> 372  *  Factor     ::= - Factor | + Factor | Scalar | ( Expression )
                                                   >> 373  *  Scalar     ::= Number | Variable
                                                   >> 374  *
                                                   >> 375  * Note. This is the left-recursive equivalent of the following basic grammar:
                                                   >> 376  *  Expression ::= Expression + Term | Expression - Term
                                                   >> 377  *  Term       ::= Term * Factor | Term / Factor
                                                   >> 378  *  factor     ::= - Factor | + Factor | Scalar | Variable | ( Expression )
                                                   >> 379  *  Scalar     ::= Number | Variable
                                                   >> 380  *
                                                   >> 381  * The parsing is composed of a 3 stages pipeline:
                                                   >> 382  *  - The reader: reads a string 1 character at a time, transferring
                                                   >> 383  *    the control back to lexer after each char. This function shows the
                                                   >> 384  *    interest in using coroutines, because its state (str) is
                                                   >> 385  *    implicitely stored in the stack between each iteration.
                                                   >> 386  *  - The lexer: consumes the characters from the reader and identifies
                                                   >> 387  *    the terminal tokens, 1 token at a time, transferring control back
                                                   >> 388  *    to the parser after each token. This function shows the interest
                                                   >> 389  *    in using coroutines, because its state (c and got_what_before) is
                                                   >> 390  *    implicitely stored in the stack between each iteration.
                                                   >> 391  *  - The parser: consumes the tokens from the lexer and builds the
                                                   >> 392  *    syntax tree of the expression. There is no real algorithmic
                                                   >> 393  *    interest in defining a coroutine devoted to do this. HOWEVER, we
                                                   >> 394  *    do use one for that because this allows us to switch to a much
                                                   >> 395  *    deeper stack. Actually, the parser is highly recursive, so that
                                                   >> 396  *    the default 16kB stack of the sos_main() function might not be
                                                   >> 397  *    enough. Here, we switch to a 64kB stack, which is safer for
                                                   >> 398  *    recursive functions. The Parser uses intermediary functions: these
                                                   >> 399  *    are defined and implemented as internal nested functions. This is
                                                   >> 400  *    just for the sake of clarity, and is absolutely not mandatory for
                                                   >> 401  *    the algorithm: one can transfer these functions out of the parser
                                                   >> 402  *    function without restriction.
                                                   >> 403  *
                                                   >> 404  * The evaluator is another recursive function that reuses the
                                                   >> 405  * parser's stack to evaluate the parsed expression with the given
                                                   >> 406  * values for the variables present in the expression. As for the
                                                   >> 407  * parser function, this function defines and uses a nested function,
                                                   >> 408  * which can be extracted from the main evaluation function at will.
                                                   >> 409  *
                                                   >> 410  * All these functions support a kind of "exception" feature: when
                                                   >> 411  * something goes wrong, control is transferred DIRECTLY back to the
                                                   >> 412  * sos_main() context, without unrolling the recursions. This shows
                                                   >> 413  * how exceptions basically work, but one should not consider this as
                                                   >> 414  * a reference exceptions implementation. Real exception mechanisms
                                                   >> 415  * (such as that in the C++ language) call the destructors to the
                                                   >> 416  * objects allocated on the stack during the "stack unwinding" process
                                                   >> 417  * upon exception handling, which complicates a lot the mechanism. We
                                                   >> 418  * don't have real Objects here (in the OOP sense, full-featured with
                                                   >> 419  * destructors), so we don't have to complicate things.
                                                   >> 420  *
                                                   >> 421  * After this little coroutine demo, one should forget all about such
                                                   >> 422  * a low-level manual direct manipulation of stacks. This would
                                                   >> 423  * probably mess up the whole kernel to do what we do here (locked
                                                   >> 424  * resources such as mutex/semaphore won't be correctly unlocked,
                                                   >> 425  * ...). Higher level "kernel thread" primitives will soon be
                                                   >> 426  * presented, which provide a higher-level set of APIs to manage CPU
                                                   >> 427  * contexts. You'll have to use EXCLUSIVELY those APIs. If you still
                                                   >> 428  * need a huge stack to do recursion for example, please don't even
                                                   >> 429  * think of changing manually the stack for something bigger ! Simply
                                                   >> 430  * rethink your algorithm, making it non-recursive.
                                                   >> 431  */
                                                   >> 432 
                                                   >> 433 
                                                   >> 434 /* The stacks involved */
                                                   >> 435 static char stack_reader[1024];
                                                   >> 436 static char stack_lexer[1024];
                                                   >> 437 static char deep_stack[65536]; /* For the parser and the evaluator */
                                                   >> 438 
                                                   >> 439 /* The CPU states for the various coroutines */
                                                   >> 440 static struct sos_cpu_kstate *st_reader, *st_lexer, *st_parser,
                                                   >> 441   *st_eval, *st_free, *st_main;
                                                   >> 442 
                                                   >> 443 
                                                   >> 444 /*
                                                   >> 445  * Default exit/reclaim functions: return control to the "sos_main()"
                                                   >> 446  * context
                                                   >> 447  */
                                                   >> 448 static void reclaim(int unused)
                                                   >> 449 {
                                                   >> 450 }
                                                   >> 451 static void func_exit(sos_ui32_t unused)
                                                   >> 452 {
                                                   >> 453   sos_cpu_kstate_exit_to(st_main, (sos_cpu_kstate_function_arg1_t*)reclaim, 0);
                                                   >> 454 }
                                                   >> 455 
                                                   >> 456 
                                                   >> 457 /*
                                                   >> 458  * The reader coroutine and associated variable. This coroutine could
                                                   >> 459  * have been a normal function, except that the current parsed
                                                   >> 460  * character would have to be stored somewhere.
                                                   >> 461  */
                                                   >> 462 static char data_reader_to_lexer;
                                                   >> 463 
                                                   >> 464 static void func_reader(const char *str)
                                                   >> 465 {
                                                   >> 466   for ( ; str && (*str != '\0') ; str++)
313     {                                             467     {
314       sos_process_unref(proc_init);            !! 468       data_reader_to_lexer = *str;
315       return -SOS_ENOENT;                      !! 469       sos_cpu_kstate_switch(& st_reader, st_lexer);
316     }                                             470     }
317                                                   471 
318   /* Duplicate the root file to set the curren !! 472   data_reader_to_lexer = '\0';
319      the init process */                       !! 473   sos_cpu_kstate_switch(& st_reader, st_lexer);
320   retval = sos_fs_duplicate_opened_file(init_r !! 474 }
321                                         & init !! 475 
322   if (SOS_OK != retval)                        !! 476 
                                                   >> 477 /*
                                                   >> 478  * The Lexer coroutine and associated types/variables. This coroutine
                                                   >> 479  * could have been a normal function, except that the current parsed
                                                   >> 480  * character, token and previous token would have to be stored
                                                   >> 481  * somewhere.
                                                   >> 482  */
                                                   >> 483 #define STR_VAR_MAXLEN 16
                                                   >> 484 static struct lex_elem
                                                   >> 485 {
                                                   >> 486   enum { LEX_IS_NUMBER, LEX_IS_OPER, LEX_IS_VAR,
                                                   >> 487          LEX_IS_OPENPAR, LEX_IS_CLOSEPAR, LEX_END } type;
                                                   >> 488   union {
                                                   >> 489     int  number;
                                                   >> 490     char operator;
                                                   >> 491     char var[STR_VAR_MAXLEN];
                                                   >> 492   };
                                                   >> 493 } data_lexer_to_parser;
                                                   >> 494 
                                                   >> 495 static void func_lexer(sos_ui32_t unused)
                                                   >> 496 {
                                                   >> 497   char c;
                                                   >> 498   enum { GOT_SPACE, GOT_NUM, GOT_OP, GOT_STR,
                                                   >> 499          GOT_OPENPAR, GOT_CLOSEPAR } got_what, got_what_before;
                                                   >> 500 
                                                   >> 501   data_lexer_to_parser.number = 0;
                                                   >> 502   got_what_before = GOT_SPACE;
                                                   >> 503   do
323     {                                             504     {
324       sos_fs_close(init_root);                 !! 505       /* Consume one character from the reader */
325       sos_process_unref(proc_init);            !! 506       sos_cpu_kstate_switch(& st_lexer, st_reader);
326       return -SOS_ENOENT;                      !! 507       c = data_reader_to_lexer;
                                                   >> 508 
                                                   >> 509       /* Classify the consumed character */
                                                   >> 510       if ( (c >= '0') && (c <= '9') )
                                                   >> 511         got_what = GOT_NUM;
                                                   >> 512       else if ( (c == '+') || (c == '-') || (c == '*') || (c == '/') )
                                                   >> 513         got_what = GOT_OP;
                                                   >> 514       else if ( ( (c >= 'a') && (c <= 'z') )
                                                   >> 515                 || ( (c >= 'A') && (c <= 'Z') ) )
                                                   >> 516         got_what = GOT_STR;
                                                   >> 517       else if (c == '(')
                                                   >> 518         got_what = GOT_OPENPAR;
                                                   >> 519       else if (c == ')')
                                                   >> 520         got_what = GOT_CLOSEPAR;
                                                   >> 521       else
                                                   >> 522         got_what = GOT_SPACE;
                                                   >> 523 
                                                   >> 524       /* Determine whether the current token is ended */
                                                   >> 525       if ( (got_what != got_what_before)
                                                   >> 526            || (got_what_before == GOT_OP)
                                                   >> 527            || (got_what_before == GOT_OPENPAR)
                                                   >> 528            || (got_what_before == GOT_CLOSEPAR) )
                                                   >> 529         {
                                                   >> 530           /* return control back to the parser if the previous token
                                                   >> 531              has been recognized */
                                                   >> 532           if ( (got_what_before != GOT_SPACE) )
                                                   >> 533             sos_cpu_kstate_switch(& st_lexer, st_parser);
                                                   >> 534 
                                                   >> 535           data_lexer_to_parser.number = 0;
                                                   >> 536         }
                                                   >> 537 
                                                   >> 538       /* Update the token being currently recognized */
                                                   >> 539       if (got_what == GOT_OP)
                                                   >> 540         {
                                                   >> 541           data_lexer_to_parser.type = LEX_IS_OPER;
                                                   >> 542           data_lexer_to_parser.operator = c;
                                                   >> 543         }
                                                   >> 544       else if (got_what == GOT_NUM)
                                                   >> 545         {
                                                   >> 546           data_lexer_to_parser.type = LEX_IS_NUMBER;
                                                   >> 547           data_lexer_to_parser.number *= 10;
                                                   >> 548           data_lexer_to_parser.number += (c - '0');
                                                   >> 549         }
                                                   >> 550       else if (got_what == GOT_STR)
                                                   >> 551         {
                                                   >> 552           char to_cat[] = { c, '\0' };
                                                   >> 553           data_lexer_to_parser.type = LEX_IS_VAR;
                                                   >> 554           strzcat(data_lexer_to_parser.var, to_cat, STR_VAR_MAXLEN);
                                                   >> 555         }
                                                   >> 556       else if (got_what == GOT_OPENPAR)
                                                   >> 557         data_lexer_to_parser.type = LEX_IS_OPENPAR;
                                                   >> 558       else if (got_what == GOT_CLOSEPAR)
                                                   >> 559         data_lexer_to_parser.type = LEX_IS_CLOSEPAR;
                                                   >> 560 
                                                   >> 561       got_what_before = got_what;
327     }                                             562     }
                                                   >> 563   while (c != '\0');
                                                   >> 564 
                                                   >> 565   /* Transfer last recognized token to the parser */
                                                   >> 566   if ( (got_what_before != GOT_SPACE) )
                                                   >> 567     sos_cpu_kstate_switch(& st_lexer, st_parser);
                                                   >> 568 
                                                   >> 569   /* Signal that no more token are available */
                                                   >> 570   data_lexer_to_parser.type = LEX_END;
                                                   >> 571   sos_cpu_kstate_switch(& st_lexer, st_parser);
                                                   >> 572 
                                                   >> 573   /* Exception: parser asks for a token AFTER having received the last
                                                   >> 574      one */
                                                   >> 575   sos_bochs_printf("Error: end of string already reached !\n");
                                                   >> 576   sos_cpu_kstate_switch(& st_lexer, st_main);
                                                   >> 577 }
328                                                   578 
329   /* Now update the process ! */               !! 579 
330   if ( ( SOS_OK != sos_process_chroot(proc_ini !! 580 /*
331        || ( SOS_OK != sos_process_chdir(proc_i !! 581  * The Parser coroutine and associated types/variables
                                                   >> 582  */
                                                   >> 583 struct syntax_node
                                                   >> 584 {
                                                   >> 585   enum { YY_IS_BINOP, YY_IS_UNAROP, YY_IS_NUM, YY_IS_VAR } type;
                                                   >> 586   union
                                                   >> 587   {
                                                   >> 588     int  number;
                                                   >> 589     char var[STR_VAR_MAXLEN];
                                                   >> 590     struct
332     {                                             591     {
333       sos_fs_close(init_root);                 !! 592       char op;
334       sos_fs_close(init_cwd);                  !! 593       struct syntax_node *parm_left, *parm_right;
335       sos_process_chroot(proc_init, NULL, & un !! 594     } binop;
336       sos_process_chdir(proc_init, NULL, & unu !! 595     struct
337       sos_process_unref(proc_init);            !! 596     {
338       return -SOS_ENOENT;                      !! 597       char op;
339     }                                          !! 598       struct syntax_node *parm;
                                                   >> 599     } unarop;
                                                   >> 600   };
                                                   >> 601 };
340                                                   602 
                                                   >> 603 static void func_parser(struct syntax_node ** syntax_tree)
                                                   >> 604 {
                                                   >> 605   static struct syntax_node *alloc_node_num(int val);
                                                   >> 606   static struct syntax_node *alloc_node_var(const char * name);
                                                   >> 607   static struct syntax_node *alloc_node_binop(char op,
                                                   >> 608                                               struct syntax_node *parm_left,
                                                   >> 609                                               struct syntax_node *parm_right);
                                                   >> 610   static struct syntax_node *alloc_node_unarop(char op,
                                                   >> 611                                                struct syntax_node *parm);
                                                   >> 612   static struct syntax_node * get_expr();
                                                   >> 613   static struct syntax_node * get_expr_lr(struct syntax_node *n);
                                                   >> 614   static struct syntax_node * get_term();
                                                   >> 615   static struct syntax_node * get_term_lr(struct syntax_node *n);
                                                   >> 616   static struct syntax_node * get_factor();
                                                   >> 617   static struct syntax_node * get_scalar();
341                                                   618 
                                                   >> 619   /* Create a new node to store a number */
                                                   >> 620   static struct syntax_node *alloc_node_num(int val)
                                                   >> 621     {
                                                   >> 622       struct syntax_node *n
                                                   >> 623         = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
                                                   >> 624       n->type   = YY_IS_NUM;
                                                   >> 625       n->number = val;
                                                   >> 626       return n;
                                                   >> 627     }
                                                   >> 628   /* Create a new node to store a variable */
                                                   >> 629   static struct syntax_node *alloc_node_var(const char * name)
                                                   >> 630     {
                                                   >> 631       struct syntax_node *n
                                                   >> 632         = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
                                                   >> 633       n->type   = YY_IS_VAR;
                                                   >> 634       strzcpy(n->var, name, STR_VAR_MAXLEN);
                                                   >> 635       return n;
                                                   >> 636     }
                                                   >> 637   /* Create a new node to store a binary operator */
                                                   >> 638   static struct syntax_node *alloc_node_binop(char op,
                                                   >> 639                                               struct syntax_node *parm_left,
                                                   >> 640                                               struct syntax_node *parm_right)
                                                   >> 641     {
                                                   >> 642       struct syntax_node *n
                                                   >> 643         = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
                                                   >> 644       n->type             = YY_IS_BINOP;
                                                   >> 645       n->binop.op         = op;
                                                   >> 646       n->binop.parm_left  = parm_left;
                                                   >> 647       n->binop.parm_right = parm_right;
                                                   >> 648       return n;
                                                   >> 649     }
                                                   >> 650   /* Create a new node to store a unary operator */
                                                   >> 651   static struct syntax_node *alloc_node_unarop(char op,
                                                   >> 652                                                struct syntax_node *parm)
                                                   >> 653     {
                                                   >> 654       struct syntax_node *n
                                                   >> 655         = (struct syntax_node*) sos_kmalloc(sizeof(struct syntax_node), 0);
                                                   >> 656       n->type        = YY_IS_UNAROP;
                                                   >> 657       n->unarop.op   = op;
                                                   >> 658       n->unarop.parm = parm;
                                                   >> 659       return n;
                                                   >> 660     }
                                                   >> 661 
                                                   >> 662   /* Raise an exception: transfer control back to main context,
                                                   >> 663      without unrolling the whole recursion */
                                                   >> 664   static void parser_exception(const char *str)
                                                   >> 665     {
                                                   >> 666       sos_bochs_printf("Parser exception: %s\n", str);
                                                   >> 667       sos_cpu_kstate_switch(& st_parser, st_main);
                                                   >> 668     }
342                                                   669 
343   /* Map the 'init' program in user space */   !! 670   /* Consume the current terminal "number" token and ask for a new
344   start_uaddr = sos_binfmt_elf32_map(as_init,  !! 671      token */
345   if (0 == start_uaddr)                        !! 672   static int get_number()
                                                   >> 673     {
                                                   >> 674       int v;
                                                   >> 675       if (data_lexer_to_parser.type != LEX_IS_NUMBER)
                                                   >> 676         parser_exception("Expected number");
                                                   >> 677       v = data_lexer_to_parser.number;
                                                   >> 678       sos_cpu_kstate_switch(& st_parser, st_lexer);
                                                   >> 679       return v;
                                                   >> 680     }
                                                   >> 681   /* Consume the current terminal "variable" token and ask for a new
                                                   >> 682      token */
                                                   >> 683   static void get_str(char name[STR_VAR_MAXLEN])
                                                   >> 684     {
                                                   >> 685       if (data_lexer_to_parser.type != LEX_IS_VAR)
                                                   >> 686         parser_exception("Expected variable");
                                                   >> 687       strzcpy(name, data_lexer_to_parser.var, STR_VAR_MAXLEN);
                                                   >> 688       sos_cpu_kstate_switch(& st_parser, st_lexer);
                                                   >> 689     }
                                                   >> 690   /* Consume the current terminal "operator" token and ask for a new
                                                   >> 691      token */
                                                   >> 692   static char get_op()
                                                   >> 693     {
                                                   >> 694       char op;
                                                   >> 695       if (data_lexer_to_parser.type != LEX_IS_OPER)
                                                   >> 696         parser_exception("Expected operator");
                                                   >> 697       op = data_lexer_to_parser.operator;
                                                   >> 698       sos_cpu_kstate_switch(& st_parser, st_lexer);
                                                   >> 699       return op;
                                                   >> 700     }
                                                   >> 701   /* Consume the current terminal "parenthese" token and ask for a new
                                                   >> 702      token */
                                                   >> 703   static void get_par()
346     {                                             704     {
347       sos_process_unref(proc_init);            !! 705       if ( (data_lexer_to_parser.type != LEX_IS_OPENPAR)
348       return -SOS_ENOENT;                      !! 706            && (data_lexer_to_parser.type != LEX_IS_CLOSEPAR) )
                                                   >> 707         parser_exception("Expected parenthese");
                                                   >> 708       sos_cpu_kstate_switch(& st_parser, st_lexer);
349     }                                             709     }
350                                                   710 
351   /* Allocate the user stack */                !! 711   /* Parse an Expression */
352   ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_ !! 712   static struct syntax_node * get_expr()
353   retval = sos_dev_zero_map(as_init, &ustack,  !! 713     {
354                             SOS_VM_MAP_PROT_RE !! 714       struct syntax_node *t = get_term();
355                             /* PRIVATE */ 0);  !! 715       return get_expr_lr(t);
356   if (SOS_OK != retval)                        !! 716     }
                                                   >> 717   /* Parse an Expr_lr */
                                                   >> 718   static struct syntax_node * get_expr_lr(struct syntax_node *n)
                                                   >> 719     {
                                                   >> 720       if ( (data_lexer_to_parser.type == LEX_IS_OPER)
                                                   >> 721            && ( (data_lexer_to_parser.operator == '+')
                                                   >> 722                 || (data_lexer_to_parser.operator == '-') ) )
                                                   >> 723         {
                                                   >> 724           char op = get_op();
                                                   >> 725           struct syntax_node *term = get_term();
                                                   >> 726           struct syntax_node *node_op = alloc_node_binop(op, n, term);
                                                   >> 727           return get_expr_lr(node_op);
                                                   >> 728         }
                                                   >> 729       return n;
                                                   >> 730     }
                                                   >> 731   /* Parse a Term */
                                                   >> 732   static struct syntax_node * get_term()
                                                   >> 733     {
                                                   >> 734       struct syntax_node *f1 = get_factor();
                                                   >> 735       return get_term_lr(f1);
                                                   >> 736     }
                                                   >> 737   /* Parse a Term_lr */
                                                   >> 738   static struct syntax_node * get_term_lr(struct syntax_node *n)
                                                   >> 739     {
                                                   >> 740       if ( (data_lexer_to_parser.type == LEX_IS_OPER)
                                                   >> 741            && ( (data_lexer_to_parser.operator == '*')
                                                   >> 742                 || (data_lexer_to_parser.operator == '/') ) )
                                                   >> 743         {
                                                   >> 744           char op = get_op();
                                                   >> 745           struct syntax_node *factor = get_factor();
                                                   >> 746           struct syntax_node *node_op = alloc_node_binop(op, n, factor);
                                                   >> 747           return get_term_lr(node_op);
                                                   >> 748         }
                                                   >> 749       return n;
                                                   >> 750     }
                                                   >> 751   /* Parse a Factor */
                                                   >> 752   static struct syntax_node * get_factor()
                                                   >> 753     {
                                                   >> 754       if ( (data_lexer_to_parser.type == LEX_IS_OPER)
                                                   >> 755            && ( (data_lexer_to_parser.operator == '-')
                                                   >> 756                 || (data_lexer_to_parser.operator == '+') ) )
                                                   >> 757         { char op = data_lexer_to_parser.operator;
                                                   >> 758         get_op(); return alloc_node_unarop(op, get_factor()); }
                                                   >> 759       else if (data_lexer_to_parser.type == LEX_IS_OPENPAR)
                                                   >> 760         {
                                                   >> 761           struct syntax_node *expr;
                                                   >> 762           get_par();
                                                   >> 763           expr = get_expr();
                                                   >> 764           if (data_lexer_to_parser.type != LEX_IS_CLOSEPAR)
                                                   >> 765             parser_exception("Mismatched parentheses");
                                                   >> 766           get_par();
                                                   >> 767           return expr;
                                                   >> 768         }
                                                   >> 769   
                                                   >> 770       return get_scalar();
                                                   >> 771     }
                                                   >> 772   /* Parse a Scalar */
                                                   >> 773   static struct syntax_node * get_scalar()
357     {                                             774     {
358       sos_process_unref(proc_init);            !! 775       if (data_lexer_to_parser.type != LEX_IS_NUMBER)
359       return -SOS_ENOMEM;                      !! 776         {
                                                   >> 777           char var[STR_VAR_MAXLEN];
                                                   >> 778           get_str(var);
                                                   >> 779           return alloc_node_var(var);
                                                   >> 780         }
                                                   >> 781       return alloc_node_num(get_number());
360     }                                             782     }
361                                                   783 
362   /* Now create the user thread */             !! 784 
363   new_thr = sos_create_user_thread(NULL,       !! 785   /*
364                                    proc_init,  !! 786    * Body of the function
365                                    start_uaddr !! 787    */
366                                    0, 0,       !! 788 
367                                    ustack + SO !! 789   /* Get the first token */
368                                    SOS_SCHED_P !! 790   sos_cpu_kstate_switch(& st_parser, st_lexer);
369   if (! new_thr)                               !! 791 
                                                   >> 792   /* Begin the parsing ! */
                                                   >> 793   *syntax_tree = get_expr();
                                                   >> 794   /* The result is returned in the syntax_tree parameter */
                                                   >> 795 }
                                                   >> 796 
                                                   >> 797 
                                                   >> 798 /*
                                                   >> 799  * Setup the parser's pipeline
                                                   >> 800  */
                                                   >> 801 static struct syntax_node * parse_expression(const char *expr)
                                                   >> 802 {
                                                   >> 803   struct syntax_node *retval = NULL;
                                                   >> 804 
                                                   >> 805   /* Build the context of the functions in the pipeline */
                                                   >> 806   sos_cpu_kstate_init(& st_reader,
                                                   >> 807                       (sos_cpu_kstate_function_arg1_t*)func_reader,
                                                   >> 808                       (sos_ui32_t)expr,
                                                   >> 809                       (sos_vaddr_t)stack_reader, sizeof(stack_reader),
                                                   >> 810                       (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
                                                   >> 811   sos_cpu_kstate_init(& st_lexer,
                                                   >> 812                       (sos_cpu_kstate_function_arg1_t*)func_lexer,
                                                   >> 813                       0,
                                                   >> 814                       (sos_vaddr_t)stack_lexer, sizeof(stack_lexer),
                                                   >> 815                       (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
                                                   >> 816   sos_cpu_kstate_init(& st_parser,
                                                   >> 817                       (sos_cpu_kstate_function_arg1_t*)func_parser,
                                                   >> 818                       (sos_ui32_t) /* syntax tree ! */&retval,
                                                   >> 819                       (sos_vaddr_t)deep_stack, sizeof(deep_stack),
                                                   >> 820                       (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
                                                   >> 821 
                                                   >> 822   /* Parse the expression */
                                                   >> 823   sos_cpu_kstate_switch(& st_main, st_parser);
                                                   >> 824   return retval;
                                                   >> 825 }
                                                   >> 826 
                                                   >> 827 
                                                   >> 828 /*
                                                   >> 829  * The Evaluator coroutine and associated types/variables
                                                   >> 830  */
                                                   >> 831 struct func_eval_params
                                                   >> 832 {
                                                   >> 833   const struct syntax_node *e;
                                                   >> 834   const char **var_name;
                                                   >> 835   int *var_val;
                                                   >> 836   int nb_vars;
                                                   >> 837 
                                                   >> 838   int result;
                                                   >> 839 };
                                                   >> 840 
                                                   >> 841 static void func_eval(struct func_eval_params *parms)
                                                   >> 842 {
                                                   >> 843   /* The internal (recursive) nested function to evaluate each node of
                                                   >> 844      the syntax tree */
                                                   >> 845   static int rec_eval(const struct syntax_node *n,
                                                   >> 846                       const char* var_name[], int var_val[], int nb_vars)
370     {                                             847     {
371       sos_process_unref(proc_init);            !! 848       switch (n->type)
372       return -SOS_ENOMEM;                      !! 849         {
                                                   >> 850         case YY_IS_NUM:
                                                   >> 851           return n->number;
                                                   >> 852 
                                                   >> 853         case YY_IS_VAR:
                                                   >> 854           {
                                                   >> 855             int i;
                                                   >> 856             for (i = 0 ; i < nb_vars ; i++)
                                                   >> 857               if (0 == strcmp(var_name[i], n->var))
                                                   >> 858                 return var_val[i];
                                                   >> 859 
                                                   >> 860             /* Exception: no variable with that name ! */
                                                   >> 861             sos_bochs_printf("ERROR: unknown variable %s\n", n->var);
                                                   >> 862             sos_cpu_kstate_switch(& st_eval, st_main);
                                                   >> 863           }
                                                   >> 864 
                                                   >> 865         case YY_IS_BINOP:
                                                   >> 866           {
                                                   >> 867             int left = rec_eval(n->binop.parm_left,
                                                   >> 868                                 var_name, var_val, nb_vars);
                                                   >> 869             int right = rec_eval(n->binop.parm_right,
                                                   >> 870                                  var_name, var_val, nb_vars);
                                                   >> 871             switch (n->binop.op)
                                                   >> 872               {
                                                   >> 873               case '+': return left + right;
                                                   >> 874               case '-': return left - right;
                                                   >> 875               case '*': return left * right;
                                                   >> 876               case '/': return left / right;
                                                   >> 877               default:
                                                   >> 878                 /* Exception: no such operator (INTERNAL error) ! */
                                                   >> 879                 sos_bochs_printf("ERROR: unknown binop %c\n", n->binop.op);
                                                   >> 880                 sos_cpu_kstate_switch(& st_eval, st_main);
                                                   >> 881               }
                                                   >> 882           }
                                                   >> 883 
                                                   >> 884         case YY_IS_UNAROP:
                                                   >> 885           {
                                                   >> 886             int arg = rec_eval(n->unarop.parm, var_name, var_val, nb_vars);
                                                   >> 887             switch (n->unarop.op)
                                                   >> 888               {
                                                   >> 889               case '-': return -arg;
                                                   >> 890               case '+': return arg;
                                                   >> 891               default:
                                                   >> 892                 /* Exception: no such operator (INTERNAL error) ! */
                                                   >> 893                 sos_bochs_printf("ERROR: unknown unarop %c\n", n->unarop.op);
                                                   >> 894                 sos_cpu_kstate_switch(& st_eval, st_main);
                                                   >> 895               }
                                                   >> 896           }
                                                   >> 897         }
                                                   >> 898       
                                                   >> 899       /* Exception: no such syntax node (INTERNAL error) ! */
                                                   >> 900       sos_bochs_printf("ERROR: invalid node type\n");
                                                   >> 901       sos_cpu_kstate_switch(& st_eval, st_main);
                                                   >> 902       return -1; /* let's make gcc happy */
373     }                                             903     }
374                                                   904 
375   sos_process_unref(proc_init);                !! 905 
376   return SOS_OK;                               !! 906   /*
                                                   >> 907    * Function BODY
                                                   >> 908    */
                                                   >> 909   /* Update p.result returned back to calling function */
                                                   >> 910   parms->result
                                                   >> 911     = rec_eval(parms->e, parms->var_name, parms->var_val, parms->nb_vars);
                                                   >> 912 }
                                                   >> 913 
                                                   >> 914 /*
                                                   >> 915  * Change the stack for something larger in order to call the
                                                   >> 916  * recursive function above in a safe way
                                                   >> 917  */
                                                   >> 918 static int eval_expression(const struct syntax_node *e,
                                                   >> 919                            const char* var_name[], int var_val[], int nb_vars)
                                                   >> 920 {
                                                   >> 921   struct func_eval_params p
                                                   >> 922     = (struct func_eval_params){ .e=e,
                                                   >> 923                                  .var_name=var_name,
                                                   >> 924                                  .var_val=var_val,
                                                   >> 925                                  .nb_vars=nb_vars,
                                                   >> 926                                  .result = 0 };
                                                   >> 927 
                                                   >> 928   sos_cpu_kstate_init(& st_eval,
                                                   >> 929                       (sos_cpu_kstate_function_arg1_t*)func_eval,
                                                   >> 930                       (sos_ui32_t)/* p.result is modified upon success */&p,
                                                   >> 931                       (sos_vaddr_t)deep_stack, sizeof(deep_stack),
                                                   >> 932                       (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
                                                   >> 933 
                                                   >> 934   /* Go ! */
                                                   >> 935   sos_cpu_kstate_switch(& st_main, st_eval);
                                                   >> 936   return p.result;
377 }                                                 937 }
378                                                   938 
379                                                   939 
                                                   >> 940 /*
                                                   >> 941  * Function to free the syntax tree
                                                   >> 942  */
                                                   >> 943 static void func_free(struct syntax_node *n)
                                                   >> 944 {
                                                   >> 945   switch (n->type)
                                                   >> 946     {
                                                   >> 947     case YY_IS_NUM:
                                                   >> 948     case YY_IS_VAR:
                                                   >> 949       break;
                                                   >> 950       
                                                   >> 951     case YY_IS_BINOP:
                                                   >> 952       func_free(n->binop.parm_left);
                                                   >> 953       func_free(n->binop.parm_right);
                                                   >> 954       break;
                                                   >> 955       
                                                   >> 956     case YY_IS_UNAROP:
                                                   >> 957       func_free(n->unarop.parm);
                                                   >> 958       break;
                                                   >> 959     }
                                                   >> 960   
                                                   >> 961   sos_kfree((sos_vaddr_t)n);
                                                   >> 962 }
                                                   >> 963 
                                                   >> 964 /*
                                                   >> 965  * Change the stack for something larger in order to call the
                                                   >> 966  * recursive function above in a safe way
                                                   >> 967  */
                                                   >> 968 static void free_syntax_tree(struct syntax_node *tree)
                                                   >> 969 {
                                                   >> 970   sos_cpu_kstate_init(& st_free,
                                                   >> 971                       (sos_cpu_kstate_function_arg1_t*)func_free,
                                                   >> 972                       (sos_ui32_t)tree,
                                                   >> 973                       (sos_vaddr_t)deep_stack, sizeof(deep_stack),
                                                   >> 974                       (sos_cpu_kstate_function_arg1_t*)func_exit, 0);
                                                   >> 975 
                                                   >> 976   /* Go ! */
                                                   >> 977   sos_cpu_kstate_switch(& st_main, st_free);
                                                   >> 978 }
                                                   >> 979 
380                                                   980 
381 /* ===========================================    981 /* ======================================================================
382  * The C entry point of our operating system      982  * The C entry point of our operating system
383  */                                               983  */
384 void sos_main(unsigned long magic, unsigned lo !! 984 void sos_main(unsigned long magic, unsigned long addr)
385      __attribute__((noreturn));                << 
386 void sos_main(unsigned long magic, unsigned lo << 
387 {                                                 985 {
                                                   >> 986   unsigned i;
388   sos_paddr_t sos_kernel_core_base_paddr, sos_    987   sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
389   struct sos_time tick_resolution;             !! 988   struct syntax_node *syntax_tree;
390   struct sos_fs_manager_instance * rootfs;     << 
391                                                   989 
392   /* Size of RAM above 1MB. Might be undefined !! 990   /* Grub sends us a structure, called multiboot_info_t with a lot of
393   unsigned long int upper_mem = 0;             !! 991      precious informations about the system, see the multiboot
                                                   >> 992      documentation for more information. */
                                                   >> 993   multiboot_info_t *mbi;
                                                   >> 994   mbi = (multiboot_info_t *) addr;
394                                                   995 
395   /* Setup bochs and console, and clear the co    996   /* Setup bochs and console, and clear the console */
396   sos_bochs_subsystem_setup();                 !! 997   sos_bochs_setup();
397                                                   998 
398   sos_x86_videomem_setup();                       999   sos_x86_videomem_setup();
399   sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);    1000   sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
400                                                   1001 
401   /* Greetings from SOS */                        1002   /* Greetings from SOS */
402   if (magic == MULTIBOOT_BOOTLOADER_MAGIC)        1003   if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
403     {                                          !! 1004     /* Loaded with Grub */
404       /* Grub sends us a structure, called mul !! 1005     sos_x86_videomem_printf(1, 0,
405          precious informations about the syste !! 1006                             SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
406          documentation for more information. * !! 1007                             "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
407       multiboot_info_t *mbi = (multiboot_info_ !! 1008                             "SOS", ',',
408                                                !! 1009                             (unsigned)(mbi->mem_upper >> 10) + 1,
409       /* Multiboot says: "The value returned f !! 1010                             (unsigned)mbi->mem_upper);
410          maximally the address of the first up << 
411          megabyte.". It also adds: "It is not  << 
412          value." aka "YMMV" ;) */              << 
413       upper_mem = mbi->mem_upper;              << 
414       sos_x86_videomem_printf(1, 0,            << 
415                               SOS_X86_VIDEO_FG << 
416                               "Welcome From GR << 
417                               "SOS article 9.5 << 
418                               (unsigned)(upper << 
419                               (unsigned)upper_ << 
420     }                                          << 
421   else if (magic == 0x42244224)                << 
422     {                                          << 
423       /* Loaded with SOS bootsect */           << 
424       upper_mem = arg;                         << 
425       sos_x86_videomem_printf(1, 0,            << 
426                               SOS_X86_VIDEO_FG << 
427                               "Welcome to %s%c << 
428                               "SOS article 9.5 << 
429                               (unsigned)(upper << 
430                               (unsigned)upper_ << 
431     }                                          << 
432   else                                            1011   else
433     /* Not loaded with grub, not from an enhan !! 1012     /* Not loaded with grub */
434     sos_x86_videomem_printf(1, 0,                 1013     sos_x86_videomem_printf(1, 0,
435                             SOS_X86_VIDEO_FG_Y    1014                             SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
436                             "Welcome to SOS ar !! 1015                             "Welcome to SOS");
437                                                   1016 
438   sos_bochs_putstring("Message in a bochs: Thi !! 1017   sos_bochs_putstring("Message in a bochs\n");
439                                                   1018 
440   /* Setup CPU segmentation and IRQ subsystem     1019   /* Setup CPU segmentation and IRQ subsystem */
441   sos_gdt_subsystem_setup();                      1020   sos_gdt_subsystem_setup();
442   sos_idt_subsystem_setup();                      1021   sos_idt_subsystem_setup();
443                                                   1022 
444   /* Setup SOS IRQs and exceptions subsystem *    1023   /* Setup SOS IRQs and exceptions subsystem */
445   sos_exception_subsystem_setup();                1024   sos_exception_subsystem_setup();
446   sos_irq_subsystem_setup();                      1025   sos_irq_subsystem_setup();
447                                                   1026 
448   /* Configure the timer so as to raise the IR    1027   /* Configure the timer so as to raise the IRQ0 at a 100Hz rate */
449   sos_i8254_set_frequency(100);                   1028   sos_i8254_set_frequency(100);
450                                                   1029 
451   /* Setup the kernel time subsystem to get pr !! 1030   /* We need a multiboot-compliant boot loader to get the size of the RAM */
452      ticks into account */                     !! 1031   if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
453   tick_resolution = (struct sos_time) { .sec=0 << 
454   sos_time_subsysem_setup(& tick_resolution);  << 
455                                                << 
456   /* We need to know the RAM size */           << 
457   if (upper_mem == 0)                          << 
458     {                                             1032     {
459       sos_x86_videomem_putstring(20, 0,           1033       sos_x86_videomem_putstring(20, 0,
460                                  SOS_X86_VIDEO    1034                                  SOS_X86_VIDEO_FG_LTRED
461                                    | SOS_X86_V    1035                                    | SOS_X86_VIDEO_BG_BLUE
462                                    | SOS_X86_V    1036                                    | SOS_X86_VIDEO_FG_BLINKING,
463                                  "I don't know !! 1037                                  "I'm not loaded with Grub !");
464       /* STOP ! */                                1038       /* STOP ! */
465       for (;;)                                    1039       for (;;)
466         continue;                                 1040         continue;
467     }                                             1041     }
468                                                   1042 
469   /*                                              1043   /*
470    * Some interrupt handlers                      1044    * Some interrupt handlers
471    */                                             1045    */
472                                                   1046 
473   /* Binding some HW interrupts and exceptions    1047   /* Binding some HW interrupts and exceptions to software routines */
474   sos_irq_set_routine(SOS_IRQ_TIMER,              1048   sos_irq_set_routine(SOS_IRQ_TIMER,
475                       clk_it);                    1049                       clk_it);
476                                                   1050 
477   /*                                              1051   /*
478    * Setup physical memory management             1052    * Setup physical memory management
479    */                                             1053    */
480                                                   1054 
481   SOS_ASSERT_FATAL(SOS_OK                      !! 1055   /* Multiboot says: "The value returned for upper memory is maximally
482                    == sos_physmem_subsystem_se !! 1056      the address of the first upper memory hole minus 1 megabyte.". It
483                                                !! 1057      also adds: "It is not guaranteed to be this value." aka "YMMV" ;) */
484                                                !! 1058   sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20),
                                                   >> 1059                               & sos_kernel_core_base_paddr,
                                                   >> 1060                               & sos_kernel_core_top_paddr);
485                                                   1061   
486   /*                                              1062   /*
487    * Switch to paged-memory mode                  1063    * Switch to paged-memory mode
488    */                                             1064    */
489                                                   1065 
490   /* Disabling interrupts should seem more cor    1066   /* Disabling interrupts should seem more correct, but it's not really
491      necessary at this stage */                   1067      necessary at this stage */
492   SOS_ASSERT_FATAL(SOS_OK ==                      1068   SOS_ASSERT_FATAL(SOS_OK ==
493                    sos_paging_subsystem_setup(    1069                    sos_paging_subsystem_setup(sos_kernel_core_base_paddr,
494                                                   1070                                               sos_kernel_core_top_paddr));
495                                                   1071   
496   /* Bind the page fault exception */             1072   /* Bind the page fault exception */
497   sos_exception_set_routine(SOS_EXCEPT_PAGE_FA    1073   sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT,
498                             pgflt_ex);            1074                             pgflt_ex);
499                                                   1075 
500   /*                                              1076   /*
501    * Setup kernel virtual memory allocator        1077    * Setup kernel virtual memory allocator
502    */                                          !! 1078    */ 
503                                                   1079 
504   if (sos_kmem_vmm_subsystem_setup(sos_kernel_    1080   if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr,
505                                    sos_kernel_    1081                                    sos_kernel_core_top_paddr,
506                                    bootstrap_s    1082                                    bootstrap_stack_bottom,
507                                    bootstrap_s    1083                                    bootstrap_stack_bottom
508                                    + bootstrap    1084                                    + bootstrap_stack_size))
509     sos_bochs_printf("Could not setup the Kern    1085     sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
510                                                   1086 
511   if (sos_kmalloc_subsystem_setup())              1087   if (sos_kmalloc_subsystem_setup())
512     sos_bochs_printf("Could not setup the Kmal    1088     sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
513                                                   1089 
514   /*                                              1090   /*
515    * Initialize the MMU context subsystem      !! 1091    * Enabling the HW interrupts here, this will make the timer HW
                                                   >> 1092    * interrupt call our clk_it handler
516    */                                             1093    */
517   sos_mm_context_subsystem_setup();            !! 1094   asm volatile ("sti\n");
518                                                   1095 
519   /*                                              1096   /*
520    * Initialize the CPU context subsystem      !! 1097    * Print hello world using coroutines
521    */                                             1098    */
522   sos_cpu_context_subsystem_setup();           !! 1099   print_hello_world();
                                                   >> 1100 
523                                                   1101 
524   /*                                              1102   /*
525    * Bind the syscall handler to its software  !! 1103    * Run coroutine tests
526    */                                             1104    */
527   sos_swintr_subsystem_setup();                !! 1105   sos_x86_videomem_printf(4, 0,
                                                   >> 1106                           SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
                                                   >> 1107                           "Coroutine test");
                                                   >> 1108   sos_x86_videomem_printf(5, 0,
                                                   >> 1109                           SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
                                                   >> 1110                           "Parsing...");
                                                   >> 1111   syntax_tree = parse_expression(" -  ( (69/ toto)+ ( (( - +-- 1))) + --toto*((toto+ - - y - +2*(y-toto))*y) +2*(y-toto) )/- (( y - toto)*2)");
528                                                   1112 
                                                   >> 1113   if (syntax_tree != NULL)
                                                   >> 1114     {
                                                   >> 1115       sos_x86_videomem_printf(6, 0,
                                                   >> 1116                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
                                                   >> 1117                               "Evaluating...");
                                                   >> 1118       sos_x86_videomem_printf(7, 0,
                                                   >> 1119                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
                                                   >> 1120                               "Result=%d (if 0: check bochs output)",
                                                   >> 1121                               eval_expression(syntax_tree,
                                                   >> 1122                                               (const char*[]){"toto", "y"},
                                                   >> 1123                                               (int[]){3, 4},
                                                   >> 1124                                               2));
                                                   >> 1125       free_syntax_tree(syntax_tree);
                                                   >> 1126       sos_x86_videomem_printf(8, 0,
                                                   >> 1127                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
                                                   >> 1128                               "Done (un-allocated syntax tree)");
                                                   >> 1129     }
                                                   >> 1130   else
                                                   >> 1131     {
                                                   >> 1132       sos_x86_videomem_printf(6, 0,
                                                   >> 1133                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_YELLOW,
                                                   >> 1134                               "Error in parsing (see bochs output)");
                                                   >> 1135     }
529                                                   1136 
530   /*                                              1137   /*
531    * Initialize the Kernel thread and schedule !! 1138    * Run some demand-paging tests
532    */                                             1139    */
533                                                !! 1140   test_demand_paging(234567, 500);
534   /* Initialize kernel thread subsystem */     << 
535   sos_thread_subsystem_setup(bootstrap_stack_b << 
536                              bootstrap_stack_s << 
537                                                << 
538   /* Initialize the scheduler */               << 
539   sos_sched_subsystem_setup();                 << 
540                                                << 
541   /* Declare the IDLE thread */                << 
542   SOS_ASSERT_FATAL(sos_create_kernel_thread("i << 
543                                             SO << 
544                                                << 
545   /* Prepare the stats subsystem */            << 
546   sos_load_subsystem_setup();                  << 
547                                                << 
548   /* Declare a thread that prints some stats * << 
549   SOS_ASSERT_FATAL(sos_create_kernel_thread("s << 
550                                             NU << 
551                                             SO << 
552                                                   1141 
553                                                   1142 
554   /*                                              1143   /*
555    * Initialise user address space management  !! 1144    * Create an un-resolved page fault, which will make the page fault
                                                   >> 1145    * handler print the backtrace.
556    */                                             1146    */
557   sos_umem_vmm_subsystem_setup();              !! 1147   test_backtrace(6, 0xdeadbeef, bootstrap_stack_bottom, bootstrap_stack_size);
558   sos_dev_zero_subsystem_setup();              << 
559                                                << 
560   /* Initialize the page and block cache subsy << 
561   sos_fs_pagecache_subsystem_setup();          << 
562   sos_blockdev_subsystem_setup();              << 
563   sos_dev_mem_chardev_setup();                 << 
564                                                   1148 
565   /*                                              1149   /*
566    * Initialize process stuff                  !! 1150    * System should be halted BEFORE here !
567    */                                             1151    */
568   sos_process_subsystem_setup();               << 
569                                                << 
570                                                << 
571   /* Enabling the HW interrupts here, this wil << 
572      interrupt call the scheduler */           << 
573   asm volatile ("sti\n");                      << 
574                                                << 
575                                                << 
576   SOS_ASSERT_FATAL(SOS_OK == sos_fs_virtfs_sub << 
577   SOS_ASSERT_FATAL(SOS_OK == sos_fs_subsystem_ << 
578                                                << 
579                                                << 
580                                                << 
581                                                << 
582                                                << 
583   tty_subsystem_setup();                       << 
584   sos_ttyS0_subsystem_setup();                 << 
585   sos_console_subsystem_setup();               << 
586                                                << 
587                                                << 
588   sos_ide_subsystem_setup();                   << 
589                                                   1152 
590                                                   1153 
                                                   >> 1154   /* An operatig system never ends */
                                                   >> 1155   for (;;)
                                                   >> 1156     {
                                                   >> 1157       /* Remove this instruction if you get an "Invalid opcode" CPU
                                                   >> 1158          exception (old 80386 CPU) */
                                                   >> 1159       asm("hlt\n");
591                                                   1160 
592   /* Start the 'init' process, which in turns  !! 1161       continue;
593      programs */                               !! 1162     }
594   start_init(rootfs);                          << 
595   /*                                           << 
596    * We can safely exit from this function now << 
597    * an idle Kernel thread ready to make the C << 
598    *                                           << 
599    * However, we must EXPLICITELY call sos_thr << 
600    * simple "return" will return nowhere ! Act << 
601    * was initialized by the Grub bootstrap sta << 
602    * word "thread" did not exist. This means t << 
603    * setup in order for a return here to call  << 
604    * automagically. Hence we must call it manu << 
605    * kernel thread where we must do this manua << 
606    */                                          << 
607   sos_bochs_printf("Bye from primary thread !\ << 
608   sos_thread_exit();                           << 
609   SOS_FATAL_ERROR("No trespassing !");         << 
610 }                                                 1163 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]