#include "clib.h" #include "globals.h" #include "i386.h" #include "phmem.h" #include "paging.h" #include "systab.h" #include "sched.h" #include "excpt.h" #include "irq.h" #include "kmalloc.h" #include "vm86.h" #include "debugg.h" #ifndef NDEBUG bool debug_verbose = false; bool debug_trace = false; bool debug_flag = false; #endif stub_stat_t stub_stat; #define SHOW_CR4(b) DEBUG_VERBOSE(#b" %d ", _cr4.##b); void start_kernel(); /* * questa e` la prima procedura chiamata da crt0.asm situazione : * * ds,ss,es = KERNEL_DS fs,gs=0 cs=KERNEL_CS * esp = stack dello stub, poco meno di 1K * * la paginazione e` gia` attivata [e con lo stub 0.6 le tabelle sono * nella memoria video!] * * cr0 : per 386 -> PG/PE * per 486 -> PG/AM/WP/PE * per 586 -> PG/AM/WP/NE/PE * * se c'e` la FPU MP = 1, comunque EM e` sempre a 0 * * cr4 : per 386/486dx2 -> nada * per 486dx4+ -> vengono abilitati VME/PVI/DE/PSE/PGE se disponibili * * * * gli interrupt sono disabilitati, il PIC e` stato riprogrammato, * l'IRQ0 e` l'int 0xf0, IRQ 8 = int 0xf8, uso l'auto EOI * * TR = task temporaneo * ldt = 0 * GDT = gdt dello stub loader, per la V0.6 i descrittori sono 10 * IDT = nulla */ int start(void) { int i; #ifndef NDEBUG if (stub_stat.flags & 1) { debug_verbose = 1; debug_trace = 1; memset((void*)0xB8000, 0, 50*80*2); /* clrscr */ } #endif DEBUG_VERBOSE("CPU %d vendor %s feature %xh FPU %d CR4 %xh\n", _cpu_family, _cpu_vendor, _cpu_feature, _fpu_family, _cr4); SHOW_CR4(vme); SHOW_CR4(pvi); SHOW_CR4(tsd); SHOW_CR4(de); SHOW_CR4(pse); SHOW_CR4(pae); SHOW_CR4(mce); SHOW_CR4(pge); SHOW_CR4(pce); DEBUG_VERBOSE("\nkernel phisical addr %xh, virtual addr %xh\n", stub_stat.kernel_base, (u32)&end_texts & 0xFFFF0000); i = (int)&end_bsss & 0x3FFFFF; DEBUG_VERBOSE("kernel pages %xh\n", i shr 12); /* * inizializza il gestore delle pagine di memoria * */ ph_memory_setup(stub_stat.kernel_base + i, stub_stat.kernel_pages - (i shr 12)); /* * alloca spazio per una nuova GDT e IDT, entrambe da 256 descrittori. * la GDT viene riempita coi valori della vecchia GDT */ systab_setup(); /* * inizializza per scheduler */ sched_setup(); /* * ok, ora ho sufficienti procedure per creare il vero task del kernel */ /* * crea i task ausiliari per le eccezioni, e quello * del kernel. */ base_tasks_setup(); tss_kernel.esp = (u32)valloc(2) + 8192; tss_kernel.eip = &start_kernel; jmp_task(tss_kernel.tss_sel); DEBUG_FATAL("unexpected return"); return 1; } v86_tss *v86; tss_t *t; extern void v86_startup; void start_kernel() { int i; tss_t *dbg; /* * ora posso inizializzare anche kmalloc */ kmalloc_startup(16); // 16 pagine = 64K /* * imposta i descrittori degli irq. * NB: Irq0 = int 0xf0, irq 8=int0xf8 */ irq_setup(); asm_sti; dbg = alloc_tss(NULL, "KDebugger"); dbg->cs = KERNEL_CS; dbg->ds = dbg->ss = dbg->es = KERNEL_DS; dbg->esp = (u32)valloc(4) + 4*4096; dbg->eip = debug_start; dbg->handler = debug_handler; dbg->eflags = 0; dbg->cr3 = tss_kernel.cr3; jmp_task(dbg->tss_sel); DEBUG_TRACE; exit(0); #if 0 v86 = alloc_v86_task("DOSV86"); v86->tss.cs = stub_stat.dos_mem_ptr shr 16; v86->tss.eip = 0; v86->tss.ss = v86->tss.ds = v86->tss.es = v86->tss.cs; v86->tss.gs = stub_stat.prefixseg; v86->tss.esp = 0xfffc; v86->tss.ss0 = KERNEL_DS; v86->tss.esp0 = alloc_free_page() + 4096; map_memory(&v86->tss, v86->tss.esp0-4096, v86->tss.esp0-4096, 1, pfWritable); // v86->tss.eflags |= (1 shl 12)+(1 shl 13); memset(v86->iobitmap, 0, 128); // v86->iobitmap[4] |= 1; memset(v86->intbitmap, 0, 32); v86->intbitmap[2] |= (1 shl 5); // v86->tss.cr3 = tss_kernel.cr3; map_memory(&v86->tss, (addr_t)0xB8000, (addr_t)0xB8000, 8, pfWritable + pfUser); // memcpy((char*)&v86_startup+4, stub_stat.cmd_line, 40); write_to_task(&v86->tss, (addr_t)(v86->tss.cs*16L), &v86_startup, 500); // memset((addr_t)0xB8000, 0x20, 0x2000); kprintf("DOS MEM: %x, CS:IP %x:%x\n\n", stub_stat.dos_mem_ptr, v86->tss.cs,v86->tss.eip); DEBUG_TRACE jmp_task(v86->tss.tss_sel); DEBUG_TRACE exit(0); #endif }