CFLAGS = -g -Iinclude/arch/x86 -ffreestanding -DGIT_COMMIT=\"$(GIT_REV)\"
-KERNEL_OBJ = kernel/entry.o kernel/arch/x86/tty/tty.o kernel/drivers/irq/i8259a.o kernel/arch/x86/irq/idt.o kernel/arch/x86/irq/sample_handler.o kernel/arch/x86/mm/paging.o kernel/kernel.o
+KERNEL_OBJ = kernel/entry.o kernel/arch/x86/tty/tty.o kernel/drivers/irq/i8259a.o kernel/arch/x86/irq/idt.o kernel/arch/x86/irq/sample_handler.o kernel/kernel.o
BOOTLOADER_OBJ = boot/x86/mbr boot/x86/vbr-fat32 boot/x86/stage3/LOADER.BIN
mov ss, ax
mov fs, ax
mov gs, ax
- call 0x100000
+
+ call load_paging_structs
+ call enable_paging
+
+ call 0xc0000000
hlt
jmp $-1
space: db " ", 0
hex_delm: db "0x", 0
newline: db 0xd, 0xa, 0
+
+%include "paging.s"
--- /dev/null
+; Code for enabling paging before calling the kernel
+; Identity maps the VGA framebuffer memory and high-half maps the kernel memory
+bits 32
+
+section .text
+
+; The problem with this code is that it assumes that the kernel's various
+; sections occupy a certain number of pages. As of writing it is correct, but as
+; the kernel grows this code may fail to map those pages, which is not good. The
+; solution to this is to use ELF instead of a flat binary. This was not done
+; before because it would require paging, but now that paging works using ELF is
+; a possibility which must be exploited.
+
+enable_paging:
+ push eax
+ mov eax, cr0
+ or eax, 0x80000000
+ mov cr0, eax
+ pop eax
+ ret
+
+load_paging_structs:
+ push eax
+ push ebx
+ xor ebx, ebx
+.pt_low_loop:
+ mov eax, ebx
+ shl eax, 12
+ or eax, 1|2 ; P and R/W flags
+ mov [page_table_low+ebx*4], eax
+ inc ebx
+ cmp ebx, 0x100
+ jl .pt_low_loop
+
+ xor ebx, ebx
+.pt_high_ro_loop:
+ mov eax, ebx
+ add eax, 0x100
+ shl eax, 12
+ or eax, 1 ; P flag
+ mov [page_table_high+ebx*4], eax
+ inc ebx
+ cmp ebx, 0x2
+ jl .pt_high_ro_loop
+
+ mov ebx, 0x2
+.pt_high_rw_loop:
+ mov eax, ebx
+ add eax, 0x100
+ shl eax, 12
+ or eax, 1|2 ; P and R/W flags
+ mov [page_table_high+ebx*4], eax
+ inc ebx
+ cmp ebx, 0x9
+ jl .pt_high_rw_loop
+
+ mov eax, page_table_low
+ and eax, 0xfffff000
+ or eax, 1|2
+ mov [page_directory], eax
+
+ mov eax, page_table_high
+ and eax, 0xfffff000
+ or eax, 1|2
+ mov [page_directory+768*4], eax
+
+ mov eax, page_directory
+ mov cr3, eax
+ pop ebx
+ pop eax
+ ret
+
+section .data
+align 4096
+page_table_low:
+ times 1024 dd 0
+page_table_high:
+ times 1024 dd 0
+page_directory:
+ times 1024 dd 0
unsigned p: 1, wr: 1, us: 1, rsvd: 1, id: 1, pk: 1, ss: 1, hlat: 1, reserved: 7, sgx: 1, reserved2: 15;
} __attribute__((packed));
-extern inline void slice_linear_addr(void *address, short *pde, short *pte, short *offset);
-extern inline void enable_paging();
-
#endif
};
struct fault_frame {
- uint32_t error_code;
+ struct pf_errcode error_code;
uintptr_t eip;
uint16_t cs;
uint32_t eflags;
pic_send_eoi(1);
kprint("Got a keyboard interrupt!\n", 0);
inb(0x60);
+ int a = *(int *) (0xa0000000);
}
__attribute__((interrupt))
void pf_handler(struct fault_frame *frame)
{
- struct pf_errcode *errcode = &(frame->error_code);
+ int address;
+ struct pf_errcode errcode = frame->error_code;
+ asm ("mov %%cr2, %0": "=a" (address));
kprint("A page fault occurred!\n", VGA_COLOR_DARK_RED);
- if (errcode->p) {
- kprint("Attempted to access non-present page\n", 0);
+ kprint("Faulting address: ", 0);
+ kprintd(address);
+ kprint("\n", 0);
+ if (!errcode.p) {
+ kprint("Address points to non-mapped page\n", 0);
}
- if (errcode->wr) {
- kprint("Kernel attempted to write to page\n", 0);
- } else kprint("Kernel attempted to read from page\n", 0);
- if (errcode->id) {
+ if (errcode.wr) {
+ kprint("Fault occurred while writing to memory\n", 0);
+ } else {
+ kprint("Fault occurred while reading from memory\n", 0);
+ }
+ if (errcode.id) {
kprint("Fault occurred while fetching instruction\n", 0);
}
- int cr2;
- asm ("mov %%cr2, %0": "=a" (cr2));
- kprint("CR2: ", 0);
- kprintd(cr2);
+ asm("cli");
halt:
- asm ("cli; hlt");
+ asm("hlt");
goto halt;
}
+++ /dev/null
-#include <mm/paging.h>
-
-inline void slice_linear_addr(void *address, short *pde, short *pte, short *offset)
-{
- *pde = (int) address >> 22;
- *pte = ((int) address >> 12) & 0x3ff;
- *offset = (int) address & 0xfff;
-}
-
-inline void enable_paging(struct page_directory_entry page_dir)
-{
- asm ("mov %0, %%eax; mov %%eax, %%cr3; mov %%cr0, %%eax; or $0x80000000, %%eax; mov %%eax, %%cr0": : "m" (page_dir) : "eax" );
-}
static struct idt_descriptor idt[256] __attribute__((aligned(0x10)));
static struct idtr idtr __attribute__((aligned(0x10)));
-static struct page_directory_entry page_dir[1024] __attribute__((aligned(0x1000)));
-static struct page_table_entry page_table[1024] __attribute__((aligned(0x1000)));
void kmain(void)
{
screen_clear();
kprint("Welcome to Nameless OS!\nRunning revision: ", 0);
kprint(GIT_COMMIT, 0);
- kprint("\nEnabling paging...\n", 0);
- for (int i=0xb8; i < 0xc0; i++) {
- page_table[i].p = 1;
- page_table[i].rw = 0;
- page_table[i].us = 0;
- page_table[i].page_frame_addr = i;
- }
- for (int i=0x100; i < 0x102; i++) {
- page_table[i].p = 1;
- page_table[i].rw = 0;
- page_table[i].us = 0;
- page_table[i].page_frame_addr = i;
- }
- for (int i=0x102; i < 0x110; i++) {
- page_table[i].p = 1;
- page_table[i].rw = 1;
- page_table[i].us = 0;
- page_table[i].page_frame_addr = i;
- }
- page_dir[0].p = 1;
- page_dir[0].page_table_addr = (int) &page_table >> 12;
- enable_paging(page_dir);
+ kprint("\n", 0);
kprint("Preparing IDT...\n", 0);
idt_set_descriptor(idt, 8, 0x8, (uint32_t) double_fault, IDT_INTERRUPT_GATE, 0x0);
idt_set_descriptor(idt, 14, 0x8, (uint32_t) pf_handler, IDT_INTERRUPT_GATE, 0x0);
pic_unmask(1);
asm volatile ("sti");
kprint("All done\n", 0);
- struct idtr curr_idtr;
- asm ("sidt %0": "=m" (curr_idtr));
- kprintw(curr_idtr.limit);
- kprintd(curr_idtr.base);
- //kprint("Gonna force a double fault\n", 0);
- //int test = 1/0;
- //int test2 = *(int *) (0xa0000000);
while(1);
}
SECTIONS
{
- . = 0x100000;
+ . = 0xc0000000;
__KERNEL_BASE__ = .;
- .text : ALIGN(4K) {
+ .text : AT(ADDR(.text) - 0xbf000000) ALIGN(4K) {
__TEXT_BASE__ = .;
kernel/entry.o (.text)
*(.text)
__TEXT_END__ = .;
}
- .rodata : ALIGN(4K) {
+ .rodata : AT(ADDR(.rodata) - 0xbf000000) ALIGN(4K) {
__RODATA_BASE__ = .;
*(.rodata)
__RODATA_END__ = .;
* matter yet because we (currently) assume that the NX bit is not
* supported anyway. */
- .data : ALIGN(4K) {
+ .data : AT(ADDR(.data) - 0xbf000000) ALIGN(4K) {
__DATA_BASE__ = .;
*(.data)
__DATA_END__ = .;
}
- .bss : ALIGN(4K) {
+ .bss : AT(ADDR(.bss) - 0xbf000000) ALIGN(4K) {
__BSS_BASE__ = .;
*(.bss)
/* Reserving 16KiB for the stack. A __STACK_TOP__ is not really