/* * Bootstrap-CPU start; we came from head.S */ void __no_return kernel_start(void) { /* Before anything else, zero the bss section. As said by C99: * “All objects with static storage duration shall be inited * before program startup”, and that the implicit init is done * with zero. Kernel assembly code also assumes a zeroed BSS * space */ clear_bss(); /* * Very-early setup: Do not call any code that will use * printk(), `current', per-CPU vars, or a spin lock. */ setup_idt(); schedulify_this_code_path(BOOTSTRAP); /* * Memory Management init */ print_info(); /* First, don't override the ramdisk area (if any) */ ramdisk_init(); /* Then discover our physical memory map .. */ e820_init(); /* and tokenize the available memory into allocatable pages */ pagealloc_init(); /* With the page allocator in place, git rid of our temporary * early-boot page tables and setup dynamic permanent ones */ vm_init(); /* MM basics done, enable dynamic heap memory to kernel code * early on .. */ kmalloc_init(); /* * Secondary-CPUs startup */ /* Discover our secondary-CPUs and system IRQs layout before * initializing the local APICs */ mptables_init(); /* Remap and mask the PIC; it's just a disturbance */ serial_init(); pic_init(); /* Initialize the APICs (and map their MMIO regs) before enabling * IRQs, and before firing other cores using Inter-CPU Interrupts */ apic_init(); ioapic_init(); /* SMP infrastructure ready, fire the CPUs! */ smpboot_init(); keyboard_init(); /* Startup finished, roll-in the scheduler! */ sched_init(); local_irq_enable(); /* * Second part of kernel initialization (Scheduler is now on!) */ ext2_init(); // Signal the secondary cores to run their own test-cases code. // They've been waiting for us (thread 0) till all of kernel // subsystems has been properly initialized. Wait No More! smpboot_trigger_secondary_cores_testcases(); run_test_cases(); halt(); }
int main (int argc, char* argv[]) { int fd, kernel_fd = -1; /* scanning whether there's -h or --help in the options */ char c, *unit; while ((c = getopt_long(argc, argv, ":skmdx:", longopts, 0)) != -1) { switch (c) { case 'h': printf (" -d <path>, --disk=<path> specify normal disk\n" " -k <path>, --kernel=<path> specify kernel file\n" " -m NUM , --memsize=NUM specify memory size\n" " -s <path>, --swap=<path> specify swap disk\n" " -h, --help print this message and exit\n"); return 0; break; case 'k': if ((kernel_fd = open (optarg, O_RDONLY)) < 0) return 1; break; case 'm': memsize = strtol (optarg, &unit, 10); if (*unit == 'K' || *unit == 'k') memsize <<= 10; else if (*unit == 'M' || *unit == 'm') memsize <<= 20; break; default: /* ignore other options now */ break; } } if (kernel_fd < 0) { printf ("No kernel file specified.\n"); return 1; } struct stat buf; fstat (kernel_fd, &buf); fd = create_mem_file (memsize); /* map the temp file & copy boot and kernel code to the memory */ int brk_end = (int)sbrk (0); mmap ((void*)brk_end, memsize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0); read_kernel (kernel_fd, brk_end - KERNBASE); /* map the reserved part to where it really should be */ mmap ((void*)KERNBASE, RESERVED_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0); /* Now we have access to ginfo normally. */ ginfo->mem_fd = fd; e820_init (kernel_fd); parse_opts (argc, argv); /* unmap useless page table entries */ memcpy ((void*)(BOOT_CODE), (void*)&__boot_start, PGSIZE); stk_init (brk_end, fd); void (*boot_start) (void); boot_start = __pa (__boot_entry); boot_start (); return 0; }