⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 C
📖 第 1 页 / 共 2 页
字号:
  /*   * Setup the root and CWD directories of the process. The root of   * this process will correspond to the "global" root of the whole   * system since all the future processes will duplicate it !   */  retval = sos_fs_new_opened_file(proc_init, rootfs->root,				  SOS_FS_OPEN_READ | SOS_FS_OPEN_WRITE,				  & init_root);  if (SOS_OK != retval)    {      sos_process_unref(proc_init);      return -SOS_ENOENT;    }  /* Duplicate the root file to set the current working directory of     the init process */  retval = sos_fs_duplicate_opened_file(init_root, proc_init,					& init_cwd);  if (SOS_OK != retval)    {      sos_fs_close(init_root);      sos_process_unref(proc_init);      return -SOS_ENOENT;    }  /* Now update the process ! */  if ( ( SOS_OK != sos_process_chroot(proc_init, init_root, & unused_of) )       || ( SOS_OK != sos_process_chdir(proc_init, init_cwd, & unused_of) ) )    {      sos_fs_close(init_root);      sos_fs_close(init_cwd);      sos_process_chroot(proc_init, NULL, & unused_of);      sos_process_chdir(proc_init, NULL, & unused_of);      sos_process_unref(proc_init);      return -SOS_ENOENT;    }  /* Map the 'init' program in user space */  start_uaddr = sos_binfmt_elf32_map(as_init, "init");  if (0 == start_uaddr)    {      sos_process_unref(proc_init);      return -SOS_ENOENT;    }  /* Allocate the user stack */  ustack = (SOS_PAGING_TOP_USER_ADDRESS - SOS_DEFAULT_USER_STACK_SIZE) + 1;  retval = sos_dev_zero_map(as_init, &ustack, SOS_DEFAULT_USER_STACK_SIZE,			    SOS_VM_MAP_PROT_READ | SOS_VM_MAP_PROT_WRITE,			    /* PRIVATE */ 0);  if (SOS_OK != retval)    {      sos_process_unref(proc_init);      return -SOS_ENOMEM;    }  /* Now create the user thread */  new_thr = sos_create_user_thread(NULL,				   proc_init,				   start_uaddr,				   0, 0,				   ustack + SOS_DEFAULT_USER_STACK_SIZE - 4,				   SOS_SCHED_PRIO_TS_LOWEST);  if (! new_thr)    {      sos_process_unref(proc_init);      return -SOS_ENOMEM;    }  sos_process_unref(proc_init);  return SOS_OK;}/* ====================================================================== * The C entry point of our operating system */void sos_main(unsigned long magic, unsigned long arg){  unsigned i;  sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;  struct sos_time tick_resolution;  struct sos_fs_manager_instance * rootfs;  /* Size of RAM above 1MB. Might be undefined ! */  unsigned long int upper_mem = 0;  /* 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)    {      /* 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 = (multiboot_info_t *) arg;      /* 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" ;) */      upper_mem = mbi->mem_upper;      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 8", ',',			      (unsigned)(upper_mem >> 10) + 1,			      (unsigned)upper_mem);    }  else if (magic == 0x42244224)    {      /* Loaded with SOS bootsect */      upper_mem = arg;      sos_x86_videomem_printf(1, 0,			      SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,			      "Welcome to %s%c RAM is %dMB (upper mem = 0x%x kB)",			      "SOS article 8", ',',			      (unsigned)(upper_mem >> 10) + 1,			      (unsigned)upper_mem);    }  else    /* Not loaded with grub, not from an enhanced bootsect */    sos_x86_videomem_printf(1, 0,			    SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,			    "Welcome to SOS article 8");  sos_bochs_putstring("Message in a bochs: This is SOS article 8.\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 to know the RAM size */  if (upper_mem == 0)    {      sos_x86_videomem_putstring(20, 0,				 SOS_X86_VIDEO_FG_LTRED				   | SOS_X86_VIDEO_BG_BLUE				   | SOS_X86_VIDEO_FG_BLINKING,				 "I don't know RAM size ! Load me 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   */  SOS_ASSERT_FATAL(SOS_OK		   == sos_physmem_subsystem_setup((upper_mem<<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);  /*   * Initialise user address space management subsystem   */  sos_umem_vmm_subsystem_setup();  sos_dev_zero_subsystem_setup();  /*   * 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");  SOS_ASSERT_FATAL(SOS_OK == sos_fs_virtfs_subsystem_setup());  SOS_ASSERT_FATAL(SOS_OK == sos_fs_subsystem_setup(NULL,						    "virtfs",						    NULL,						    & rootfs));  /* Start the 'init' process, which in turns launches the other     programs */  start_init(rootfs);  /*   * 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 + -