physical memory management and started usermode
This commit is contained in:
parent
e1b6525a7e
commit
8b58e8663f
Binary file not shown.
1
Makefile
1
Makefile
|
@ -15,6 +15,7 @@ KERNELIMG := $(BUILDDIR)/kernel.bin
|
|||
|
||||
QEMUFLAGS = -d int -s \
|
||||
-kernel $(KERNELIMG) \
|
||||
-m 512M \
|
||||
-device piix3-ide,id=ide -drive id=disk,file=image.img,format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 \
|
||||
|
||||
.PHONY: all kernel qemu clean docs
|
||||
|
|
12
idt.c
12
idt.c
|
@ -1,4 +1,6 @@
|
|||
#include <idt.h>
|
||||
#include <vga.h>
|
||||
#include <printf.h>
|
||||
|
||||
void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes) {
|
||||
idt[i].offset_lo = (uint16_t)(offset & 0xFFFF);
|
||||
|
@ -7,3 +9,13 @@ void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t s
|
|||
idt[i].attributes = attributes;
|
||||
idt[i].offset_hi = (uint16_t)(offset >> 16);
|
||||
}
|
||||
|
||||
void exception_handler(struct registers regs) {
|
||||
clear_screen();
|
||||
|
||||
printf("Exception 0x%X (0x%X) has occurred\nEAX: 0x%08X\nECX: 0x%08X\nEDX: 0x%08X\nEBX: 0x%08X\nESI: 0x%08X\nEDI: 0x%08X\nEBP: 0x%08X\nESP: 0x%08X\n",
|
||||
regs.int_no, regs.err_code, regs.eax, regs.ecx, regs.edx, regs.ebx, regs.esi, regs.edi, regs.ebp, regs.esp+24);
|
||||
|
||||
printf("\nEIP: 0x%08X\nCS: 0x%08X\nEFLAGS: 0x%08X",
|
||||
regs.eip, regs.cs, regs.eflags);
|
||||
}
|
||||
|
|
34
include/fat12.h
Normal file
34
include/fat12.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef RK_FAT12_H_
|
||||
#define RK_FAT12_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct fat12_boot_sector {
|
||||
uint8_t jump_boot[3]; // Jump instruction to boot code
|
||||
uint8_t oem_name[8]; // OEM name and version
|
||||
uint16_t bytes_per_sector; // Bytes per sector
|
||||
uint8_t sectors_per_cluster; // Sectors per cluster
|
||||
uint16_t reserved_sectors; // Reserved sectors
|
||||
uint8_t num_fats; // Number of FATs
|
||||
uint16_t root_entry_count; // Number of root directory entries
|
||||
uint16_t total_sectors_16; // Total sectors (16-bit)
|
||||
uint8_t media; // Media descriptor
|
||||
uint16_t fat_size_16; // Sectors per FAT (16-bit)
|
||||
uint16_t sectors_per_track; // Sectors per track (for BIOS)
|
||||
uint16_t num_heads; // Number of heads (for BIOS)
|
||||
uint32_t hidden_sectors; // Hidden sectors
|
||||
uint32_t total_sectors_32; // Total sectors (32-bit)
|
||||
|
||||
// Extended Boot Record (EBR) fields
|
||||
uint8_t drive_number; // Drive number
|
||||
uint8_t reserved1; // Reserved
|
||||
uint8_t boot_signature; // Extended boot signature
|
||||
uint32_t volume_id; // Volume ID (serial number)
|
||||
uint8_t volume_label[11]; // Volume label
|
||||
uint8_t file_system_type[8]; // File system type (e.g., "FAT12 ")
|
||||
|
||||
uint8_t boot_code[448]; // Boot code
|
||||
uint16_t boot_sector_signature; // Boot sector signature (0xAA55)
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif
|
|
@ -1,9 +1,50 @@
|
|||
#ifndef RK_GDT_H_
|
||||
#define RK_GDT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GDT_NULL 0
|
||||
#define GDT_KERNEL_CODE 1
|
||||
#define GDT_KERNEL_DATA 2
|
||||
#define GDT_SEGMENT_SELECTOR(i, p) ((i << 3) | p)
|
||||
|
||||
struct gdt_entry {
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_middle;
|
||||
uint8_t access;
|
||||
uint8_t granularity;
|
||||
uint8_t base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tss_entry {
|
||||
uint32_t prev_tss; // The previous TSS - with hardware task switching this is used
|
||||
uint32_t esp0; // The stack pointer to load when we change to kernel mode
|
||||
uint32_t ss0; // The stack segment to load when we change to kernel mode
|
||||
uint32_t esp1; // Unused...
|
||||
uint32_t ss1;
|
||||
uint32_t esp2;
|
||||
uint32_t ss2;
|
||||
uint32_t cr3;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t es; // The value to load into ES when we change to kernel mode
|
||||
uint32_t cs; // The value to load into CS when we change to kernel mode
|
||||
uint32_t ss; // The value to load into SS when we change to kernel mode
|
||||
uint32_t ds; // The value to load into DS when we change to kernel mode
|
||||
uint32_t fs; // The value to load into FS when we change to kernel mode
|
||||
uint32_t gs; // The value to load into GS when we change to kernel mode
|
||||
uint32_t ldt; // Unused...
|
||||
uint16_t trap;
|
||||
uint16_t iomap_base;
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,17 @@ enum IDT_ATTRIBUTES {
|
|||
INT_PRESENT = 0x80,
|
||||
};
|
||||
|
||||
struct registers {
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
||||
uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */
|
||||
|
||||
uint32_t eip;
|
||||
uint32_t cs;
|
||||
uint32_t eflags;
|
||||
};
|
||||
|
||||
void encode_idt_entry(struct idt_entry idt[], int i, uint32_t offset, uint16_t segment_selector, uint8_t attributes);
|
||||
void flush_idt(uint32_t idt_pointer);
|
||||
void exception_handler(struct registers regs);
|
||||
|
||||
#endif
|
||||
|
|
22
include/kernel.h
Normal file
22
include/kernel.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef RK_KERNEL_H_
|
||||
#define RK_KERNEL_H_
|
||||
|
||||
#include <multiboot.h>
|
||||
#include <acpi.h>
|
||||
|
||||
struct kernel_context {
|
||||
struct rsdp *rsdp;
|
||||
struct xsdp *xsdp;
|
||||
|
||||
struct rsdt *rsdt;
|
||||
struct mcfg *mcfg;
|
||||
|
||||
uint32_t multi_mmap_size;
|
||||
struct multiboot_mmap_entry *multi_mmap;
|
||||
|
||||
uint32_t available_bytes;
|
||||
uint32_t mmap_size;
|
||||
uint32_t *mmap;
|
||||
};
|
||||
|
||||
#endif
|
20
include/mem.h
Normal file
20
include/mem.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef RK_MEM_H_
|
||||
#define RK_MEM_H_
|
||||
|
||||
#include <kernel.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define KERNEL_START 0x1000000 // 1 MiB
|
||||
#define KERNEL_SIZE 0xC800 // 50 KiB
|
||||
#define BLOCK_SIZE 4096
|
||||
#define BITS 32
|
||||
|
||||
uint8_t mmap_init(struct kernel_context *ctx);
|
||||
void mmap_set_block(struct kernel_context *ctx, int block);
|
||||
void mmap_free_block(struct kernel_context *ctx, int block);
|
||||
void *mmap_find_first_free_block(struct kernel_context *ctx);
|
||||
void *mmap_block_to_physical(struct kernel_context *ctx, int block);
|
||||
|
||||
void *memset(void *s, int c, uint32_t len);
|
||||
|
||||
#endif
|
|
@ -28,4 +28,19 @@ struct multiboot_info {
|
|||
uint32_t vbeInterfaceLength;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry
|
||||
{
|
||||
uint32_t size;
|
||||
uint32_t addr_low;
|
||||
uint32_t addr_high;
|
||||
uint32_t len_low;
|
||||
uint32_t len_high;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
uint32_t type;
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif
|
||||
|
|
111
kmain.c
111
kmain.c
|
@ -1,4 +1,4 @@
|
|||
#include "ide.h"
|
||||
#include <kernel.h>
|
||||
#include <multiboot.h>
|
||||
#include <acpi.h>
|
||||
#include <vga.h>
|
||||
|
@ -9,33 +9,112 @@
|
|||
#include <idt.h>
|
||||
#include <pic8259.h>
|
||||
#include <ps2.h>
|
||||
|
||||
struct kernel_context {
|
||||
struct rsdp *rsdp;
|
||||
struct xsdp *xsdp;
|
||||
|
||||
struct rsdt *rsdt;
|
||||
};
|
||||
#include <ide.h>
|
||||
#include <mem.h>
|
||||
#include <fat12.h>
|
||||
|
||||
struct kernel_context ctx = {0};
|
||||
|
||||
struct idt_entry g_idt[256] = {0};
|
||||
struct idtr g_idtr = {0};
|
||||
|
||||
extern void exception_handler();
|
||||
extern uint32_t isr_stub_table[32];
|
||||
extern void ps2_isr();
|
||||
|
||||
#define MAGIC_BREAKPOINT __asm__ volatile("xchgw %bx, %bx");
|
||||
|
||||
#define USER_DS 0x23 // User data segment selector
|
||||
#define USER_CS 0x1B // User code segment selector
|
||||
|
||||
extern struct gdt_entry gdt[6];
|
||||
struct tss_entry tss;
|
||||
|
||||
void tss_flush(uint16_t tss_selector) {
|
||||
asm volatile (
|
||||
"ltr %0"
|
||||
: // no output
|
||||
: "r" (tss_selector)
|
||||
);
|
||||
}
|
||||
|
||||
void test() {
|
||||
printf("\n\nHello from user mode!\n");
|
||||
for (;;) {}
|
||||
}
|
||||
|
||||
void switch_to_user_mode(void *user_stack, void *user_entry) {
|
||||
asm volatile (
|
||||
"movl $0x23, %%eax \n" // User data segment selector
|
||||
"mov %%ax, %%ds \n"
|
||||
"mov %%ax, %%es \n"
|
||||
"mov %%ax, %%fs \n"
|
||||
"mov %%ax, %%gs \n"
|
||||
|
||||
"pushl $0x23 \n" // User stack segment
|
||||
"pushl %0 \n" // User stack pointer
|
||||
"pushfl \n" // Push EFLAGS
|
||||
"popl %%eax \n"
|
||||
"orl $0x200, %%eax \n" // Enable interrupts (set IF)
|
||||
"pushl %%eax \n"
|
||||
|
||||
"pushl $0x1B \n" // User code segment
|
||||
"pushl %1 \n" // User entry point
|
||||
|
||||
"iret \n" // Interrupt return (switches to user mode)
|
||||
:
|
||||
: "r"(user_stack), "r"(user_entry)
|
||||
: "eax"
|
||||
);
|
||||
}
|
||||
|
||||
void write_tss(int num, uint16_t ss0, uint32_t esp0) {
|
||||
uint32_t base = (uint32_t)&tss;
|
||||
uint32_t limit = base + sizeof(tss);
|
||||
|
||||
gdt[num].base_low = base & 0xFFFF;
|
||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||||
gdt[num].limit_low = limit & 0xFFFF;
|
||||
gdt[num].granularity = (limit >> 16) & 0x0F;
|
||||
gdt[num].granularity |= 0x40;
|
||||
gdt[num].access = 0x89;
|
||||
|
||||
memset(&tss, 0, sizeof(tss));
|
||||
tss.ss0 = ss0;
|
||||
tss.esp0 = esp0;
|
||||
tss.cs = 0x0b;
|
||||
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13;
|
||||
}
|
||||
|
||||
void kmain(struct multiboot_info *info) {
|
||||
clear_screen();
|
||||
set_color(VGA_COLOR_CYAN);
|
||||
// Check if the bootloader gave us the upper and lower memory
|
||||
if (!(info->flags & 0x1)) goto halt;
|
||||
|
||||
ctx.multi_mmap = (struct multiboot_mmap_entry *)info->memMapAddress;
|
||||
ctx.multi_mmap_size = info->memMapLength / sizeof(struct multiboot_mmap_entry);
|
||||
|
||||
for (uint32_t i = 0; i < ctx.multi_mmap_size; i++) {
|
||||
struct multiboot_mmap_entry entry = ctx.multi_mmap[i];
|
||||
if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue;
|
||||
|
||||
uint32_t len = (uint32_t)(entry.len_low | entry.len_high);
|
||||
uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high);
|
||||
printf("Region #%d: 0x%08X-0x%08X\n", i, addr, addr+len);
|
||||
}
|
||||
|
||||
if (!mmap_init(&ctx)) {
|
||||
set_color(VGA_COLOR_RED);
|
||||
printf("Failed to create memory map\n");
|
||||
goto halt;
|
||||
}
|
||||
|
||||
printf("Detected %d bytes of memory\n", ctx.available_bytes);
|
||||
|
||||
// Create and load an IDT
|
||||
for (int i = 0; i < 32; i++) {
|
||||
encode_idt_entry(g_idt, i, (uint32_t)&exception_handler, GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||
encode_idt_entry(g_idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, 0x00), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||
}
|
||||
|
||||
g_idtr.size = (sizeof(struct idt_entry) * 256) - 1;
|
||||
|
@ -119,7 +198,17 @@ void kmain(struct multiboot_info *info) {
|
|||
}
|
||||
|
||||
set_color(VGA_COLOR_WHITE);
|
||||
printf("\nYou are now being dropped into a kernel shell\n$ ");
|
||||
|
||||
void *buf = mmap_find_first_free_block(&ctx);
|
||||
ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, (uint8_t *)buf);
|
||||
// struct fat12_boot_sector *boot_sect = (struct fat12_boot_sector *)buf;
|
||||
// int fat_size = boot_sect->total_sectors_16 * boot_sect->bytes_per_sector;
|
||||
|
||||
write_tss(5, 0x10, 0x0);
|
||||
tss_flush(0x2B);
|
||||
void *stack_bottom = mmap_find_first_free_block(&ctx);
|
||||
void *stack_top = stack_bottom + 4096;
|
||||
switch_to_user_mode(stack_top, buf);
|
||||
halt:
|
||||
for (;;) {}
|
||||
}
|
||||
|
|
121
mem.c
Normal file
121
mem.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include <mem.h>
|
||||
#include <printf.h>
|
||||
|
||||
// TODO: Fix this, it wastes memory when switching regions because the previous offset isnt being subtracted
|
||||
// Should work fine for now?
|
||||
void *mmap_block_to_physical(struct kernel_context *ctx, int block) {
|
||||
uint32_t offset = block * BLOCK_SIZE;
|
||||
|
||||
for (uint32_t i = 0; i < ctx->multi_mmap_size; i++) {
|
||||
struct multiboot_mmap_entry entry = ctx->multi_mmap[i];
|
||||
if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue;
|
||||
|
||||
uint32_t len = (uint32_t)(entry.len_low | entry.len_high);
|
||||
uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high);
|
||||
if (len > offset)
|
||||
return (void *)(addr + offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, uint32_t len) {
|
||||
unsigned char *dst = s;
|
||||
while (len > 0) {
|
||||
*dst = (unsigned char) c;
|
||||
dst++;
|
||||
len--;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
uint8_t mmap_init(struct kernel_context *ctx) {
|
||||
// Calculate the number of bytes available to us
|
||||
for (uint32_t i = 0; i < ctx->multi_mmap_size; i++) {
|
||||
struct multiboot_mmap_entry entry = ctx->multi_mmap[i];
|
||||
if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue;
|
||||
|
||||
uint32_t len = (uint32_t)(entry.len_low | entry.len_high);
|
||||
ctx->available_bytes += len;
|
||||
}
|
||||
|
||||
ctx->mmap_size = ctx->available_bytes / BLOCK_SIZE / 8;
|
||||
printf("Memory map size: %d bytes\n", ctx->mmap_size);
|
||||
|
||||
// Loop again to find the first region with enough space to hold the memory map
|
||||
int index = -1;
|
||||
for (uint32_t i = 0; i < ctx->multi_mmap_size; i++) {
|
||||
struct multiboot_mmap_entry entry = ctx->multi_mmap[i];
|
||||
if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue;
|
||||
|
||||
uint32_t len = (uint32_t)(entry.len_low | entry.len_high);
|
||||
if (len > ctx->mmap_size) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) return 0; // Failed
|
||||
|
||||
// Create map
|
||||
struct multiboot_mmap_entry entry = ctx->multi_mmap[index];
|
||||
uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high);
|
||||
ctx->mmap = (uint32_t *)addr;
|
||||
// Zero the map
|
||||
memset(ctx->mmap, 0, ctx->mmap_size);
|
||||
// Reserve the blocks that hold the memory map + 1
|
||||
uint32_t blocks_to_set = ctx->mmap_size / BLOCK_SIZE + 1;
|
||||
for (uint32_t i = 0; i < blocks_to_set; i++)
|
||||
mmap_set_block(ctx, i);
|
||||
// Reserve the kernel space
|
||||
int bits = ctx->mmap_size * 8;
|
||||
for (int i = 0; i < bits; i++) {
|
||||
uint32_t phys = (uint32_t)mmap_block_to_physical(ctx, i);
|
||||
if (phys > KERNEL_START && phys < KERNEL_START + KERNEL_SIZE)
|
||||
mmap_set_block(ctx, i);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mmap_set_block(struct kernel_context *ctx, int block) {
|
||||
int index = block / BITS;
|
||||
int bit = block;
|
||||
if (block >= BITS)
|
||||
bit -= BITS;
|
||||
|
||||
uint32_t mask = 1 << bit;
|
||||
if (!(ctx->mmap[index] & mask))
|
||||
ctx->mmap[index] |= mask;
|
||||
}
|
||||
|
||||
void mmap_free_block(struct kernel_context *ctx, int block) {
|
||||
int index = block / BITS;
|
||||
int bit = block;
|
||||
if (block >= BITS)
|
||||
bit -= BITS;
|
||||
|
||||
uint32_t mask = 1 << bit;
|
||||
if (ctx->mmap[index] & mask)
|
||||
ctx->mmap[index] ^= mask;
|
||||
}
|
||||
|
||||
void *mmap_find_first_free_block(struct kernel_context *ctx) {
|
||||
int bits = ctx->mmap_size * 8;
|
||||
for (int i = 0; i < bits; i++) {
|
||||
int index = i / BITS;
|
||||
int bit = i;
|
||||
if (i >= BITS)
|
||||
bit -= BITS;
|
||||
|
||||
uint32_t mask = 1 << bit;
|
||||
|
||||
uint32_t dword = ctx->mmap[index];
|
||||
if (!(dword & mask)) {
|
||||
return mmap_block_to_physical(ctx, i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
%define MAGIC 0x1BADB002
|
||||
%define FLAGS 0b100
|
||||
%define FLAGS 0b110
|
||||
|
||||
; Multiboot v1 Specification
|
||||
; https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
|
||||
|
@ -49,13 +49,74 @@ _start:
|
|||
halt:
|
||||
hlt
|
||||
jmp halt
|
||||
global exception_handler
|
||||
exception_handler:
|
||||
add esp, 4
|
||||
mov byte [0xb8000], 'X'
|
||||
iret
|
||||
|
||||
extern exception_handler
|
||||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
cli
|
||||
push %1
|
||||
pusha
|
||||
call exception_handler
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
||||
%endmacro
|
||||
%macro isr_no_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
cli
|
||||
push 0
|
||||
push %1
|
||||
pusha
|
||||
call exception_handler
|
||||
popa
|
||||
add esp, 12
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
isr_no_err_stub 0
|
||||
isr_no_err_stub 1
|
||||
isr_no_err_stub 2
|
||||
isr_no_err_stub 3
|
||||
isr_no_err_stub 4
|
||||
isr_no_err_stub 5
|
||||
isr_no_err_stub 6
|
||||
isr_no_err_stub 7
|
||||
isr_err_stub 8
|
||||
isr_no_err_stub 9
|
||||
isr_err_stub 10
|
||||
isr_err_stub 11
|
||||
isr_err_stub 12
|
||||
isr_err_stub 13
|
||||
isr_err_stub 14
|
||||
isr_no_err_stub 15
|
||||
isr_no_err_stub 16
|
||||
isr_err_stub 17
|
||||
isr_no_err_stub 18
|
||||
isr_no_err_stub 19
|
||||
isr_no_err_stub 20
|
||||
isr_no_err_stub 21
|
||||
isr_no_err_stub 22
|
||||
isr_no_err_stub 23
|
||||
isr_no_err_stub 24
|
||||
isr_no_err_stub 25
|
||||
isr_no_err_stub 26
|
||||
isr_no_err_stub 27
|
||||
isr_no_err_stub 28
|
||||
isr_no_err_stub 29
|
||||
isr_err_stub 30
|
||||
isr_no_err_stub 31
|
||||
|
||||
global isr_stub_table
|
||||
isr_stub_table:
|
||||
%assign i 0
|
||||
%rep 32
|
||||
dd isr_stub_%+i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
|
||||
global ps2_isr
|
||||
ps2_isr:
|
||||
cli
|
||||
extern ps2_handler
|
||||
pushad
|
||||
cld
|
||||
|
@ -66,7 +127,8 @@ ps2_isr:
|
|||
|
||||
; GDT for a flat memory layout
|
||||
; We get access to all memory and can utilize paging
|
||||
gdt_start:
|
||||
global gdt
|
||||
gdt:
|
||||
gdt_null:
|
||||
dq 0
|
||||
gdt_kern_code:
|
||||
|
@ -83,11 +145,27 @@ gdt_kern_data:
|
|||
db 0b10010010
|
||||
db 0b11001111
|
||||
db 0x00
|
||||
gdt_user_code:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
db 0b11111010
|
||||
db 0b11001111
|
||||
db 0x00
|
||||
gdt_user_data:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
db 0b11110010
|
||||
db 0b11001111
|
||||
db 0x00
|
||||
tss:
|
||||
dq 0
|
||||
gdt_end:
|
||||
|
||||
gdtp:
|
||||
dw gdt_end - gdt_start - 1
|
||||
dd gdt_start
|
||||
dw gdt_end - gdt - 1
|
||||
dd gdt
|
||||
|
||||
|
||||
; Reserve 16KiB of kernel stack space
|
||||
|
|
Loading…
Reference in New Issue
Block a user