void main(void) { clear(); println_newline(); print_colored(" _ _ ", LOGO_NEM_COLOR); println_colored(" ____ _____", LOGO_OS_COLOR); print_colored(" | \\ | | ", LOGO_NEM_COLOR); println_colored("/ __ \\ / ____|", LOGO_OS_COLOR); print_colored(" | \\| | ___ _ __ ___ ", LOGO_NEM_COLOR); println_colored("| | | | (___ ", LOGO_OS_COLOR); print_colored(" | . ` |/ _ \\ '_ ` _ \\", LOGO_NEM_COLOR); println_colored("| | | |\\___ \\ ", LOGO_OS_COLOR); print_colored(" | |\\ | __/ | | | | ", LOGO_NEM_COLOR); println_colored("| |__| |____) |", LOGO_OS_COLOR); print_colored(" |_| \\_|\\___|_| |_| |_|", LOGO_NEM_COLOR); println_colored("\\____/|_____/ ", LOGO_OS_COLOR); println_newline(); initialize_idt(); initialize_keyboard(); while (1); }
/* Check if MAGIC is valid and print the Multiboot information structure pointed by ADDR. */ void entry (unsigned long magic, unsigned long addr) { /* Initialize the idt */ init_idt(); 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); if (CHECK_FLAG (mbi->flags, 3)) { int mod_count = 0; int i; module_t* mod = (module_t*)mbi->mods_addr; starting_address = mod->mod_start; 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++; } } /* 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; ltr(KERNEL_TSS); } /* Initialize the PIC */ i8259_init(); /* Initialize devices, memory, filesystem, enable device interrupts on the * PIC, any other initialization stuff... */ initialize_paging(); /* initialize the RTC to 2Hz */ rtc_initialize(); /* initialize keyboard */ initialize_keyboard(); /* initialize function pointers */ func_init(); /* TESTING FILE SYSTEMS */ init_file_systems(starting_address); init_terminals(); //printf("Init File Systems Done\n"); //test_file_systems((uint8_t*)"frame0.txt"); //printf("Done testing\n"); /* FINISH FILE SYSTEMS TESTING */ /* 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 */ printf("Enabling Interrupts\n"); sti(); // testing for changing RTC freq /*int32_t * freq; int32_t temp = 1024; freq = &temp; rtc_write(freq, 4); int i; for(i = 0; i < 10; i ++) { rtc_read(); printf("testing"); } temp = 256; rtc_write(freq, 4); for (i = 0; i < 20; i++) { rtc_read(); printf("\n"); printf("second_test"); }*/ /*while(1) { asm volatile("int $0x28"); }*/ //int d = 6 / 0; /* Execute the first program (`shell') ... */ clear(); execute((uint8_t*)"shell"); /* Spin (nicely, so we don't chew up cycles) */ asm volatile(".1: hlt; jmp .1;"); }