📄 main.c
字号:
/* Lend the CPU to some other thread */ sos_thread_yield(); }}/* ====================================================================== * Kernel thread showing some CPU usage statistics on the console every 1s */static void stat_thread(){ while (1) { sos_ui32_t flags; sos_ui32_t load1, load5, load15; char str1[11], str5[11], str15[11]; struct sos_time t; t.sec = 1; t.nanosec = 0; sos_thread_sleep(& t); sos_disable_IRQs(flags); /* The IDLE task is EXcluded in the following computation */ sos_load_get_sload(&load1, &load5, &load15); sos_load_to_string(str1, load1); sos_load_to_string(str5, load5); sos_load_to_string(str15, load15); sos_x86_videomem_printf(16, 34, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Kernel (- Idle): %s %s %s ", str1, str5, str15); sos_load_get_uload(&load1, &load5, &load15); sos_load_to_string(str1, load1); sos_load_to_string(str5, load5); sos_load_to_string(str15, load15); sos_x86_videomem_printf(17, 34, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "User: %s %s %s ", str1, str5, str15); sos_load_get_uratio(&load1, &load5, &load15); sos_load_to_string(str1, load1); sos_load_to_string(str5, load5); sos_load_to_string(str15, load15); sos_x86_videomem_printf(18, 34, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "User CPU %%: %s %s %s ", str1, str5, str15); /* The IDLE task is INcluded in the following computation */ sos_load_get_sratio(&load1, &load5, &load15); sos_load_to_string(str1, load1); sos_load_to_string(str5, load5); sos_load_to_string(str15, load15); sos_x86_videomem_printf(19, 34, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Kernel CPU %% (+ Idle): %s %s %s ", str1, str5, str15); sos_restore_IRQs(flags); }}/* ====================================================================== * The C entry point of our operating system */void sos_main(unsigned long magic, unsigned long addr){ unsigned i; sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr; struct sos_time tick_resolution; /* Grub sends us a structure, called multiboot_info_t with a lot of precious informations about the system, see the multiboot documentation for more information. */ multiboot_info_t *mbi; mbi = (multiboot_info_t *) addr; /* Setup bochs and console, and clear the console */ sos_bochs_setup(); sos_x86_videomem_setup(); sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); /* Greetings from SOS */ if (magic == MULTIBOOT_BOOTLOADER_MAGIC) /* Loaded with Grub */ sos_x86_videomem_printf(1, 0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)", "SOS article 7", ',', (unsigned)(mbi->mem_upper >> 10) + 1, (unsigned)mbi->mem_upper); else /* Not loaded with grub */ sos_x86_videomem_printf(1, 0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Welcome to SOS article 7"); sos_bochs_putstring("Message in a bochs: This is SOS article 7.\n"); /* Setup CPU segmentation and IRQ subsystem */ sos_gdt_subsystem_setup(); sos_idt_subsystem_setup(); /* Setup SOS IRQs and exceptions subsystem */ sos_exception_subsystem_setup(); sos_irq_subsystem_setup(); /* Configure the timer so as to raise the IRQ0 at a 100Hz rate */ sos_i8254_set_frequency(100); /* Setup the kernel time subsystem to get prepared to take the timer ticks into account */ tick_resolution = (struct sos_time) { .sec=0, .nanosec=10000000UL }; sos_time_subsysem_setup(& tick_resolution); /* We need a multiboot-compliant boot loader to get the size of the RAM */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { sos_x86_videomem_putstring(20, 0, SOS_X86_VIDEO_FG_LTRED | SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_BLINKING, "I'm not loaded with Grub !"); /* STOP ! */ for (;;) continue; } /* * Some interrupt handlers */ /* Binding some HW interrupts and exceptions to software routines */ sos_irq_set_routine(SOS_IRQ_TIMER, clk_it); /* * Setup physical memory management */ /* Multiboot says: "The value returned for upper memory is maximally the address of the first upper memory hole minus 1 megabyte.". It also adds: "It is not guaranteed to be this value." aka "YMMV" ;) */ sos_physmem_subsystem_setup((mbi->mem_upper<<10) + (1<<20), & sos_kernel_core_base_paddr, & sos_kernel_core_top_paddr); /* * Switch to paged-memory mode */ /* Disabling interrupts should seem more correct, but it's not really necessary at this stage */ SOS_ASSERT_FATAL(SOS_OK == sos_paging_subsystem_setup(sos_kernel_core_base_paddr, sos_kernel_core_top_paddr)); /* Bind the page fault exception */ sos_exception_set_routine(SOS_EXCEPT_PAGE_FAULT, pgflt_ex); /* * Setup kernel virtual memory allocator */ if (sos_kmem_vmm_subsystem_setup(sos_kernel_core_base_paddr, sos_kernel_core_top_paddr, bootstrap_stack_bottom, bootstrap_stack_bottom + bootstrap_stack_size)) sos_bochs_printf("Could not setup the Kernel virtual space allocator\n"); if (sos_kmalloc_subsystem_setup()) sos_bochs_printf("Could not setup the Kmalloc subsystem\n"); /* * Initialize the MMU context subsystem */ sos_mm_context_subsystem_setup(); /* * Initialize the CPU context subsystem */ sos_cpu_context_subsystem_setup(); /* * Bind the syscall handler to its software interrupt handler */ sos_swintr_subsystem_setup(); /* * Initialize the Kernel thread and scheduler subsystems */ /* Initialize kernel thread subsystem */ sos_thread_subsystem_setup(bootstrap_stack_bottom, bootstrap_stack_size); /* Initialize the scheduler */ sos_sched_subsystem_setup(); /* Declare the IDLE thread */ SOS_ASSERT_FATAL(sos_create_kernel_thread("idle", idle_thread, NULL, SOS_SCHED_PRIO_TS_LOWEST) != NULL); /* Prepare the stats subsystem */ sos_load_subsystem_setup(); /* Declare a thread that prints some stats */ SOS_ASSERT_FATAL(sos_create_kernel_thread("stat_thread", stat_thread, NULL, SOS_SCHED_PRIO_TS_LOWEST) != NULL); /* * Initialize process stuff */ sos_process_subsystem_setup(); /* Enabling the HW interrupts here, this will make the timer HW interrupt call the scheduler */ asm volatile ("sti\n"); /* Run some tests involving USER processes and threads */ extern void test_art7(); test_art7(); /* Now run some Kernel threads just for fun ! */ extern void MouseSim(); MouseSim(); test_thread(); /* * We can safely exit from this function now, for there is already * an idle Kernel thread ready to make the CPU busy working... * * However, we must EXPLICITELY call sos_thread_exit() because a * simple "return" will return nowhere ! Actually this first thread * was initialized by the Grub bootstrap stage, at a time when the * word "thread" did not exist. This means that the stack was not * setup in order for a return here to call sos_thread_exit() * automagically. Hence we must call it manually. This is the ONLY * kernel thread where we must do this manually. */ sos_bochs_printf("Bye from primary thread !\n"); sos_thread_exit(); SOS_FATAL_ERROR("No trespassing !");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -