void entry (unsigned long magic, unsigned long addr) { multiboot_info_t *mbi; /* Clear the screen. */ clear(); /* Am I booted by a Multiboot-compliant boot loader? */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf ("Invalid magic number: 0x%#x\n", (unsigned) magic); return; } /* Set MBI to the address of the Multiboot information structure. */ mbi = (multiboot_info_t *) addr; /* Print out the flags. */ printf ("flags = 0x%#x\n", (unsigned) mbi->flags); /* Are mem_* valid? */ if (CHECK_FLAG (mbi->flags, 0)) printf ("mem_lower = %uKB, mem_upper = %uKB\n", (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); /* Is boot_device valid? */ if (CHECK_FLAG (mbi->flags, 1)) printf ("boot_device = 0x%#x\n", (unsigned) mbi->boot_device); /* Is the command line passed? */ if (CHECK_FLAG (mbi->flags, 2)) printf ("cmdline = %s\n", (char *) mbi->cmdline); void * zbigfs_location = NULL; if (CHECK_FLAG (mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; while(mod_count < mbi->mods_count) { printf("Module %d loaded at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_start); printf("Module %d ends at address: 0x%#x\n", mod_count, (unsigned int)mod->mod_end); printf("First few bytes of module:\n"); for(i = 0; i < 16; i++) { printf("0x%x ", *((char*)(mod->mod_start+i))); } printf("\n"); mod_count++; mod++; } if (mod_count){ module_t* zbigfsmod = (module_t*)mbi->mods_addr; zbigfs_location = (void *) zbigfsmod->mod_start; } else { printf("No module 0, zbigfs will FAIL!"); } } /* Bits 4 and 5 are mutually exclusive! */ if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) { printf ("Both bits 4 and 5 are set.\n"); return; } /* Is the section header table of ELF valid? */ if (CHECK_FLAG (mbi->flags, 5)) { elf_section_header_table_t *elf_sec = &(mbi->elf_sec); printf ("elf_sec: num = %u, size = 0x%#x," " addr = 0x%#x, shndx = 0x%#x\n", (unsigned) elf_sec->num, (unsigned) elf_sec->size, (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); } /* Are mmap_* valid? */ if (CHECK_FLAG (mbi->flags, 6)) { memory_map_t *mmap; printf ("mmap_addr = 0x%#x, mmap_length = 0x%x\n", (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); for (mmap = (memory_map_t *) mbi->mmap_addr; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size))) printf (" size = 0x%x, base_addr = 0x%#x%#x\n" " type = 0x%x, length = 0x%#x%#x\n", (unsigned) mmap->size, (unsigned) mmap->base_addr_high, (unsigned) mmap->base_addr_low, (unsigned) mmap->type, (unsigned) mmap->length_high, (unsigned) mmap->length_low); } /* Construct an LDT entry in the GDT */ { seg_desc_t the_ldt_desc; the_ldt_desc.granularity = 0; the_ldt_desc.opsize = 1; the_ldt_desc.reserved = 0; the_ldt_desc.avail = 0; the_ldt_desc.present = 1; the_ldt_desc.dpl = 0x0; the_ldt_desc.sys = 0; the_ldt_desc.type = 0x2; SET_LDT_PARAMS(the_ldt_desc, &ldt, ldt_size); ldt_desc_ptr = the_ldt_desc; lldt(KERNEL_LDT); } /* Construct a TSS entry in the GDT */ { seg_desc_t the_tss_desc; the_tss_desc.granularity = 0; the_tss_desc.opsize = 0; the_tss_desc.reserved = 0; the_tss_desc.avail = 0; the_tss_desc.seg_lim_19_16 = TSS_SIZE & 0x000F0000; the_tss_desc.present = 1; the_tss_desc.dpl = 0x0; the_tss_desc.sys = 0; the_tss_desc.type = 0x9; the_tss_desc.seg_lim_15_00 = TSS_SIZE & 0x0000FFFF; SET_TSS_PARAMS(the_tss_desc, &tss, tss_size); tss_desc_ptr = the_tss_desc; tss.ldt_segment_selector = KERNEL_LDT; tss.ss0 = KERNEL_DS; tss.esp0 = 0x800000; //8MB ltr(KERNEL_TSS); } //printf("Enabling Interrupts\n"); /* Init the PIC */ populate_idt(); i8259_init(); rtc_init(); outb(PIT_MODIFY_LOW | PIT_MODIFY_HIGH | PIT_MODE_2 ,PIT_CTRL_ADDR); outb(PIT_DEFAULT_RATE_LOW,PIT_PORT0_CTRL_ADDR); //set low byte outb(PIT_DEFAULT_RATE_HIGH,PIT_PORT0_CTRL_ADDR); //set high byte /* * pc speaker code from osdev * uint32_t Div; uint8_t tmp; //Set the PIT to the desired frequency Div = 1193180 / 1000; outb(0x43, 0xb6); outb(0x42, (uint8_t) (Div) ); outb(0x42, (uint8_t) (Div >> 8)); //And play the sound using the PC speaker tmp = inb(0x61); if (tmp != (tmp | 3)) { outb(0x61, tmp | 3); } */ disable_irq(0); /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ /* Enable interrupts */ /* Do not enable the following until after you have set up your * IDT correctly otherwise QEMU will triple fault and simple close * without showing you any output */ //Enable interrupts for the first time printf("Enabling Interrupts\n"); sti(); //Initialize paging and mount the filesysem init_paging(); printf("Mounting module 0 as read-only zbigfs filesystem\n"); zbigfs_mount(zbigfs_location); //Initialize PCBs and then clear the terminal so it looks nice init_pcbs(); term_clear(); /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }
// Kernel void kernel(dword magic, dword addr) { dword * t; byte * buffer; multiboot_info_t * multiboot_info; // Print something clrscr(); puts("Starting...\n"); // MBoot check if(magic != MULTIBOOT_BOOTLOADER_MAGIC) { puts("Invalid magic number!\n"); for(;;); } multiboot_info = (multiboot_info_t *)addr; if (CHECK_FLAG(multiboot_info -> flags, 4) && CHECK_FLAG(multiboot_info -> flags, 5)) { puts("Invalid! Both bits 4 and 5 are set!\n"); for(;;); } printf("multiboot_info_flags = 0x%x\n", multiboot_info -> flags); if(CHECK_FLAG(multiboot_info -> flags, 0)) { printf("mem_lower = 0x%x KiB\n", multiboot_info -> mem_lower); printf("mem_upper = 0x%x KiB\n", multiboot_info -> mem_upper); } if(CHECK_FLAG(multiboot_info -> flags, 1)) { printf("boot_device = 0x%x\n", multiboot_info -> boot_device); } if(CHECK_FLAG(multiboot_info -> flags, 2)) { printf("cmdline = %s\n", (char *)multiboot_info -> cmdline); } // Init GDT set_gd(gd + 0, 0x0, 0x0, 0x0); // zero set_gd(gd + 1, 0x0, 0xcfffff, 0x9a); // cs set_gd(gd + 2, 0x0, 0xcfffff, 0x92); // ds gdtr.limit = 0x2000; gdtr.gd = gd; asm("lgdt %0"::"m"(gdtr)); // Init IRQ init_irq(); // Init IDT populate_idt(id); idtr.limit = 0x7ff; idtr.id = id; asm("lidt %0"::"m"(idtr)); // Init paging init_paging(); asm ("" : :"a"(pdbr)); asm("mov %eax, %cr3"); asm("mov %cr0, %eax"); asm("bts $0x1f, %eax"); asm("mov %eax, %cr0"); asm("jmp . + 2"); // Test FAT fat_init(& media_read, 30); buffer = malloc(512); fat_loadfile("test", buffer, 512); puts((char *)buffer); // Permit int asm("sti"); // Test paging t = (dword *)0x900000; *t = 7; // LOOP for(;;); }