int kern_init(void) { extern char edata[], end[]; memset(edata, 0, end - edata); cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; cprintf("%s\n\n", message); print_kerninfo(); grade_backtrace(); pic_init(); // init interrupt controller idt_init(); // init interrupt descriptor table pmm_init(); // init physical memory management vmm_init(); // init virtual memory management sched_init(); // init scheduler proc_init(); // init process table swap_init(); // init swap fs_init(); // init fs clock_init(); // init clock interrupt intr_enable(); // enable irq interrupt //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() // user/kernel mode switch test //lab1_switch_test(); cpu_idle(); // run idle process }
/** * The entry. */ int main(int argc, char *argv[], char *envp[]) { if (ginfo->status == STATUS_DEBUG) raise(SIGTRAP); cons_init(); const char *message = "(THU.CST) os is loading ..."; kprintf("%s\n\n", message); intr_init(); ide_init(); host_signal_init(); /* Only to initialize lcpu_count. */ mp_init(); pmm_init(); pmm_init_ap(); vmm_init(); sched_init(); proc_init(); swap_init(); fs_init(); sync_init(); umclock_init(); cpu_idle(); host_exit(SIGINT); return 0; }
int kern_init(void) { extern char edata[], end[]; memset(edata, 0, end - edata); cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; kprintf ("%s\n\n", message); /* Only to initialize lcpu_count. */ mp_init (); pmm_init(); // init physical memory management pmm_init_ap (); pic_init(); // init interrupt controller vmm_init(); // init virtual memory management sched_init(); // init scheduler proc_init(); // init process table sync_init(); // init sync struct ide_init(); // init ide devices swap_init(); // init swap fs_init(); // init fs clock_init(); // init clock interrupt intr_enable(); // enable irq interrupt cpu_idle(); // run idle process }
int __noreturn kern_init(void) { extern char edata[], end[]; memset(edata, 0, end - edata); cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; cprintf("%s\n\n", message); print_kerninfo(); pmm_init(); // init physical memory management pic_init(); // init interrupt controller idt_init(); // init interrupt descriptor table vmm_init(); // init virtual memory management sched_init(); // init scheduler proc_init(); // init process table sync_init(); // init sync struct ide_init(); // init ide devices swap_init(); // init swap fs_init(); // init fs clock_init(); // init clock interrupt intr_enable(); // enable irq interrupt cpu_idle(); // run idle process }
void frame_init(){ lock_init(&framelock); /* SPT_init(); */ lock_init(&filesys_lock2); lock_init (&mapids_lock); list_init (&framelist); swap_init(); }
int evict_page(struct page* p) { // removes page from coremap if (!swap_initialized) { int err = swap_init(); if (err) { return err; } } spinlock_acquire(&p->pg_lock); KASSERT(p->is_dirty==0); // page should be clean KASSERT(p->status==IN_MEM); // page should be in memory, but not tlb coremap_ufree(p->ram_addr); // free the coremap entry spinlock_acquire(&p->pg_lock); return 0; }
void umain(void) { static_assert(sizeof(struct File) == 256); binaryname = "fs"; cprintf("FS is running\n"); // Check that we are able to do I/O outw(0x8A00, 0x8A00); cprintf("FS can do I/O\n"); serve_init(); fs_init(); swap_init(); fs_test(); check_SwapBlock(); serve(); }
int kern_init(void) { extern char edata[], end[]; memset(edata, 0, end - edata); cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; kprintf("%s\n\n", message); print_kerninfo(); /* Only to initialize lcpu_count. */ mp_init(); debug_init(); // init debug registers pmm_init(); // init physical memory management pmm_init_ap(); pic_init(); // init interrupt controller idt_init(); // init interrupt descriptor table vmm_init(); // init virtual memory management sched_init(); // init scheduler proc_init(); // init process table sync_init(); // init sync struct ide_init(); // init ide devices #ifdef UCONFIG_SWAP swap_init(); // init swap #endif fs_init(); // init fs clock_init(); // init clock interrupt mod_init(); intr_enable(); // enable irq interrupt /* do nothing */ cpu_idle(); // run idle process }
//swap out to disk size_t swap_out_of_memory (void * upage) { swap_init (); if (swap_block == NULL || &swap_list == NULL) { return -1; } lock_acquire(&swap_lock); struct list_elem * e = list_begin(&swap_list); int index; int i; for(e; e != list_end(&swap_list); e = list_next(e)) { index++; struct swap_item * item = list_entry(e, struct swap_item, elem); if(item->available == true) { item->available = false; index = item->index; break; } } if(index == list_size(&swap_list)) { lock_release(&swap_lock); return -1; } for (i = 0; i < SECTORS_PER_PAGE; i++) { block_write (swap_block, index * SECTORS_PER_PAGE + i, (uint8_t *) upage + i * BLOCK_SECTOR_SIZE); } lock_release(&swap_lock); return index; }
int swap_in_page(struct page* p) { if (!swap_initialized) { int err = swap_init(); if (err) return err; } spinlock_acquire(&p->pg_lock); paddr_t pa = coremap_ualloc(p); while (pa==0) { swap_out_page(); pa = coremap_ualloc(p); } p->ram_addr = pa; read_in_page(p); p->status = IN_MEM; p->is_dirty = 0; spinlock_release(&p->pg_lock); return 0; }
int swap_out_page(void) { if (!swap_initialized) { int err = swap_init(); if (err) return err; } struct page* p = find_swapout(); if (p==NULL) panic("Could not find a page to swap out"); spinlock_acquire(&p->pg_lock); if (p->is_dirty) write_out_page(p); evict_page(p); p->status = IN_SWAP; p->ram_addr = 31; spinlock_release(&p->pg_lock); return 0; }
extern "C" int _start(kernel_args *bootKernelArgs, int currentCPU) { if (bootKernelArgs->kernel_args_size != sizeof(kernel_args) || bootKernelArgs->version != CURRENT_KERNEL_ARGS_VERSION) { // This is something we cannot handle right now - release kernels // should always be able to handle the kernel_args of earlier // released kernels. debug_early_boot_message("Version mismatch between boot loader and " "kernel!\n"); return -1; } smp_set_num_cpus(bootKernelArgs->num_cpus); // wait for all the cpus to get here smp_cpu_rendezvous(&sCpuRendezvous, currentCPU); // the passed in kernel args are in a non-allocated range of memory if (currentCPU == 0) memcpy(&sKernelArgs, bootKernelArgs, sizeof(kernel_args)); smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU); // do any pre-booting cpu config cpu_preboot_init_percpu(&sKernelArgs, currentCPU); thread_preboot_init_percpu(&sKernelArgs, currentCPU); // if we're not a boot cpu, spin here until someone wakes us up if (smp_trap_non_boot_cpus(currentCPU, &sCpuRendezvous3)) { // init platform arch_platform_init(&sKernelArgs); // setup debug output debug_init(&sKernelArgs); set_dprintf_enabled(true); dprintf("Welcome to kernel debugger output!\n"); dprintf("Haiku revision: %lu\n", get_haiku_revision()); // init modules TRACE("init CPU\n"); cpu_init(&sKernelArgs); cpu_init_percpu(&sKernelArgs, currentCPU); TRACE("init interrupts\n"); int_init(&sKernelArgs); TRACE("init VM\n"); vm_init(&sKernelArgs); // Before vm_init_post_sem() is called, we have to make sure that // the boot loader allocated region is not used anymore boot_item_init(); debug_init_post_vm(&sKernelArgs); low_resource_manager_init(); // now we can use the heap and create areas arch_platform_init_post_vm(&sKernelArgs); lock_debug_init(); TRACE("init driver_settings\n"); driver_settings_init(&sKernelArgs); debug_init_post_settings(&sKernelArgs); TRACE("init notification services\n"); notifications_init(); TRACE("init teams\n"); team_init(&sKernelArgs); TRACE("init ELF loader\n"); elf_init(&sKernelArgs); TRACE("init modules\n"); module_init(&sKernelArgs); TRACE("init semaphores\n"); haiku_sem_init(&sKernelArgs); TRACE("init interrupts post vm\n"); int_init_post_vm(&sKernelArgs); cpu_init_post_vm(&sKernelArgs); commpage_init(); TRACE("init system info\n"); system_info_init(&sKernelArgs); TRACE("init SMP\n"); smp_init(&sKernelArgs); TRACE("init timer\n"); timer_init(&sKernelArgs); TRACE("init real time clock\n"); rtc_init(&sKernelArgs); TRACE("init condition variables\n"); condition_variable_init(); // now we can create and use semaphores TRACE("init VM semaphores\n"); vm_init_post_sem(&sKernelArgs); TRACE("init generic syscall\n"); generic_syscall_init(); smp_init_post_generic_syscalls(); TRACE("init scheduler\n"); scheduler_init(); TRACE("init threads\n"); thread_init(&sKernelArgs); TRACE("init kernel daemons\n"); kernel_daemon_init(); arch_platform_init_post_thread(&sKernelArgs); TRACE("init I/O interrupts\n"); int_init_io(&sKernelArgs); TRACE("init VM threads\n"); vm_init_post_thread(&sKernelArgs); low_resource_manager_init_post_thread(); TRACE("init VFS\n"); vfs_init(&sKernelArgs); #if ENABLE_SWAP_SUPPORT TRACE("init swap support\n"); swap_init(); #endif TRACE("init POSIX semaphores\n"); realtime_sem_init(); xsi_sem_init(); xsi_msg_init(); // Start a thread to finish initializing the rest of the system. Note, // it won't be scheduled before calling scheduler_start() (on any CPU). TRACE("spawning main2 thread\n"); thread_id thread = spawn_kernel_thread(&main2, "main2", B_NORMAL_PRIORITY, NULL); resume_thread(thread); // We're ready to start the scheduler and enable interrupts on all CPUs. scheduler_enable_scheduling(); // bring up the AP cpus in a lock step fashion TRACE("waking up AP cpus\n"); sCpuRendezvous = sCpuRendezvous2 = 0; smp_wake_up_non_boot_cpus(); smp_cpu_rendezvous(&sCpuRendezvous, 0); // wait until they're booted // exit the kernel startup phase (mutexes, etc work from now on out) TRACE("exiting kernel startup\n"); gKernelStartup = false; smp_cpu_rendezvous(&sCpuRendezvous2, 0); // release the AP cpus to go enter the scheduler TRACE("starting scheduler on cpu 0 and enabling interrupts\n"); scheduler_start(); enable_interrupts(); } else { // lets make sure we're in sync with the main cpu // the boot processor has probably been sending us // tlb sync messages all along the way, but we've // been ignoring them arch_cpu_global_TLB_invalidate(); // this is run for each non boot processor after they've been set loose cpu_init_percpu(&sKernelArgs, currentCPU); smp_per_cpu_init(&sKernelArgs, currentCPU); // wait for all other AP cpus to get to this point smp_cpu_rendezvous(&sCpuRendezvous, currentCPU); smp_cpu_rendezvous(&sCpuRendezvous2, currentCPU); // welcome to the machine scheduler_start(); enable_interrupts(); } #ifdef TRACE_BOOT // We disable interrupts for this dprintf(), since otherwise dprintf() // would acquires a mutex, which is something we must not do in an idle // thread, or otherwise the scheduler would be seriously unhappy. disable_interrupts(); TRACE("main: done... begin idle loop on cpu %d\n", currentCPU); enable_interrupts(); #endif for (;;) arch_cpu_idle(); return 0; }
int main(int argc, char *argv[]) { int opt; unsigned swapsize; FILE *tfp = stdin; char *replacement_alg = NULL; char *usage = "USAGE: sim -f tracefile -m memorysize -s swapsize -a algorithm\n"; while ((opt = getopt(argc, argv, "f:m:a:s:")) != -1) { switch (opt) { case 'f': tracefile = optarg; break; case 'm': memsize = (unsigned)strtoul(optarg, NULL, 10); break; case 'a': replacement_alg = optarg; break; case 's': swapsize = (unsigned)strtoul(optarg, NULL, 10); break; default: fprintf(stderr, "%s", usage); exit(1); } } if(tracefile != NULL) { if((tfp = fopen(tracefile, "r")) == NULL) { perror("Error opening tracefile:"); exit(1); } } // Initialize main data structures for simulation. // This happens before calling the replacement algorithm init function // so that the init_fcn can refer to the coremap if needed. //coremap is the amount of memory needed to hold all physical frame structs coremap = malloc(memsize * sizeof(struct frame)); //physmem is the bits/bytes in the total physical memory, a large array of bytes physmem = malloc(memsize * SIMPAGESIZE); swap_init(swapsize); init_pagetable(); // Initialize replacement algorithm functions. if(replacement_alg == NULL) { fprintf(stderr, "%s", usage); exit(1); } else { int i; for (i = 0; i < num_algs; i++) { if(strcmp(algs[i].name, replacement_alg) == 0) { init_fcn = algs[i].init; ref_fcn = algs[i].ref; evict_fcn = algs[i].evict; break; } } if(evict_fcn == NULL) { fprintf(stderr, "Error: invalid replacement algorithm - %s\n", replacement_alg); exit(1); } } // Call replacement algorithm's init_fcn before replaying trace. init_fcn(); replay_trace(tfp); print_pagedirectory(); // Cleanup - removes temporary swapfile. swap_destroy(); printf("\n"); printf("Hit count: %d\n", hit_count); printf("Miss count: %d\n", miss_count); printf("Clean evictions: %d\n",evict_clean_count); printf("Dirty evictions: %d\n",evict_dirty_count); printf("Total references : %d\n", ref_count); printf("Hit rate: %.4f\n", (double)hit_count/ref_count * 100); printf("Miss rate: %.4f\n", (double)miss_count/ref_count *100); return(0); }
/* * This function is called from mem_init() to reserve the pages needed for * ST-RAM management. */ void __init atari_stram_reserve_pages(unsigned long start_mem) { #ifdef CONFIG_STRAM_SWAP /* if max_swap_size is negative (i.e. no stram_swap= option given), * determine at run time whether to use ST-RAM swapping */ if (max_swap_size < 0) /* Use swapping if ST-RAM doesn't make up more than MAX_STRAM_FRACTION * of total memory. In that case, the max. size is set to 16 MB, * because ST-RAM can never be bigger than that. * Also, never use swapping on a Hades, there's no separate ST-RAM in * that machine. */ max_swap_size = (!MACH_IS_HADES && (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <= max_mapnr*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0; DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size ); #endif /* always reserve first page of ST-RAM, the first 2 kB are * supervisor-only! */ set_bit( PG_reserved, &mem_map[MAP_NR(stram_start)].flags ); #ifdef CONFIG_STRAM_SWAP if (!max_swap_size) { fallback: #endif DPRINTK( "atari_stram_reserve_pages: swapping disabled\n" ); if (!kernel_in_stram) { /* Reserve all pages that have been marked by pre-mem_init * stram_alloc() (e.g. for the screen memory). */ reserve_region( rsvd_stram_beg, rsvd_stram_end ); DPRINTK( "atari_stram_reserve_pages: reseverved %08lx-%08lx\n", rsvd_stram_beg, rsvd_stram_end ); } /* else (kernel in ST-RAM): nothing to do, ST-RAM buffers are * kernel data */ #ifdef CONFIG_STRAM_SWAP } else { unsigned long swap_data; BLOCK *p; /* determine first page to use as swap: * if the kernel is in TT-RAM, this is the first page of (usable) * ST-RAM; else if there were already some allocations (probable...), * use the lowest address of these (the list is sorted by address!); * otherwise just use the end of kernel data (= start_mem) */ swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : alloc_list ? alloc_list->start : start_mem; /* decrement by one page, rest of kernel assumes that first swap page * is always reserved and maybe doesn't handle SWP_ENTRY == 0 * correctly */ swap_start -= PAGE_SIZE; swap_end = stram_end; if (swap_end-swap_start > max_swap_size) swap_end = swap_start + max_swap_size; DPRINTK( "atari_stram_reserve_pages: swapping enabled; " "swap=%08lx-%08lx\n", swap_start, swap_end ); /* reserve some amount of memory for maintainance of * swapping itself: 1 page for the lockmap, and one page * for each 2048 (PAGE_SIZE/2) swap pages. (2 bytes for * each page) */ swap_data = start_mem; start_mem += (((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1) >> (PAGE_SHIFT-1)) + 1) << PAGE_SHIFT; /* correct swap_start if necessary */ if (swap_start == swap_data) swap_start = start_mem; if (!swap_init( start_mem, swap_data )) { printk( KERN_ERR "ST-RAM swap space initialization failed\n" ); max_swap_size = 0; goto fallback; } /* reserve region for swapping meta-data */ reserve_region( swap_data, start_mem ); /* reserve swapping area itself */ reserve_region( swap_start+PAGE_SIZE, swap_end ); /* Formerly static areas have been included in the swap area. */ for( p = alloc_list; p; p = p->next ) { if (p->flags & BLOCK_STATIC) p->flags = (p->flags & ~BLOCK_STATIC) | BLOCK_INSWAP; } /* * If the whole ST-RAM is used for swapping, there are no allocatable * dma pages left. But unfortunately, some shared parts of the kernel * (particularily the SCSI mid-level) call __get_dma_pages() * unconditionally :-( These calls then fail, and scsi.c even doesn't * check for NULL return values and just crashes. The quick fix for * this (instead of doing much clean up work in the SCSI code) is to * pretend all pages are DMA-able by setting mach_max_dma_address to * ULONG_MAX. This doesn't change any functionality so far, since * get_dma_pages() shouldn't be used on Atari anyway anymore (better * use atari_stram_alloc()), and the Atari SCSI drivers don't need DMA * memory. But unfortunately there's now no kind of warning (even not * a NULL return value) if you use get_dma_pages() nevertheless :-( * You just will get non-DMA-able memory... */ mach_max_dma_address = 0xffffffff; /* * Ok, num_physpages needs not be really exact, but it's better to * subtract the pages set aside for swapping. */ num_physpages -= SWAP_NR(swap_end)-1; } #endif mem_init_done = 1; }
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 }
/* * Initial boot sequence. */ static void boot(void) { /* * The order of these is important! * Don't go changing it without thinking about the consequences. * * Among other things, be aware that console output gets * buffered up at first and does not actually appear until * mainbus_bootstrap() attaches the console device. This can * be remarkably confusing if a bug occurs at this point. So * don't put new code before mainbus_bootstrap if you don't * absolutely have to. * * Also note that the buffer for this is only 1k. If you * overflow it, the system will crash without printing * anything at all. You can make it larger though (it's in * dev/generic/console.c). */ kprintf("\n"); kprintf("OS/161 base system version %s\n", BASE_VERSION); kprintf("%s", harvard_copyright); kprintf("\n"); kprintf("Bala&Barry's system version %s (%s #%d)\n", GROUP_VERSION, buildconfig, buildversion); kprintf("\n"); /* Early initialization. */ ram_bootstrap(); vm_bootstrap(); proc_bootstrap(); thread_bootstrap(); hardclock_bootstrap(); vfs_bootstrap(); kheap_nextgeneration(); /* Probe and initialize devices. Interrupts should come on. */ kprintf("Device probe...\n"); KASSERT(curthread->t_curspl > 0); mainbus_bootstrap(); KASSERT(curthread->t_curspl == 0); /* Now do pseudo-devices. */ pseudoconfig(); kprintf("\n"); kheap_nextgeneration(); /* Late phase of initialization. */ kprintf_bootstrap(); thread_start_cpus(); test161_bootstrap(); swap_init(); /* Default bootfs - but ignore failure, in case emu0 doesn't exist */ vfs_setbootfs("emu0"); kheap_nextgeneration(); /* * Make sure various things aren't screwed up. */ COMPILE_ASSERT(sizeof(userptr_t) == sizeof(char *)); COMPILE_ASSERT(sizeof(*(userptr_t)0) == sizeof(char)); }