// Setup code for APs void mp_main(void) { // We are in high EIP now, safe to switch to kern_pgdir lcr3(PADDR(kern_pgdir)); cprintf("SMP: CPU %d starting\n", cpunum()); lapic_init(); env_init_percpu(); trap_init_percpu(); xchg(&thiscpu->cpu_status, CPU_STARTED); // tell boot_aps() we're up #ifdef USE_TICKET_SPIN_LOCK spinlock_test(); #endif // Now that we have finished some basic setup, call sched_yield() // to start running processes on this CPU. But make sure that // only one CPU can enter the scheduler at a time! // // Your code here: lock_kernel(); sched_yield(); // Remove this after you finish Exercise 4 //for (;;); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. //<<<<<<< HEAD ENV_CREATE(user_icode, ENV_TYPE_USER); //======= // ENV_CREATE(user_dumbfork, ENV_TYPE_USER); //>>>>>>> lab4 #endif // TEST* // Should not be necessary - drains keyboard because interrupt has given up. kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
INITCODE void arch_processor_init(cpu_id_t cpuid) { arch_cpu_init(cpuid); if (cpu_has_feature(X86_FTR_APIC)) { lapic_init(cpuid); lapic_timer_init(cpuid); } }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); //bluesea //经测试,下面的语句会输出:edata f0114300, end f0114970 //因此,edata < end, [edata, end)之间是bss段, kernel需要用的global variable. // > end之后的内存可以用于boot_alloc //cprintf("edata %x, end %x\n", edata, end); cprintf("6828 decimal is %o octal!\n", 6828); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. //ENV_CREATE(user_primes, ENV_TYPE_USER); //ENV_CREATE(user_yield, ENV_TYPE_USER); //ENV_CREATE(user_yield, ENV_TYPE_USER); //ENV_CREATE(user_yield, ENV_TYPE_USER); ENV_CREATE(user_dumbfork, ENV_TYPE_USER); #endif // TEST* // Schedule and run the first user environment! sched_yield(); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("372 decimal is %o octal!\n", 372); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); // Should always have idle processes at first. int i; for (i = 0; i < NCPU; i++) ENV_CREATE(user_idle, ENV_TYPE_IDLE); // ENV_CREATE(user_yield, ENV_TYPE_USER); // ENV_CREATE(user_yield, ENV_TYPE_USER); // ENV_CREATE(user_yield, ENV_TYPE_USER); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. ENV_CREATE(user_primes, ENV_TYPE_USER); #endif // TEST* // Schedule and run the first user environment! sched_yield(); }
// Bootstrap processor gets here after setting up the hardware. // Additional processors start here. static void mpmain(void) { cprintf("cpu%d: mpmain\n", cpu()); idtinit(); if(cpu() != mp_bcpu()) lapic_init(cpu()); setupsegs(0); xchg(&cpus[cpu()].booted, 1); cprintf("cpu%d: scheduling\n"); scheduler(); }
/* * Initialize the local APIC on the BSP. */ static int madt_setup_local(void) { madt = pmap_mapbios(madt_physaddr, madt_length); lapic_init(madt->Address); printf("ACPI APIC Table: <%.*s %.*s>\n", (int)sizeof(madt->Header.OemId), madt->Header.OemId, (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId); /* * We ignore 64-bit local APIC override entries. Should we * perhaps emit a warning here if we find one? */ return (0); }
/* * Initialize the local APIC on the BSP. */ static int mptable_setup_local(void) { vm_paddr_t addr; /* Is this a pre-defined config? */ printf("MPTable: <"); if (mpfps->config_type != 0) { addr = DEFAULT_APIC_BASE; printf("Default Configuration %d", mpfps->config_type); } else { addr = mpct->apic_address; printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id, (int)sizeof(mpct->product_id), mpct->product_id); } printf(">\n"); lapic_init(addr); return (0); }
/** * Bootstrap processor starts running C code here. */ int main(void) { /** * ld会生成如下几个变量用来标识程序的段 * * _etext(etext) 正文段结束后第一个地址 * _edata(edata) 数据段结束后第一个地址 * _end(end) bss段结束后第一个地址 */ extern char edata[], end[]; // clear BSS memset(edata, 0, end - edata); // collect info about this machine mp_init(); lapic_init(mp_bcpu()); cprintf("\ncpu%d: starting myos\n\n", cpu()); cprintf("Welcome to myos !\n"); pinit(); // process table binit(); // buffer cache pic_init(); // interrupt controller ioapic_init(); // another interrupt controller kinit(); // physical memory allocator tvinit(); // trap vectors fileinit(); // file table iinit(); // inode cache console_init(); // I/O devices & their interrupts ide_init(); // disk if(!ismp) timer_init(); // uniprocessor timer userinit(); // first user process bootothers(); // start other processors // Finish setting up this processor in mpmain. mpmain(); }
bool apic_init(){ char apic[4] = {'A', 'P', 'I', 'C'}; MADT_t *madt = (MADT_t *)acpi_table(apic); if (madt != null){ // Gather Local and IO APIC(s) _lapic_addr = (uint64)madt->lapic_addr; // Enumerate APICs uint64 length = (madt->h.length - sizeof(MADT_t) + 4); APICHeader_t *ah = (APICHeader_t *)(&madt->ptr); while (length > 0){ #if DEBUG == 1 //debug_print(DC_WGR, "APIC type: %d", ah->type); #endif switch (ah->type){ case APIC_TYPE_LAPIC: // Test if it's enabled - if not - don't touch it if ((((LocalAPIC_t *)ah)->flags & 1) != 0){ _lapic[_lapic_count] = (LocalAPIC_t *)ah; _lapic_count ++; } break; case APIC_TYPE_IOAPIC: _ioapic[_ioapic_count] = (IOAPIC_t *)ah; _ioapic_count ++; break; } length -= ah->length; ah = (APICHeader_t *)(((uint64)ah) + ah->length); } #if DEBUG == 1 debug_print(DC_WB, "CPU count:%d", _lapic_count); #endif // Initialize Local APIC lapic_init(); // Initialize IO APIC ioapic_init(); } }
void ap_init(void) { gdt_init(per_cpu_ptr(cpus, bcpuid)); tls_init(per_cpu_ptr(cpus, bcpuid)); kprintf("CPU%d alive\n", myid()); /* load new pagetable(shared with bsp) */ pmm_init_ap(); idt_init(); // init interrupt descriptor table /* test pmm */ struct Page *p = alloc_pages(2); kprintf("I'm %d, get 0x%016llx(PA)\n", myid(), page2pa(p)); free_pages(p, 2); lapic_init(); proc_init_ap(); atomic_inc(&bsync); /* let BSP know we are up */ intr_enable(); // enable irq interrupt cpu_idle(); }
// Setup code for APs void mp_main(void) { // We are in high EIP now, safe to switch to kern_pgdir lcr3(PADDR(kern_pgdir)); cprintf("SMP: CPU %d starting\n", cpunum()); lapic_init(); env_init_percpu(); trap_init_percpu(); xchg(&thiscpu->cpu_status, CPU_STARTED); // tell boot_aps() we're up // Now that we have finished some basic setup, call sched_yield() // to start running processes on this CPU. But make sure that // only one CPU can enter the scheduler at a time! // // Your code here: lock_kernel(); //Acquire the lock sched_yield(); //Call the sched_yield() function to schedule and run different environments, Exercise 6 // Remove this after you finish Exercise 4 //for (;;); }
void i386_init(void) { /* __asm __volatile("int $12"); */ extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); extern char end[]; end_debug = read_section_headers((0x10000+KERNBASE), (uintptr_t)end); // Lab 2 memory management initialization functions x64_vm_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Acquire the big kernel lock before waking up APs // Your code here: //Starting non-boot CPUs lock_kernel(); boot_aps(); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. //ENV_CREATE(user_icode, ENV_TYPE_USER); // Should not be necessary - drains keyboard because interrupt has given up. //kbd_intr(); //ENV_CREATE(user_primes, ENV_TYPE_USER); //ENV_CREATE(user_testpteshare, ENV_TYPE_USER); //ENV_CREATE(user_testfdsharing, ENV_TYPE_USER); //ENV_CREATE(user_testbss, ENV_TYPE_USER); //ENV_CREATE(user_spawnhello, ENV_TYPE_USER); ENV_CREATE(user_icode, ENV_TYPE_USER); //ENV_CREATE(user_testshell, ENV_TYPE_USER); //ENV_CREATE(user_testfile, ENV_TYPE_USER); //ENV_CREATE(user_primespipe, ENV_TYPE_USER); //ENV_CREATE(user_testkbd, ENV_TYPE_USER); #endif // TEST* // Schedule and run the first user environment! sched_yield(); }
// Called first from entry.S on the bootstrap processor, // and later from boot/bootother.S on all other processors. // As a rule, "init" functions in PIOS are called once on EACH processor. void init(void) { extern char start[], edata[], end[]; // Before anything else, complete the ELF loading process. // Clear all uninitialized global data (BSS) in our program, // ensuring that all static/global variables start out zero. if (cpu_onboot()) memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); extern uint8_t _binary_obj_boot_bootother_start[], _binary_obj_boot_bootother_size[]; uint8_t *code = (uint8_t*)lowmem_bootother_vec; memmove(code, _binary_obj_boot_bootother_start, (uint32_t) _binary_obj_boot_bootother_size); // Lab 1: test cprintf and debug_trace cprintf("1234 decimal is %o octal!\n", 1234); debug_check(); // Initialize and load the bootstrap CPU's GDT, TSS, and IDT. cpu_init(); trap_init(); // Physical memory detection/initialization. // Can't call mem_alloc until after we do this! mem_init(); // Lab 2: check spinlock implementation if (cpu_onboot()) spinlock_check(); // Initialize the paged virtual memory system. pmap_init(); // Find and start other processors in a multiprocessor system mp_init(); // Find info about processors in system pic_init(); // setup the legacy PIC (mainly to disable it) ioapic_init(); // prepare to handle external device interrupts lapic_init(); // setup this CPU's local APIC cpu_bootothers(); // Get other processors started // cprintf("CPU %d (%s) has booted\n", cpu_cur()->id, // cpu_onboot() ? "BP" : "AP"); file_init(); // Create root directory and console I/O files // Lab 4: uncomment this when you can handle IRQ_SERIAL and IRQ_KBD. //cons_intenable(); // Let the console start producing interrupts // Initialize the process management code. proc_init(); // Initialize the process management code. proc_init(); if(!cpu_onboot()) proc_sched(); proc *root = proc_root = proc_alloc(NULL,0); elfhdr *ehs = (elfhdr *)ROOTEXE_START; assert(ehs->e_magic == ELF_MAGIC); proghdr *phs = (proghdr *) ((void *) ehs + ehs->e_phoff); proghdr *ep = phs + ehs->e_phnum; for (; phs < ep; phs++) { if (phs->p_type != ELF_PROG_LOAD) continue; void *fa = (void *) ehs + ROUNDDOWN(phs->p_offset, PAGESIZE); uint32_t va = ROUNDDOWN(phs->p_va, PAGESIZE); uint32_t zva = phs->p_va + phs->p_filesz; uint32_t eva = ROUNDUP(phs->p_va + phs->p_memsz, PAGESIZE); uint32_t perm = SYS_READ | PTE_P | PTE_U; if(phs->p_flags & ELF_PROG_FLAG_WRITE) perm |= SYS_WRITE | PTE_W; for (; va < eva; va += PAGESIZE, fa += PAGESIZE) { pageinfo *pi = mem_alloc(); assert(pi != NULL); if(va < ROUNDDOWN(zva, PAGESIZE)) memmove(mem_pi2ptr(pi), fa, PAGESIZE); else if (va < zva && phs->p_filesz) { memset(mem_pi2ptr(pi),0, PAGESIZE); memmove(mem_pi2ptr(pi), fa, zva-va); } else memset(mem_pi2ptr(pi), 0, PAGESIZE); pte_t *pte = pmap_insert(root->pdir, pi, va, perm); assert(pte != NULL); } } root->sv.tf.eip = ehs->e_entry; root->sv.tf.eflags |= FL_IF; pageinfo *pi = mem_alloc(); assert(pi != NULL); pte_t *pte = pmap_insert(root->pdir, pi, VM_STACKHI-PAGESIZE, SYS_READ | SYS_WRITE | PTE_P | PTE_U | PTE_W); assert(pte != NULL); root->sv.tf.esp = VM_STACKHI; proc_ready(root); proc_sched(); // Initialize the I/O system. // Lab 1: change this so it enters user() in user mode, // running on the user_stack declared above, // instead of just calling user() directly. user(); // FIXME: Maybe get rid of this }
/* * Initialize the local APIC on the BSP. */ static int madt_setup_local(void) { ACPI_TABLE_DMAR *dmartbl; vm_paddr_t dmartbl_physaddr; const char *reason; char *hw_vendor; u_int p[4]; int user_x2apic; bool bios_x2apic; madt = pmap_mapbios(madt_physaddr, madt_length); if ((cpu_feature2 & CPUID2_X2APIC) != 0) { reason = NULL; /* * Automatically detect several configurations where * x2APIC mode is known to cause troubles. User can * override the setting with hw.x2apic_enable tunable. */ dmartbl_physaddr = acpi_find_table(ACPI_SIG_DMAR); if (dmartbl_physaddr != 0) { dmartbl = acpi_map_table(dmartbl_physaddr, ACPI_SIG_DMAR); if ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0) reason = "by DMAR table"; acpi_unmap_table(dmartbl); } if (vm_guest == VM_GUEST_VMWARE) { vmware_hvcall(VMW_HVCMD_GETVCPU_INFO, p); if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 || (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) reason = "inside VMWare without intr redirection"; } else if (vm_guest == VM_GUEST_XEN) { reason = "due to running under XEN"; } else if (vm_guest == VM_GUEST_NO && CPUID_TO_FAMILY(cpu_id) == 0x6 && CPUID_TO_MODEL(cpu_id) == 0x2a) { hw_vendor = kern_getenv("smbios.planar.maker"); /* * It seems that some Lenovo and ASUS * SandyBridge-based notebook BIOSes have a * bug which prevents booting AP in x2APIC * mode. Since the only way to detect mobile * CPU is to check northbridge pci id, which * cannot be done that early, disable x2APIC * for all Lenovo and ASUS SandyBridge * machines. */ if (hw_vendor != NULL) { if (!strcmp(hw_vendor, "LENOVO") || !strcmp(hw_vendor, "ASUSTeK Computer Inc.")) { reason = "for a suspected SandyBridge BIOS bug"; } freeenv(hw_vendor); } } bios_x2apic = lapic_is_x2apic(); if (reason != NULL && bios_x2apic) { if (bootverbose) printf("x2APIC should be disabled %s but " "already enabled by BIOS; enabling.\n", reason); reason = NULL; } if (reason == NULL) x2apic_mode = 1; else if (bootverbose) printf("x2APIC available but disabled %s\n", reason); user_x2apic = x2apic_mode; TUNABLE_INT_FETCH("hw.x2apic_enable", &user_x2apic); if (user_x2apic != x2apic_mode) { if (bios_x2apic && !user_x2apic) printf("x2APIC disabled by tunable and " "enabled by BIOS; ignoring tunable."); else x2apic_mode = user_x2apic; } } lapic_init(madt->Address); printf("ACPI APIC Table: <%.*s %.*s>\n", (int)sizeof(madt->Header.OemId), madt->Header.OemId, (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId); /* * We ignore 64-bit local APIC override entries. Should we * perhaps emit a warning here if we find one? */ return (0); }
int kern_init(uint64_t mbmagic, uint64_t mbmem) { extern char edata[], end[]; memset(edata, 0, end - edata); /* percpu variable for CPU0 is preallocated */ percpu_offsets[0] = __percpu_start; cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; kprintf("%s\n\n", message); if(mbmagic == MULTIBOOT_BOOTLOADER_MAGIC){ kprintf("Multiboot dectected: param %p\n", (void*)mbmem); mbmem2e820((Mbdata*)VADDR_DIRECT(mbmem)); parse_initrd((Mbdata*)VADDR_DIRECT(mbmem)); } print_kerninfo(); /* get_cpu_var not available before tls_init() */ hz_init(); gdt_init(per_cpu_ptr(cpus, 0)); tls_init(per_cpu_ptr(cpus, 0)); acpitables_init(); lapic_init(); numa_init(); pmm_init_numa(); // init physical memory management, numa awared /* map the lapic */ lapic_init_late(); //init the acpi stuff idt_init(); // init interrupt descriptor table pic_init(); // init interrupt controller // acpi_conf_init(); percpu_init(); cpus_init(); #ifdef UCONFIG_ENABLE_IPI ipi_init(); #endif refcache_init(); vmm_init(); // init virtual memory management sched_init(); // init scheduler proc_init(); // init process table sync_init(); // init sync struct /* ext int */ ioapic_init(); acpi_init(); ide_init(); // init ide devices #ifdef UCONFIG_SWAP swap_init(); // init swap #endif fs_init(); // init fs clock_init(); // init clock interrupt mod_init(); trap_init(); //XXX put here? bootaps(); intr_enable(); // enable irq interrupt #ifdef UCONFIG_HAVE_LINUX_DDE36_BASE dde_kit_init(); #endif /* do nothing */ cpu_idle(); // run idle process }
void i386_init(void) { /* __asm __volatile("int $12"); */ extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); #ifdef VMM_GUEST /* Guest VMX extension exposure check */ { uint32_t ecx = 0; cpuid(0x1, NULL, NULL, &ecx, NULL); if (ecx & 0x20) panic("[ERR] VMX extension exposed to guest.\n"); else cprintf("VMX extension hidden from guest.\n"); } #endif #ifndef VMM_GUEST extern char end[]; end_debug = read_section_headers((0x10000+KERNBASE), (uintptr_t)end); #endif // Lab 2 memory management initialization functions x64_vm_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); #ifndef VMM_GUEST // Lab 4 multiprocessor initialization functions lapic_init(); #endif // Lab 4 multitasking initialization functions pic_init(); // Lab 6 hardware initialization functions time_init(); pci_init(); // Acquire the big kernel lock before waking up APs // Your code here: #ifndef VMM_GUEST // Starting non-boot CPUs boot_aps(); #endif cprintf("\nAdding idle"); ENV_CREATE(user_idle, ENV_TYPE_IDLE); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else //start fs cprintf("\nAdding FILE SYSTEM"); ENV_CREATE(fs_fs,ENV_TYPE_FS); #if defined(TEST_EPT_MAP) test_ept_map(); #endif cprintf("\nAdding ICODE"); ENV_CREATE(user_icode,ENV_TYPE_USER); #endif // Should not be necessary - drains keyboard because interrupt has given up. // kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Lab 6 hardware initialization functions time_init(); pci_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); // Should always have idle processes at first. int i; for (i = 0; i < NCPU; i++) ENV_CREATE(user_idle, ENV_TYPE_IDLE); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); #if !defined(TEST_NO_NS) // Start ns. ENV_CREATE(net_ns, ENV_TYPE_NS); #endif #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. ENV_CREATE(user_icode, ENV_TYPE_USER); #endif // TEST* // Should not be necessary - drains keyboard because interrupt has given up. kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); // cprintf("6828 decimal is %o octal!%n\n%n", 6828, &chnum1, &chnum2); // cprintf("pading space in the right to number 22: %-8d.\n", 22); // cprintf("chnum1: %d chnum2: %d\n", chnum1, chnum2); // cprintf("%n", NULL); // memset(ntest, 0xd, sizeof(ntest) - 1); // cprintf("%s%n", ntest, &chnum1); // cprintf("chnum1: %d\n", chnum1); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); #ifdef USE_TICKET_SPIN_LOCK unlock_kernel(); spinlock_test(); lock_kernel(); #endif // Should always have idle processes at first. int i; for (i = 0; i < NCPU; i++) ENV_CREATE(user_idle, ENV_TYPE_IDLE); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. //ENV_CREATE(user_primes, ENV_TYPE_USER); //ENV_CREATE(user_yield, ENV_TYPE_USER); //ENV_CREATE(user_yield, ENV_TYPE_USER); //ENV_CREATE(user_yield, ENV_TYPE_USER); //ENV_CREATE(user_dumbfork, ENV_TYPE_USER); ENV_CREATE(user_hello, ENV_TYPE_USER); #endif // TEST* // Schedule and run the first user environment! sched_yield(); }