Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- +----------------------------------------------------------+
- | +------------------------------------------------------+ |
- | | Quafios Kernel 1.0.1. | |
- | | -> Kernel code entry (i386). | |
- | +------------------------------------------------------+ |
- +----------------------------------------------------------+
- */
- // This file is part of Quafios 1.0.1 source code.
- // Copyright (C) 2012 Mostafa Abd El-Aziz Mohamed.
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with Quafios. If not, see <http://www.gnu.org/licenses/>.
- // Visit http://www.quafios.com/ for contact information.
- extern /* "C" */ void entry() __attribute__ ((section(".entry")));
- extern /* "C" */ void entry_error() __attribute__ ((section(".entry")));
- void entry_error(const char *vmsg) {
- unsigned int i = 0;
- unsigned char col = *((unsigned char *) 0x450);
- unsigned char row = *((unsigned char *) 0x451);
- unsigned int off = ((row*80)+col)*2;
- unsigned char *vga = (unsigned char *) 0xb8000;
- char *msg = (char *) kvirt_to_phy(vmsg);
- while (msg[i]) {
- vga[off++] = msg[i++];
- vga[off++] = 0x0C;
- }
- idle();
- }
- void entry() {
- // (I) Read Multiboot information:
- // ========================================
- // Multi-boot standard specs says that after kernel load,
- // EAX and EBX registers should contain "Boot magic
- // signature" and a pointer to "Boot info structures"
- // respectively.
- unsigned int boot_magic;
- multiboot_info_t *mbi;
- __asm__ ("":"=a"(boot_magic),"=b"(mbi));
- // Check if the boot magic signature is invalid:
- if (boot_magic != MULTIBOOT_BOOTLOADER_MAGIC)
- entry_error("Boot Error: Boot loader is not a multi-boot compliant loader.");
- // Get info about BIOS memory map from the boot info struct:
- if (!(mbi->flags & MULTIBOOT_INFO_MEM_MAP))
- entry_error("Boot Error: No memory map found.");
- unsigned int *map = (unsigned int *) kvirt_to_phy(&pmmap);
- linkedlist *flist = (linkedlist *) kvirt_to_phy(&pfreelist);
- // Read BIOS Memory Map, and set RAM Regions as free:
- unsigned int i = 0, j;
- linknode *prev = (linknode *) flist;
- while (i < (mbi->mmap_length)) {
- multiboot_memory_map_t *mbmm; // Entry.
- mbmm = (multiboot_memory_map_t *) (mbi->mmap_addr + i);
- unsigned int addr = mbmm->addr;
- unsigned int size = mbmm->len;
- if (mbmm->type == MULTIBOOT_MEMORY_AVAILABLE) {
- *kvirt_to_phy(&ram_size) = addr + size;
- // Align to 4KB Boundary:
- if (addr & 0xFFF) {
- size -= 0x1000-(addr&0xFFF);
- addr = (addr&0xFFFFF000) + 0x1000;
- }
- j = 0;
- while(j < size/PAGE_SIZE) {
- unsigned int frame = (addr>>12) + j++;
- unsigned int page = frame * PAGE_SIZE;
- // Don't mark these pages as free:
- // Lower Memory:
- if (page >= LOWER_MEMORY_BASE &&
- page < LOWER_MEMORY_SIZE) continue;
- // Kernel Space:
- if (page >= KERNEL_PHYSICAL_START &&
- page < KERNEL_PHYSICAL_END) continue;
- // add the page to free list :)
- linknode *entry = (linknode *) &map[frame];
- prev->next = (linknode *) kphy_to_virt(entry);
- prev = entry;
- flist->count++;
- }
- *kvirt_to_phy(&pmem_usable_pages) += j;
- }
- i += (mbmm->size) + sizeof(mbmm->size);
- }
- prev->next = NULLNODE;
- // (II) Initialize general page directory & page tables:
- // ======================================================
- unsigned int membase;
- // Kernel Memory Area Entries in general page table
- // (at 0xC0000000):
- for (i = 768; i < 1024; i++)
- kvirt_to_phy(general_pagedir)[i] = ((unsigned int)
- &kvirt_to_phy(kmem_pagetab)[(i-768)*1024]) | PAGE_ENTRY_KERNEL_MODE;
- // 1- Initialize kernel image page tables...
- membase = KERNEL_PHYSICAL_START;
- for (i = 0; membase < KERNEL_PHYSICAL_END; i++) {
- kvirt_to_phy(kmem_pagetab)[i] = membase | PAGE_ENTRY_KERNEL_MODE;
- membase += PAGE_SIZE;
- }
- // 2- Initialize lower memory image in kernel memory:
- membase = LOWER_MEMORY_BASE;
- for (; membase < LOWER_MEMORY_END; i++) {
- kvirt_to_phy(kmem_pagetab)[i] = membase | PAGE_ENTRY_KERNEL_MODE;
- membase += PAGE_SIZE;
- }
- // Temporarily map ".entry" section:
- kvirt_to_phy(general_pagedir)[0] = ((unsigned int)
- kvirt_to_phy(temp_pagetab)) |
- PAGE_ENTRY_KERNEL_MODE;
- kvirt_to_phy(temp_pagetab)[ENTRY_SECTION_START/PAGE_SIZE] =
- ENTRY_SECTION_START | PAGE_ENTRY_KERNEL_MODE;
- // (III) Enable Paging:
- // ======================
- // Setup CR3:
- set_cr3(kvirt_to_phy(general_pagedir));
- // Write-back and invalidate the cache:
- __asm__ ("wbinvd");
- // Enable Paging and Disable Caching:
- set_cr0(CR0_GENERIC);
- // (IV) Change Stack:
- // ====================
- __asm__ ("mov %%eax, %%esp"::"a"(&kernel_stack[KERNEL_STACK_SIZE]));
- // (V) Initialize kernel:
- // ==========================
- __asm__ ("call main");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement