fix idt and begin paging
This commit is contained in:
parent
ef1ee78320
commit
624ffbe738
8
Makefile
8
Makefile
|
@ -5,7 +5,7 @@ CC = x86_64-elf-gcc
|
|||
NASM = nasm
|
||||
|
||||
# User controllable CFLAGS.
|
||||
CFLAGS = -Wall -Wextra -O3 -pipe
|
||||
CFLAGS = -Wall -Wextra -O2 -pipe
|
||||
NASMFLAGS = -felf64
|
||||
|
||||
# Internal link flags that should not be changed by the user.
|
||||
|
@ -20,7 +20,7 @@ INTERNALLDFLAGS := \
|
|||
# Internal C flags that should not be changed by the user.
|
||||
INTERNALCFLAGS := \
|
||||
-Iinclude \
|
||||
-std=gnu11 \
|
||||
-std=gnu17 \
|
||||
-ffreestanding \
|
||||
-fno-stack-protector \
|
||||
-fno-pic -fpie \
|
||||
|
@ -40,7 +40,9 @@ OBJ += font.o
|
|||
.PHONY: all clean run
|
||||
|
||||
run: $(ISO)
|
||||
qemu-system-x86_64 -cdrom $(ISO) -serial file:serial.log -drive id=disk,file=build/disk.img,if=none,format=raw -device ide-hd,drive=disk,bus=ide.0
|
||||
qemu-system-x86_64 -cdrom $(ISO) -m 128M -serial file:serial.log \
|
||||
-drive id=disk,file=disk.img,if=none,format=raw \
|
||||
-device ide-hd,drive=disk,bus=ide.0
|
||||
|
||||
$(ISO): $(KERNEL)
|
||||
mkdir -p sysroot
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
.intel_syntax noprefix
|
||||
|
||||
.rodata
|
||||
gdt:
|
||||
.null:
|
||||
dq 0x0
|
||||
.code:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
db 10011010b
|
||||
db 11001111b
|
||||
db 0x00
|
||||
.data:
|
||||
dw 0xffff
|
||||
dw 0x0000
|
||||
db 0x00
|
||||
db 10010010b
|
||||
db 11001111b
|
||||
db 0x00
|
||||
.end:
|
||||
.descriptor:
|
||||
dw .end - gdt - 1
|
||||
dd gdt
|
||||
|
||||
.text
|
||||
.global gdt_load
|
||||
|
||||
gdt_load:
|
||||
push eax
|
||||
lgdt [gdt.descriptor]
|
||||
jmp 0x08:.loaded_cs
|
||||
.loaded_cs:
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
pop eax
|
||||
ret
|
|
@ -1,25 +0,0 @@
|
|||
#include <drivers/idt/idt.h>
|
||||
#include <drivers/terminal/terminal.h>
|
||||
|
||||
struct idt_entry idt[256];
|
||||
static unsigned long idt_address;
|
||||
static unsigned long idt_ptr[2];
|
||||
|
||||
void idt_init() {
|
||||
idt_address = (unsigned long)idt;
|
||||
idt_ptr[0] = (sizeof (struct idt_entry) * 256) + ((idt_address & 0xffff) << 16);
|
||||
idt_ptr[1] = idt_address >> 16;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"lidt %0\n\t"
|
||||
"sti\n\t" : : "m"(idt_ptr)
|
||||
);
|
||||
}
|
||||
|
||||
void idt_register_handler(uint8_t interrupt, unsigned long address) {
|
||||
idt[interrupt].offset_lowerbits = address & 0xffff;
|
||||
idt[interrupt].selector = KERNEL_CODE_SEGMENT_OFFSET;
|
||||
idt[interrupt].zero = 0;
|
||||
idt[interrupt].type_attr = INTERRUPT_GATE;
|
||||
idt[interrupt].offset_higherbits = (address & 0xffff0000) >> 16;
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
#include <drivers/idt/isr.h>
|
||||
#include <drivers/terminal/terminal.h>
|
||||
|
||||
__attribute__((interrupt)) static void isr0(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Division By Zero");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr1(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Debug");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr2(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Non Maskable Interrupt");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr3(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Breakpoint");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr4(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Into Detected Overflow");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr5(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Out of Bounds");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr6(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Invalid Opcode");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr7(struct interrupt_frame* frame) {
|
||||
terminal_writeline("No Coprocessor");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr8(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Double Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr9(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Coprocessor Segment Overrun");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr10(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Bad TSS");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr11(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Segment Not Present");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr12(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Stack Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr13(struct interrupt_frame* frame) {
|
||||
terminal_writeline("General Protection Fault");
|
||||
|
||||
terminal_writeline("heres some info:");
|
||||
|
||||
terminal_writestring("ip: ");
|
||||
terminal_writeline(itoa(frame->ip));
|
||||
terminal_writestring("sp: ");
|
||||
terminal_writeline(itoa(frame->sp));
|
||||
terminal_writestring("cs: ");
|
||||
terminal_writeline(itoa(frame->cs));
|
||||
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr14(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Page Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr15(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Unknown Interrupt");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr16(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Coprocessor Fault");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr17(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Alignment Check");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr18(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Machine Check");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr_reserved(struct interrupt_frame* frame) {
|
||||
terminal_writeline("Reserved");
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
void isr_install(void) {
|
||||
idt_register_handler(0, (unsigned long)isr0);
|
||||
idt_register_handler(1, (unsigned long)isr1);
|
||||
idt_register_handler(2, (unsigned long)isr2);
|
||||
idt_register_handler(3, (unsigned long)isr3);
|
||||
idt_register_handler(4, (unsigned long)isr4);
|
||||
idt_register_handler(5, (unsigned long)isr5);
|
||||
idt_register_handler(6, (unsigned long)isr6);
|
||||
idt_register_handler(7, (unsigned long)isr7);
|
||||
idt_register_handler(8, (unsigned long)isr8);
|
||||
idt_register_handler(9, (unsigned long)isr9);
|
||||
idt_register_handler(10, (unsigned long)isr10);
|
||||
idt_register_handler(11, (unsigned long)isr11);
|
||||
idt_register_handler(12, (unsigned long)isr12);
|
||||
idt_register_handler(13, (unsigned long)isr13);
|
||||
idt_register_handler(14, (unsigned long)isr14);
|
||||
idt_register_handler(15, (unsigned long)isr15);
|
||||
idt_register_handler(16, (unsigned long)isr16);
|
||||
idt_register_handler(17, (unsigned long)isr17);
|
||||
idt_register_handler(18, (unsigned long)isr18);
|
||||
idt_register_handler(19, (unsigned long)isr_reserved);
|
||||
idt_register_handler(20, (unsigned long)isr_reserved);
|
||||
idt_register_handler(21, (unsigned long)isr_reserved);
|
||||
idt_register_handler(22, (unsigned long)isr_reserved);
|
||||
idt_register_handler(23, (unsigned long)isr_reserved);
|
||||
idt_register_handler(24, (unsigned long)isr_reserved);
|
||||
idt_register_handler(25, (unsigned long)isr_reserved);
|
||||
idt_register_handler(26, (unsigned long)isr_reserved);
|
||||
idt_register_handler(27, (unsigned long)isr_reserved);
|
||||
idt_register_handler(28, (unsigned long)isr_reserved);
|
||||
idt_register_handler(29, (unsigned long)isr_reserved);
|
||||
idt_register_handler(30, (unsigned long)isr_reserved);
|
||||
idt_register_handler(31, (unsigned long)isr_reserved);
|
||||
|
||||
idt_init();
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
#include <framebuffer.h>
|
||||
#include <std/stdio.h>
|
||||
|
||||
void putpixel(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint32_t color) {
|
||||
void putpixel(framebuffer_t *framebuffer, u16 x, u16 y, u32 color) {
|
||||
if (color & 255 == 0) return;
|
||||
uint64_t where = x * framebuffer->pixelwidth + y * framebuffer->pitch;
|
||||
u64 where = x * framebuffer->pixelwidth + y * framebuffer->pitch;
|
||||
framebuffer->address[where] = (color >> 8) & 255; // BLUE
|
||||
framebuffer->address[where + 1] = (color >> 16) & 255; // GREEN
|
||||
framebuffer->address[where + 2] = (color >> 24) & 255; // RED
|
||||
}
|
||||
|
||||
void fillrect(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color) {
|
||||
void fillrect(framebuffer_t *framebuffer, u16 x, u16 y, u16 w, u16 h, u32 color) {
|
||||
if (color & 255 == 0) return;
|
||||
uint8_t* where;
|
||||
uint32_t pw = framebuffer->pixelwidth;
|
||||
for (uint16_t i = y; i < h + y; i++) {
|
||||
where = (uint8_t*)((uint64_t)framebuffer->address + framebuffer->pitch * i);
|
||||
for (uint16_t j = x; j < w + x; j++) {
|
||||
u8 *where;
|
||||
u32 pw = framebuffer->pixelwidth;
|
||||
for (u16 i = y; i < h + y; i++) {
|
||||
where = (u8*)((u64)framebuffer->address + framebuffer->pitch * i);
|
||||
for (u16 j = x; j < w + x; j++) {
|
||||
where[j * pw] = (color >> 8) & 255; // BLUE
|
||||
where[j * pw + 1] = (color >> 16) & 255; // GREEN
|
||||
where[j * pw + 2] = (color >> 24) & 255; // RED
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
// NOTE(hippoz): The function below is actually a joke. It's temporary. I'll
|
||||
// implement the timer soon.
|
||||
uint8_t sleep(int h) {
|
||||
u8 sleep(int h) {
|
||||
if (h != 1)
|
||||
return 1;
|
||||
for (unsigned long long i = 0; i < 99999999999; i++)
|
||||
|
@ -79,8 +79,7 @@ unsigned char ide_read(unsigned char channel, unsigned char reg) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void ide_read_buffer(unsigned char channel, unsigned char reg,
|
||||
unsigned int *buffer, unsigned int quads) {
|
||||
void ide_read_buffer(u8 channel, u8 reg, u32 *buffer, u32 quads) {
|
||||
/* WARNING: This code contains a serious bug. The inline assembly trashes ES
|
||||
* and ESP for all of the code the compiler generates between the inline
|
||||
* assembly blocks.
|
||||
|
@ -308,7 +307,7 @@ void ide_wait_irq() {
|
|||
}
|
||||
|
||||
unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
|
||||
unsigned int lba, uint8_t *buf) {
|
||||
unsigned int lba, u8 *buf) {
|
||||
unsigned char lba_mode /* 0: CHS, 1:LBA28, 2: LBA48 */,
|
||||
dma /* 0: No DMA, 1: DMA */, cmd;
|
||||
unsigned char lba_io[6];
|
||||
|
@ -450,7 +449,7 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
|
|||
return 0; // Easy, isn't it? no
|
||||
}
|
||||
|
||||
uint8_t ide_read_sectors(unsigned char drive, unsigned int lba, uint8_t *buf) {
|
||||
u8 ide_read_sectors(unsigned char drive, unsigned int lba, u8 *buf) {
|
||||
// Check if the drive is present:
|
||||
if (drive > 3 || ide_devices[drive].Reserved == 0)
|
||||
return 0x01; // Drive not present
|
||||
|
@ -470,7 +469,7 @@ uint8_t ide_read_sectors(unsigned char drive, unsigned int lba, uint8_t *buf) {
|
|||
return ide_print_error(drive, err);
|
||||
}
|
||||
|
||||
uint8_t ide_write_sectors(unsigned char drive, unsigned int lba, uint8_t *buf) {
|
||||
u8 ide_write_sectors(unsigned char drive, unsigned int lba, u8 *buf) {
|
||||
if (drive > 3 || ide_devices[drive].Reserved == 0)
|
||||
return 0x01; // Drive not present
|
||||
if (((lba + 1) > ide_devices[drive].Size) &&
|
||||
|
@ -494,7 +493,7 @@ void ide_init() {
|
|||
sleep(1);
|
||||
|
||||
printf("Testing IDE drive...\n");
|
||||
uint8_t buf[512] = {0};
|
||||
u8 buf[512] = {0};
|
||||
memcpy(buf, "Hello world", sizeof("Hello world"));
|
||||
ide_write_sectors(0, 1, buf);
|
||||
|
||||
|
@ -502,14 +501,14 @@ void ide_init() {
|
|||
sleep(1);
|
||||
sleep(1);
|
||||
|
||||
uint8_t outbuf[512] = {0};
|
||||
u8 outbuf[512] = {0};
|
||||
ide_read_sectors(0, 1, outbuf);
|
||||
|
||||
sleep(1);
|
||||
sleep(1);
|
||||
sleep(1);
|
||||
|
||||
for (uint8_t i = 0; i < 11; i++) {
|
||||
for (u8 i = 0; i < 11; i++) {
|
||||
printf("%d: %c | ", i, outbuf[i]);
|
||||
}
|
||||
printf("\n");
|
48
arch/x86_64/drivers/idt/idt.c
Normal file
48
arch/x86_64/drivers/idt/idt.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <drivers/idt/idt.h>
|
||||
#include <drivers/terminal/terminal.h>
|
||||
|
||||
__attribute__((aligned(0x10)))
|
||||
static idt_entry_t idt[256];
|
||||
|
||||
static idtr_t idtr;
|
||||
|
||||
void idt_init() {
|
||||
idtr.base = (uintptr_t)&idt[0];
|
||||
idtr.limit = (u16)sizeof(idt_entry_t) * 256 - 1;
|
||||
|
||||
asm volatile ("lidt %0" : : "memory"(idtr)); // load the new IDT
|
||||
asm volatile ("sti"); // set the interrupt flag
|
||||
}
|
||||
|
||||
void idt_set_entry(u8 vector, void* isr, u8 flags) {
|
||||
idt_entry_t* entry = &idt[vector];
|
||||
|
||||
entry->isr_low = (u64)isr & 0xFFFF;
|
||||
entry->kernel_cs = KERNEL_CODE_SEGMENT_OFFSET;
|
||||
entry->ist = 0;
|
||||
entry->attributes = flags;
|
||||
entry->isr_mid = ((u64)isr >> 16) & 0xFFFF;
|
||||
entry->isr_high = ((u64)isr >> 32) & 0xFFFFFFFF;
|
||||
entry->reserved = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void idt_init() {
|
||||
idt_address = (unsigned long)idt;
|
||||
idt_ptr[0] = (sizeof (struct idt_entry) * 256) + ((idt_address & 0xffff) << 16);
|
||||
idt_ptr[1] = idt_address >> 16;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"lidt %0\n\t"
|
||||
"sti\n\t" : : "m"(idt_ptr)
|
||||
);
|
||||
}
|
||||
|
||||
void idt_register_handler(u8 interrupt, unsigned long address) {
|
||||
idt[interrupt].offset_lowerbits = address & 0xffff;
|
||||
idt[interrupt].selector = KERNEL_CODE_SEGMENT_OFFSET;
|
||||
idt[interrupt].zero = 0;
|
||||
idt[interrupt].type_attr = INTERRUPT_GATE;
|
||||
idt[interrupt].offset_higherbits = (address & 0xffff0000) >> 16;
|
||||
}
|
||||
*/
|
124
arch/x86_64/drivers/idt/isr.c
Normal file
124
arch/x86_64/drivers/idt/isr.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
#include <drivers/idt/isr.h>
|
||||
#include <drivers/terminal/terminal.h>
|
||||
|
||||
inline isr_exception(interrupt_frame_t *frame, const char *error) {
|
||||
printf(error);
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr0(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Division By Zero");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr1(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Debug");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr2(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Non Maskable Interrupt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr3(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Breakpoint");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr4(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Into Detected Overflow");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr5(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Out of Bounds");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr6(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Invalid Opcode");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr7(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "No Coprocessor");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr8(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Double Fault");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr9(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Coprocessor Segment Overrun");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr10(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Bad TSS");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr11(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Segment Not Present");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr12(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Stack Fault");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr13(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "General Protection Fault");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr14(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Page Fault");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr15(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Unknown Interrupt");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr16(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Coprocessor Fault");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr17(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Alignment Check");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr18(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Machine Check");
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void isr_reserved(interrupt_frame_t *frame) {
|
||||
isr_exception(frame, "Reserved");
|
||||
}
|
||||
|
||||
void isr_install(void) {
|
||||
idt_set_entry(0, (void*)isr0, INTERRUPT_GATE);
|
||||
idt_set_entry(1, (void*)isr1, INTERRUPT_GATE);
|
||||
idt_set_entry(2, (void*)isr2, INTERRUPT_GATE);
|
||||
idt_set_entry(3, (void*)isr3, INTERRUPT_GATE);
|
||||
idt_set_entry(4, (void*)isr4, INTERRUPT_GATE);
|
||||
idt_set_entry(5, (void*)isr5, INTERRUPT_GATE);
|
||||
idt_set_entry(6, (void*)isr6, INTERRUPT_GATE);
|
||||
idt_set_entry(7, (void*)isr7, INTERRUPT_GATE);
|
||||
idt_set_entry(8, (void*)isr8, INTERRUPT_GATE);
|
||||
idt_set_entry(9, (void*)isr9, INTERRUPT_GATE);
|
||||
idt_set_entry(10, (void*)isr10, INTERRUPT_GATE);
|
||||
idt_set_entry(11, (void*)isr11, INTERRUPT_GATE);
|
||||
idt_set_entry(12, (void*)isr12, INTERRUPT_GATE);
|
||||
idt_set_entry(13, (void*)isr13, INTERRUPT_GATE);
|
||||
idt_set_entry(14, (void*)isr14, INTERRUPT_GATE);
|
||||
idt_set_entry(15, (void*)isr15, INTERRUPT_GATE);
|
||||
idt_set_entry(16, (void*)isr16, INTERRUPT_GATE);
|
||||
idt_set_entry(17, (void*)isr17, INTERRUPT_GATE);
|
||||
idt_set_entry(18, (void*)isr18, INTERRUPT_GATE);
|
||||
idt_set_entry(19, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(20, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(21, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(22, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(23, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(24, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(25, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(26, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(27, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(28, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(29, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(30, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
idt_set_entry(31, (void*)isr_reserved, INTERRUPT_GATE);
|
||||
|
||||
idt_init();
|
||||
}
|
|
@ -44,15 +44,15 @@ unsigned char kbdus[128] = {
|
|||
0, /* All other keys are undefined */
|
||||
};
|
||||
|
||||
uint8_t lastkey = 0;
|
||||
uint8_t __kbd_enabled = 0;
|
||||
u8 lastkey = 0;
|
||||
u8 __kbd_enabled = 0;
|
||||
|
||||
void keyboard_buffer_push_key(unsigned char scancode) {
|
||||
kbdbuf[lastkey++] = scancode;
|
||||
}
|
||||
|
||||
unsigned char keyboard_buffer_pop_key() {
|
||||
uint8_t index = lastkey--;
|
||||
u8 index = lastkey--;
|
||||
unsigned char scancode = kbdbuf[index];
|
||||
kbdbuf[index] = 0;
|
||||
return scancode;
|
||||
|
@ -62,7 +62,7 @@ unsigned char keyboard_get_key_from_scancode(unsigned char scancode) {
|
|||
return kbdus[scancode];
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) static void keyboard_irq(struct interrupt_frame* frame) {
|
||||
__attribute__((interrupt)) static void keyboard_irq(interrupt_frame_t *frame) {
|
||||
unsigned char scancode = inportb(0x60);
|
||||
|
||||
if (scancode & 128) {
|
||||
|
@ -75,7 +75,7 @@ __attribute__((interrupt)) static void keyboard_irq(struct interrupt_frame* fram
|
|||
pic_send_eoi(1);
|
||||
}
|
||||
|
||||
uint8_t keyboard_enabled(void) {
|
||||
u8 keyboard_enabled(void) {
|
||||
return __kbd_enabled;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ void* keyboard_write() {
|
|||
|
||||
int keyboard_init(void) {
|
||||
pic_irq_enable(1);
|
||||
idt_register_handler(33, (uint32_t)keyboard_irq);
|
||||
idt_set_entry(33, (void*)keyboard_irq, INTERRUPT_GATE);
|
||||
|
||||
__kbd_enabled = 1;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include <drivers/pic/pic.h>
|
||||
|
||||
static uint8_t pic1_mask = 0xff;
|
||||
static uint8_t pic2_mask = 0xff;
|
||||
static u8 pic1_mask = 0xff;
|
||||
static u8 pic2_mask = 0xff;
|
||||
|
||||
void pic_init() {
|
||||
outportb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
|
@ -25,14 +25,14 @@ void pic_init() {
|
|||
pic_irq_enable(2);
|
||||
}
|
||||
|
||||
void pic_send_eoi(uint8_t no) {
|
||||
void pic_send_eoi(u8 no) {
|
||||
if (no >= 8) {
|
||||
outportb(PIC2_COMMAND, PIC_EOI);
|
||||
}
|
||||
outportb(PIC1_COMMAND, PIC_EOI);
|
||||
}
|
||||
|
||||
void pic_irq_enable(uint8_t no) {
|
||||
void pic_irq_enable(u8 no) {
|
||||
if (no >= 8) {
|
||||
no -= 8;
|
||||
pic2_mask &= ~(1 << no);
|
||||
|
@ -43,7 +43,7 @@ void pic_irq_enable(uint8_t no) {
|
|||
}
|
||||
}
|
||||
|
||||
void pic_irq_disable(uint8_t no) {
|
||||
void pic_irq_disable(u8 no) {
|
||||
if (no >= 8) {
|
||||
no -= 8;
|
||||
pic2_mask |= (1 << no);
|
|
@ -1,13 +1,13 @@
|
|||
#include <psf.h>
|
||||
|
||||
// c is a unicode character, cx and cy are cursor position in characters
|
||||
void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t cy, uint32_t fg, uint32_t bg) {
|
||||
void draw_psf_char(framebuffer_t *framebuffer, u32 c, u16 cx, u16 cy, u32 fg, u32 bg) {
|
||||
PSF_font *font = (PSF_font*)&_binary_font_psfu_start;
|
||||
// we need to know how many bytes encode one row
|
||||
int bytesperline = (font->width + 7) / 8;
|
||||
// get the glyph for the character. If there's no
|
||||
// glyph for a given character, we'll display the first glyph.
|
||||
uint8_t *glyph = (uint8_t*)&_binary_font_psfu_start + font->headersize +
|
||||
u8 *glyph = (u8*)&_binary_font_psfu_start + font->headersize +
|
||||
(c > 0 && c < font->numglyph ? c : 0) * font->bytesperglyph;
|
||||
// calculate the upper left corner on screen where we want to display.
|
||||
// we only do this once, and adjust the whereet later. This is faster.
|
||||
|
@ -20,10 +20,10 @@ void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t
|
|||
mask = 1 << (font->width - 1);
|
||||
// display a row
|
||||
for (x = 0; x < font->width; x++) {
|
||||
*((uint32_t*)(framebuffer->address + line)) = *((uint32_t*)glyph) & mask ? fg : bg;
|
||||
*((u32*)(framebuffer->address + line)) = *((u32*)glyph) & mask ? fg : bg;
|
||||
// adjust to the next pixel
|
||||
mask >>= 1;
|
||||
line += 4;
|
||||
line += framebuffer->pixelwidth;
|
||||
}
|
||||
// adjust to the next line
|
||||
glyph += bytesperline;
|
|
@ -1,17 +1,16 @@
|
|||
#include <drivers/terminal/terminal.h>
|
||||
#include <drivers/device/device.h>
|
||||
|
||||
size_t terminal_row;
|
||||
size_t terminal_column;
|
||||
uint8_t terminal_color;
|
||||
uint16_t *terminal_buffer;
|
||||
usize terminal_row;
|
||||
usize terminal_column;
|
||||
u8 terminal_color;
|
||||
framebuffer_t *terminal_framebuffer;
|
||||
|
||||
void terminal_clear() {
|
||||
for (size_t y = 0; y < VGA_HEIGHT; y++) {
|
||||
for (size_t x = 0; x < VGA_WIDTH; x++) {
|
||||
const size_t index = y * VGA_WIDTH + x;
|
||||
terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||
for (usize y = 0; y < terminal_height; y++) {
|
||||
for (usize x = 0; x < terminal_width; x++) {
|
||||
const usize index = y * terminal_width + x;
|
||||
//terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +37,10 @@ void* terminal_devwrite(void* data) {
|
|||
|
||||
int terminal_initialize(framebuffer_t *terminal_fb) {
|
||||
terminal_framebuffer = terminal_fb;
|
||||
terminal_width = terminal_framebuffer->width / 8;
|
||||
terminal_height = terminal_framebuffer->height / 16;
|
||||
terminal_row = 0;
|
||||
terminal_column = 0;
|
||||
terminal_color = vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE);
|
||||
terminal_buffer = (uint16_t*) 0xB8000;
|
||||
terminal_clear();
|
||||
|
||||
struct device terminal_device = {
|
||||
|
@ -52,56 +51,45 @@ int terminal_initialize(framebuffer_t *terminal_fb) {
|
|||
return push_device(terminal_device);
|
||||
}
|
||||
|
||||
void terminal_setcolor(uint8_t color) {
|
||||
void terminal_setcolor(u8 color) {
|
||||
terminal_color = color;
|
||||
}
|
||||
|
||||
void terminal_clearline(size_t line) {
|
||||
for (size_t x = 0; x < VGA_WIDTH; x++) {
|
||||
const size_t index = line * VGA_WIDTH + x;
|
||||
terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||
void terminal_clearline(usize line) {
|
||||
for (usize x = 0; x < terminal_width; x++) {
|
||||
const usize index = line * terminal_width + x;
|
||||
//terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||
}
|
||||
}
|
||||
|
||||
void terminal_clearlines(size_t from, size_t to) {
|
||||
for (size_t y = from; y <= to; y++) {
|
||||
for (size_t x = 0; x < VGA_WIDTH; x++) {
|
||||
const size_t index = y * VGA_WIDTH + x;
|
||||
terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||
void terminal_clearlines(usize from, usize to) {
|
||||
for (usize y = from; y <= to; y++) {
|
||||
for (usize x = 0; x < terminal_width; x++) {
|
||||
const usize index = y * terminal_width + x;
|
||||
//terminal_buffer[index] = vga_entry(' ', terminal_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void terminal_updatecursor() {
|
||||
size_t temp = terminal_row * VGA_WIDTH + terminal_column;
|
||||
/*
|
||||
usize temp = terminal_row * terminal_width + terminal_column;
|
||||
outportb(0x3D4, 14);
|
||||
outportb(0x3D5, temp >> 8);
|
||||
outportb(0x3D4, 15);
|
||||
outportb(0x3D5, temp);
|
||||
}
|
||||
|
||||
void terminal_scrollup() {
|
||||
for (size_t index = 0; index < VGA_WIDTH * (VGA_HEIGHT - 1); index++) {
|
||||
terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH];
|
||||
}
|
||||
terminal_clearline(VGA_HEIGHT);
|
||||
if ((terminal_row - 1) < 0) {
|
||||
terminal_row = 0;
|
||||
terminal_column = 0;
|
||||
} else {
|
||||
terminal_row -= 1;
|
||||
}
|
||||
terminal_updatecursor();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void terminal_checknewline() {
|
||||
if (terminal_row >= VGA_HEIGHT - 1) {
|
||||
terminal_scrollup();
|
||||
if (terminal_row >= terminal_height - 1) {
|
||||
//terminal_scrollup();
|
||||
}
|
||||
}
|
||||
|
||||
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) {
|
||||
//terminal_buffer[y * VGA_WIDTH + x] = vga_entry(c, color);
|
||||
void terminal_putentryat(char c, u8 color, usize x, usize y) {
|
||||
//terminal_buffer[y * terminal_width + x] = vga_entry(c, color);
|
||||
draw_psf_char(terminal_framebuffer, c, x, y, 0xFFFFFFFF, 0);
|
||||
}
|
||||
|
||||
|
@ -111,7 +99,7 @@ void terminal_putchar(char c) {
|
|||
case '\b':
|
||||
if (--terminal_column < 0) {
|
||||
if (terminal_row-- > 0) {
|
||||
terminal_column = VGA_WIDTH - 1;
|
||||
terminal_column = terminal_width - 1;
|
||||
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
|
||||
}
|
||||
} else {
|
||||
|
@ -131,7 +119,7 @@ void terminal_putchar(char c) {
|
|||
terminal_column++;
|
||||
}
|
||||
|
||||
if (terminal_column >= VGA_WIDTH) {
|
||||
if (terminal_column >= terminal_width) {
|
||||
terminal_column = 0;
|
||||
terminal_row++;
|
||||
}
|
||||
|
@ -140,7 +128,7 @@ void terminal_putchar(char c) {
|
|||
terminal_checknewline();
|
||||
}
|
||||
|
||||
void terminal_write(const char* data, size_t size) {
|
||||
for (size_t i = 0; i < size; i++)
|
||||
void terminal_write(const char* data, usize size) {
|
||||
for (usize i = 0; i < size; i++)
|
||||
terminal_putchar(data[i]);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <types.h>
|
||||
|
||||
#include <stivale2.h>
|
||||
#include <std/inline.h>
|
||||
#include <std/util.h>
|
||||
|
@ -12,11 +12,9 @@
|
|||
#include <drivers/ide/ide.h>
|
||||
#include <framebuffer.h>
|
||||
#include <psf.h>
|
||||
#include <paging.h>
|
||||
|
||||
// We need to tell the stivale bootloader where we want our stack to be.
|
||||
// We are going to allocate our stack as an uninitialised array in .bss.
|
||||
static uint8_t stack[4096];
|
||||
void kmain();
|
||||
static u8 stack[16384];
|
||||
|
||||
bool is_running = true;
|
||||
int keyboard_descriptor = 0;
|
||||
|
@ -42,7 +40,7 @@ static struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = {
|
|||
.framebuffer_height = 600,
|
||||
.framebuffer_bpp = 32
|
||||
};
|
||||
|
||||
|
||||
// The stivale2 specification says we need to define a "header structure".
|
||||
// This structure needs to reside in the .stivale2hdr ELF section in order
|
||||
// for the bootloader to find it. We use this __attribute__ directive to
|
||||
|
@ -64,10 +62,8 @@ static struct stivale2_header stivale_hdr = {
|
|||
// points to the first one in the linked list.
|
||||
.tags = (uintptr_t)&framebuffer_hdr_tag
|
||||
};
|
||||
|
||||
// We will now write a helper function which will allow us to scan for tags
|
||||
// that we want FROM the bootloader (structure tags).
|
||||
void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) {
|
||||
|
||||
void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, u64 id) {
|
||||
struct stivale2_tag *current_tag = (void *)stivale2_struct->tags;
|
||||
for (;;) {
|
||||
// If the tag pointer is NULL (end of linked list), we did not find
|
||||
|
@ -89,39 +85,83 @@ void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) {
|
|||
|
||||
framebuffer_t *framebuffer;
|
||||
|
||||
// The following will be our kernel's entry point.
|
||||
extern usize _kernel_start;
|
||||
extern usize _kernel_end;
|
||||
|
||||
void _start(struct stivale2_struct *stivale2_struct) {
|
||||
struct stivale2_struct_tag_framebuffer *tagfb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID);
|
||||
struct stivale2_struct_tag_framebuffer *tag_fb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID);
|
||||
struct stivale2_struct_tag_memmap *tag_mmap = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_MEMMAP_ID);
|
||||
|
||||
if (tagfb == NULL) {
|
||||
if (tag_fb == NULL || tag_mmap == NULL) {
|
||||
printf("Requested stivale2 tags were not found, hanging...");
|
||||
for (;;) {
|
||||
asm ("hlt");
|
||||
}
|
||||
}
|
||||
framebuffer->address = (uint8_t*)tagfb->framebuffer_addr;
|
||||
framebuffer->width = tagfb->framebuffer_width;
|
||||
framebuffer->height = tagfb->framebuffer_height;
|
||||
framebuffer->depth = tagfb->framebuffer_bpp;
|
||||
framebuffer->pitch = tagfb->framebuffer_pitch;
|
||||
framebuffer->pixelwidth = tagfb->framebuffer_bpp / 8;
|
||||
|
||||
framebuffer->address = (u8*)tag_fb->framebuffer_addr;
|
||||
framebuffer->width = tag_fb->framebuffer_width;
|
||||
framebuffer->height = tag_fb->framebuffer_height;
|
||||
framebuffer->depth = tag_fb->framebuffer_bpp;
|
||||
framebuffer->pitch = tag_fb->framebuffer_pitch;
|
||||
framebuffer->pixelwidth = tag_fb->framebuffer_bpp / 8;
|
||||
|
||||
terminal_descriptor = terminal_initialize(framebuffer);
|
||||
printf("Terminal initialized, descriptor: %d\n", terminal_descriptor);
|
||||
|
||||
printf("Framebuffer | addr: %#X, width: %d, height: %d, depth: %d, pitch: %d\n", framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch, framebuffer->pixelwidth);
|
||||
|
||||
kmain();
|
||||
}
|
||||
printf("Framebuffer | addr: %#lX, width: %d, height: %d, depth: %d, pitch: %d\n", (usize)framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch);
|
||||
|
||||
void shell() {
|
||||
u64 total_memory = 0;
|
||||
for (u64 i = 0; i < tag_mmap->entries; i++) {
|
||||
struct stivale2_mmap_entry entry = tag_mmap->memmap[i];
|
||||
char *entry_name;
|
||||
switch (entry.type) {
|
||||
case STIVALE2_MMAP_USABLE: entry_name = "Usable"; break;
|
||||
case STIVALE2_MMAP_RESERVED: entry_name = "Reserved"; break;
|
||||
case STIVALE2_MMAP_ACPI_RECLAIMABLE: entry_name = "ACPI Reclaimable"; break;
|
||||
case STIVALE2_MMAP_ACPI_NVS: entry_name = "ACPI NVS"; break;
|
||||
case STIVALE2_MMAP_BAD_MEMORY: entry_name = "Bad Memory"; break;
|
||||
case STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE: entry_name = "Bootloader Reclaimable"; break;
|
||||
case STIVALE2_MMAP_KERNEL_AND_MODULES: entry_name = "Kernel and Modules"; break;
|
||||
case STIVALE2_MMAP_FRAMEBUFFER: entry_name = "Framebuffer"; break;
|
||||
default: entry_name = "Unknown";
|
||||
}
|
||||
total_memory += entry.length;
|
||||
printf("Memory map entry | name: %s, base: %#lX, length: %ld KiB\n", entry_name, entry.base, entry.length / 1024);
|
||||
}
|
||||
printf("Total memory: %ld KiB\n", total_memory / 1024);
|
||||
//printf("\"\"\"Used\"\"\" memory: %ld B\n", (_kernel_end - _kernel_start));
|
||||
|
||||
printf("Preparing interrupts... ");
|
||||
pic_init();
|
||||
isr_install();
|
||||
printf("done\n");
|
||||
/*
|
||||
printf("Preparing IDE driver... \n");
|
||||
printf("Searching for IDE devices... \n");
|
||||
ide_init();
|
||||
*/
|
||||
fillrect(framebuffer, 750, 550, 25, 25, 0x00FFD5FF);
|
||||
|
||||
keyboard_descriptor = keyboard_init();
|
||||
printf("Keyboard ready, descriptor: %d\n", keyboard_descriptor);
|
||||
|
||||
printf("Are interrupts enabled? ");
|
||||
if (are_interrupts_enabled() == 1) {
|
||||
printf("yes\n");
|
||||
} else {
|
||||
printf("no\n");
|
||||
}
|
||||
|
||||
printf("_start memory address: %#lX\n", (usize)_start);
|
||||
printf("----------\n");
|
||||
printf("hello yes");
|
||||
|
||||
while (is_running) {
|
||||
printf("\n> ");
|
||||
|
||||
while (true) {
|
||||
uint32_t scancode = (uint32_t)read(keyboard_descriptor, NULL);
|
||||
usize scancode = (usize)read(keyboard_descriptor, NULL);
|
||||
if (!scancode) continue;
|
||||
|
||||
bool special = true;
|
||||
|
@ -153,70 +193,3 @@ void shell() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern void load_page_directory(uint32_t);
|
||||
extern void enable_paging();
|
||||
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
uint32_t first_page_table[1024] __attribute__((aligned(4096)));
|
||||
uint32_t second_page_table[1024] __attribute__((aligned(4096)));
|
||||
|
||||
#define PAGE_PRESENT 1 << 0
|
||||
#define PAGE_WRITABLE 1 << 1
|
||||
#define PAGE_USER 1 << 2
|
||||
#define PAGE_WRITE_THROUGH 1 << 3
|
||||
#define PAGE_CACHE_DISABLE 1 << 4
|
||||
#define PAGE_ACCESSED 1 << 5
|
||||
#define PAGE_DIRTY 1 << 6
|
||||
#define PAGE_LARGE 1 << 7
|
||||
#define PAGE_GLOBAL 1 << 8
|
||||
/*
|
||||
void setup_paging() {
|
||||
// set each entry to not present
|
||||
for (uint32_t i = 0; i < 1024; i++) {
|
||||
page_directory[i] = 0;
|
||||
}
|
||||
|
||||
// i holds the physical address where we want to start mapping these pages to.
|
||||
// in this case, we want to map these pages to the very beginning of memory.
|
||||
// we will fill all 1024 entries in the table, mapping 4 megabytes
|
||||
for (uint32_t i = 0; i < 1024; i++) {
|
||||
first_page_table[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_WRITABLE;
|
||||
}
|
||||
|
||||
page_directory[0] = ((uint32_t)first_page_table) | PAGE_PRESENT | PAGE_WRITABLE;
|
||||
|
||||
load_page_directory((uint32_t)page_directory);
|
||||
enable_paging();
|
||||
}
|
||||
*/
|
||||
void kmain() {
|
||||
//setup_paging();
|
||||
|
||||
printf("Preparing interrupts... ");
|
||||
pic_init();
|
||||
isr_install();
|
||||
printf("done\n");
|
||||
|
||||
printf("Preparing IDE driver... \n");
|
||||
printf("Searching for IDE devices... \n");
|
||||
ide_init();
|
||||
|
||||
fillrect(framebuffer, 500, 200, 100, 100, 0x00FFD5FF);
|
||||
fillrect(framebuffer, 600, 300, 100, 100, 0xFF00D5FF);
|
||||
|
||||
keyboard_descriptor = keyboard_init();
|
||||
printf("Keyboard ready, descriptor: %d\n", keyboard_descriptor);
|
||||
|
||||
printf("Are interrupts enabled? ");
|
||||
if (are_interrupts_enabled() == 1) {
|
||||
printf("yes\n");
|
||||
} else {
|
||||
printf("no\n");
|
||||
}
|
||||
|
||||
printf("kmain memory address: %#X\n", (unsigned int)kmain);
|
||||
|
||||
printf("----------\n");
|
||||
shell();
|
||||
}
|
18
arch/x86_64/paging.c
Normal file
18
arch/x86_64/paging.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <paging.h>
|
||||
|
||||
// see amd64 architecture manual https://www.amd.com/system/files/TechDocs/24593.pdf
|
||||
// page 200 for more information
|
||||
|
||||
void map_page(u64 physical, u64 virtual) {
|
||||
address_t a;
|
||||
a.int_address = virtual;
|
||||
u64 *pdp = (PML4[a.parsed_address.pml4_offset] & PAGE_ADDRESS_MASK) >> 12;
|
||||
u64 *pd = (pdp[a.parsed_address.pdp_offset] & PAGE_ADDRESS_MASK) >> 12;
|
||||
u64 *pt = (pd[a.parsed_address.pd_offset] & PAGE_ADDRESS_MASK) >> 12;
|
||||
pt[a.parsed_address.pt_offset] = (physical & (PAGE_ADDRESS_MASK >> 12));
|
||||
}
|
||||
|
||||
void setup_paging(u64 total_memory) {
|
||||
page_bitmap->size = (total_memory / 4096 + 1) * 8;
|
||||
memset(page_bitmap->contents, 0, page_bitmap->size / 8);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#include <std/string.h>
|
||||
#include <std/ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// shamelessly stolen from https://wiki.osdev.org/User:A22347/Printf
|
||||
|
@ -253,7 +253,7 @@ int vprintf (const char* format, va_list list)
|
|||
}
|
||||
case 'z':
|
||||
{
|
||||
size_t integer = va_arg(list, size_t);
|
||||
usize integer = va_arg(list, usize);
|
||||
__int_str(integer, intStrBuffer, base, plusSign, spaceNoSign, lengthSpec, leftJustify, zeroPad);
|
||||
displayString(intStrBuffer, &chars);
|
||||
break;
|
||||
|
@ -319,7 +319,7 @@ int vprintf (const char* format, va_list list)
|
|||
}
|
||||
case 'z':
|
||||
{
|
||||
size_t integer = va_arg(list, size_t);
|
||||
usize integer = va_arg(list, usize);
|
||||
__int_str(integer, intStrBuffer, base, plusSign, spaceNoSign, lengthSpec, leftJustify, zeroPad);
|
||||
displayString(intStrBuffer, &chars);
|
||||
break;
|
||||
|
@ -380,7 +380,7 @@ int vprintf (const char* format, va_list list)
|
|||
*(va_arg(list, intmax_t*)) = chars;
|
||||
break;
|
||||
case 'z':
|
||||
*(va_arg(list, size_t*)) = chars;
|
||||
*(va_arg(list, usize*)) = chars;
|
||||
break;
|
||||
case 't':
|
||||
*(va_arg(list, ptrdiff_t*)) = chars;
|
|
@ -1,9 +1,9 @@
|
|||
#include <std/string.h>
|
||||
|
||||
int memcmp(const void* aptr, const void* bptr, size_t size) {
|
||||
int memcmp(const void* aptr, const void* bptr, usize size) {
|
||||
const unsigned char* a = (const unsigned char*) aptr;
|
||||
const unsigned char* b = (const unsigned char*) bptr;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
for (usize i = 0; i < size; i++) {
|
||||
if (a[i] < b[i])
|
||||
return -1;
|
||||
else if (b[i] < a[i])
|
||||
|
@ -12,36 +12,36 @@ int memcmp(const void* aptr, const void* bptr, size_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) {
|
||||
void* memcpy(void* restrict dstptr, const void* restrict srcptr, usize size) {
|
||||
unsigned char* dst = (unsigned char*) dstptr;
|
||||
const unsigned char* src = (const unsigned char*) srcptr;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
for (usize i = 0; i < size; i++)
|
||||
dst[i] = src[i];
|
||||
return dstptr;
|
||||
}
|
||||
|
||||
void* memmove(void* dstptr, const void* srcptr, size_t size) {
|
||||
void* memmove(void* dstptr, const void* srcptr, usize size) {
|
||||
unsigned char* dst = (unsigned char*) dstptr;
|
||||
const unsigned char* src = (const unsigned char*) srcptr;
|
||||
if (dst < src) {
|
||||
for (size_t i = 0; i < size; i++)
|
||||
for (usize i = 0; i < size; i++)
|
||||
dst[i] = src[i];
|
||||
} else {
|
||||
for (size_t i = size; i != 0; i--)
|
||||
for (usize i = size; i != 0; i--)
|
||||
dst[i-1] = src[i-1];
|
||||
}
|
||||
return dstptr;
|
||||
}
|
||||
|
||||
void* memset(void* bufptr, int value, size_t size) {
|
||||
void* memset(void* bufptr, int value, usize size) {
|
||||
unsigned char* buf = (unsigned char*) bufptr;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
for (usize i = 0; i < size; i++)
|
||||
buf[i] = (unsigned char) value;
|
||||
return bufptr;
|
||||
}
|
||||
|
||||
size_t strlen(const char* str) {
|
||||
size_t len = 0;
|
||||
usize strlen(const char* str) {
|
||||
usize len = 0;
|
||||
while (str[len])
|
||||
len++;
|
||||
return len;
|
|
@ -1,18 +1,13 @@
|
|||
#include <std/util.h>
|
||||
|
||||
void* malloc(size_t amount) {
|
||||
char variable[amount];
|
||||
return &variable;
|
||||
}
|
||||
|
||||
static size_t rand_next = 1;
|
||||
static usize rand_next = 1;
|
||||
|
||||
int rand(void) {
|
||||
rand_next = rand_next * 1103515245 + 12345;
|
||||
return (size_t)(rand_next/65536) % 32768;
|
||||
return (usize)(rand_next/65536) % 32768;
|
||||
}
|
||||
|
||||
void srand(size_t seed) {
|
||||
void srand(usize seed) {
|
||||
rand_next = seed;
|
||||
}
|
||||
|
||||
|
@ -47,4 +42,4 @@ unsigned int atoi(const char *in) {
|
|||
size += ((in[j - 1] - '0') * count);
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// AHCI driver, source: https://wiki.osdev.org/AHCI
|
||||
|
||||
// FIS = Frame Information Structure
|
||||
|
@ -23,51 +19,51 @@ typedef enum {
|
|||
|
||||
// ---- Various other FIS things (this struct was not found in OSDev wiki)
|
||||
typedef struct tagFIS_SET_DEVICE_BITS {
|
||||
uint8_t fis_type;
|
||||
uint8_t pmport:4;
|
||||
uint8_t rsvd:2;
|
||||
uint8_t i:1;
|
||||
uint8_t n:1;
|
||||
uint8_t statusl:3;
|
||||
uint8_t rsvd2:1;
|
||||
uint8_t statush:3;
|
||||
uint8_t rsvd3:1;
|
||||
uint8_t error;
|
||||
u8 fis_type;
|
||||
u8 pmport:4;
|
||||
u8 rsvd:2;
|
||||
u8 i:1;
|
||||
u8 n:1;
|
||||
u8 statusl:3;
|
||||
u8 rsvd2:1;
|
||||
u8 statush:3;
|
||||
u8 rsvd3:1;
|
||||
u8 error;
|
||||
} FIS_DEV_BITS;
|
||||
|
||||
// ---- Register FIS - Host to Device ----
|
||||
typedef struct tagFIS_REG_H2D
|
||||
{
|
||||
// DWORD 0
|
||||
uint8_t fis_type; // FIS_TYPE_REG_H2D
|
||||
u8 fis_type; // FIS_TYPE_REG_H2D
|
||||
|
||||
uint8_t pmport:4; // Port multiplier
|
||||
uint8_t rsv0:3; // Reserved
|
||||
uint8_t c:1; // 1: Command, 0: Control
|
||||
u8 pmport:4; // Port multiplier
|
||||
u8 rsv0:3; // Reserved
|
||||
u8 c:1; // 1: Command, 0: Control
|
||||
|
||||
uint8_t command; // Command register
|
||||
uint8_t featurel; // Feature register, 7:0
|
||||
u8 command; // Command register
|
||||
u8 featurel; // Feature register, 7:0
|
||||
|
||||
// DWORD 1
|
||||
uint8_t lba0; // LBA low register, 7:0
|
||||
uint8_t lba1; // LBA mid register, 15:8
|
||||
uint8_t lba2; // LBA high register, 23:16
|
||||
uint8_t device; // Device register
|
||||
u8 lba0; // LBA low register, 7:0
|
||||
u8 lba1; // LBA mid register, 15:8
|
||||
u8 lba2; // LBA high register, 23:16
|
||||
u8 device; // Device register
|
||||
|
||||
// DWORD 2
|
||||
uint8_t lba3; // LBA register, 31:24
|
||||
uint8_t lba4; // LBA register, 39:32
|
||||
uint8_t lba5; // LBA register, 47:40
|
||||
uint8_t featureh; // Feature register, 15:8
|
||||
u8 lba3; // LBA register, 31:24
|
||||
u8 lba4; // LBA register, 39:32
|
||||
u8 lba5; // LBA register, 47:40
|
||||
u8 featureh; // Feature register, 15:8
|
||||
|
||||
// DWORD 3
|
||||
uint8_t countl; // Count register, 7:0
|
||||
uint8_t counth; // Count register, 15:8
|
||||
uint8_t icc; // Isochronous command completion
|
||||
uint8_t control; // Control register
|
||||
u8 countl; // Count register, 7:0
|
||||
u8 counth; // Count register, 15:8
|
||||
u8 icc; // Isochronous command completion
|
||||
u8 control; // Control register
|
||||
|
||||
// DWORD 4
|
||||
uint8_t rsv1[4]; // Reserved
|
||||
u8 rsv1[4]; // Reserved
|
||||
} FIS_REG_H2D;
|
||||
|
||||
// ---- Register FIS – Device to Host ----
|
||||
|
@ -75,164 +71,164 @@ typedef struct tagFIS_REG_H2D
|
|||
typedef struct tagFIS_REG_D2H
|
||||
{
|
||||
// DWORD 0
|
||||
uint8_t fis_type; // FIS_TYPE_REG_D2H
|
||||
u8 fis_type; // FIS_TYPE_REG_D2H
|
||||
|
||||
uint8_t pmport:4; // Port multiplier
|
||||
uint8_t rsv0:2; // Reserved
|
||||
uint8_t i:1; // Interrupt bit
|
||||
uint8_t rsv1:1; // Reserved
|
||||
u8 pmport:4; // Port multiplier
|
||||
u8 rsv0:2; // Reserved
|
||||
u8 i:1; // Interrupt bit
|
||||
u8 rsv1:1; // Reserved
|
||||
|
||||
uint8_t status; // Status register
|
||||
uint8_t error; // Error register
|
||||
u8 status; // Status register
|
||||
u8 error; // Error register
|
||||
|
||||
// DWORD 1
|
||||
uint8_t lba0; // LBA low register, 7:0
|
||||
uint8_t lba1; // LBA mid register, 15:8
|
||||
uint8_t lba2; // LBA high register, 23:16
|
||||
uint8_t device; // Device register
|
||||
u8 lba0; // LBA low register, 7:0
|
||||
u8 lba1; // LBA mid register, 15:8
|
||||
u8 lba2; // LBA high register, 23:16
|
||||
u8 device; // Device register
|
||||
|
||||
// DWORD 2
|
||||
uint8_t lba3; // LBA register, 31:24
|
||||
uint8_t lba4; // LBA register, 39:32
|
||||
uint8_t lba5; // LBA register, 47:40
|
||||
uint8_t rsv2; // Reserved
|
||||
u8 lba3; // LBA register, 31:24
|
||||
u8 lba4; // LBA register, 39:32
|
||||
u8 lba5; // LBA register, 47:40
|
||||
u8 rsv2; // Reserved
|
||||
|
||||
// DWORD 3
|
||||
uint8_t countl; // Count register, 7:0
|
||||
uint8_t counth; // Count register, 15:8
|
||||
uint8_t rsv3[2]; // Reserved
|
||||
u8 countl; // Count register, 7:0
|
||||
u8 counth; // Count register, 15:8
|
||||
u8 rsv3[2]; // Reserved
|
||||
|
||||
// DWORD 4
|
||||
uint8_t rsv4[4]; // Reserved
|
||||
u8 rsv4[4]; // Reserved
|
||||
} FIS_REG_D2H;
|
||||
|
||||
// ---- Data FIS – Bidirectional ----
|
||||
// This FIS is used by the host or device to send data payload. The data size can be varied.
|
||||
typedef struct tagFIS_DATA {
|
||||
// DWORD 0
|
||||
uint8_t fis_type; // FIS_TYPE_DATA
|
||||
u8 fis_type; // FIS_TYPE_DATA
|
||||
|
||||
uint8_t pmport:4; // Port multiplier
|
||||
uint8_t rsv0:4; // Reserved
|
||||
u8 pmport:4; // Port multiplier
|
||||
u8 rsv0:4; // Reserved
|
||||
|
||||
uint8_t rsv1[2]; // Reserved
|
||||
u8 rsv1[2]; // Reserved
|
||||
|
||||
// DWORD 1 ~ N
|
||||
uint32_t data[1]; // Payload
|
||||
u32 data[1]; // Payload
|
||||
} FIS_DATA;
|
||||
|
||||
// ---- PIO Setup – Device to Host ----
|
||||
// This FIS is used by the device to tell the host that it’s about to send or ready to receive a PIO data payload.
|
||||
typedef struct tagFIS_PIO_SETUP {
|
||||
// DWORD 0
|
||||
uint8_t fis_type; // FIS_TYPE_PIO_SETUP
|
||||
u8 fis_type; // FIS_TYPE_PIO_SETUP
|
||||
|
||||
uint8_t pmport:4; // Port multiplier
|
||||
uint8_t rsv0:1; // Reserved
|
||||
uint8_t d:1; // Data transfer direction, 1 - device to host
|
||||
uint8_t i:1; // Interrupt bit
|
||||
uint8_t rsv1:1;
|
||||
u8 pmport:4; // Port multiplier
|
||||
u8 rsv0:1; // Reserved
|
||||
u8 d:1; // Data transfer direction, 1 - device to host
|
||||
u8 i:1; // Interrupt bit
|
||||
u8 rsv1:1;
|
||||
|
||||
uint8_t status; // Status register
|
||||
uint8_t error; // Error register
|
||||
u8 status; // Status register
|
||||
u8 error; // Error register
|
||||
|
||||
// DWORD 1
|
||||
uint8_t lba0; // LBA low register, 7:0
|
||||
uint8_t lba1; // LBA mid register, 15:8
|
||||
uint8_t lba2; // LBA high register, 23:16
|
||||
uint8_t device; // Device register
|
||||
u8 lba0; // LBA low register, 7:0
|
||||
u8 lba1; // LBA mid register, 15:8
|
||||
u8 lba2; // LBA high register, 23:16
|
||||
u8 device; // Device register
|
||||
|
||||
// DWORD 2
|
||||
uint8_t lba3; // LBA register, 31:24
|
||||
uint8_t lba4; // LBA register, 39:32
|
||||
uint8_t lba5; // LBA register, 47:40
|
||||
uint8_t rsv2; // Reserved
|
||||
u8 lba3; // LBA register, 31:24
|
||||
u8 lba4; // LBA register, 39:32
|
||||
u8 lba5; // LBA register, 47:40
|
||||
u8 rsv2; // Reserved
|
||||
|
||||
// DWORD 3
|
||||
uint8_t countl; // Count register, 7:0
|
||||
uint8_t counth; // Count register, 15:8
|
||||
uint8_t rsv3; // Reserved
|
||||
uint8_t e_status; // New value of status register
|
||||
u8 countl; // Count register, 7:0
|
||||
u8 counth; // Count register, 15:8
|
||||
u8 rsv3; // Reserved
|
||||
u8 e_status; // New value of status register
|
||||
|
||||
// DWORD 4
|
||||
uint16_t tc; // Transfer count
|
||||
uint8_t rsv4[2]; // Reserved
|
||||
u16 tc; // Transfer count
|
||||
u8 rsv4[2]; // Reserved
|
||||
} FIS_PIO_SETUP;
|
||||
|
||||
// ---- DMA Setup – Device to Host ----
|
||||
typedef struct tagFIS_DMA_SETUP {
|
||||
// DWORD 0
|
||||
uint8_t fis_type; // FIS_TYPE_DMA_SETUP
|
||||
u8 fis_type; // FIS_TYPE_DMA_SETUP
|
||||
|
||||
uint8_t pmport:4; // Port multiplier
|
||||
uint8_t rsv0:1; // Reserved
|
||||
uint8_t d:1; // Data transfer direction, 1 - device to host
|
||||
uint8_t i:1; // Interrupt bit
|
||||
uint8_t a:1; // Auto-activate. Specifies if DMA Activate FIS is needed
|
||||
u8 pmport:4; // Port multiplier
|
||||
u8 rsv0:1; // Reserved
|
||||
u8 d:1; // Data transfer direction, 1 - device to host
|
||||
u8 i:1; // Interrupt bit
|
||||
u8 a:1; // Auto-activate. Specifies if DMA Activate FIS is needed
|
||||
|
||||
uint8_t rsved[2]; // Reserved
|
||||
u8 rsved[2]; // Reserved
|
||||
|
||||
//DWORD 1&2
|
||||
|
||||
uint64_t DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.
|
||||
u64 DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.
|
||||
|
||||
//DWORD 3
|
||||
uint32_t rsvd; //More reserved
|
||||
u32 rsvd; //More reserved
|
||||
|
||||
//DWORD 4
|
||||
uint32_t DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0
|
||||
u32 DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0
|
||||
|
||||
//DWORD 5
|
||||
uint32_t TransferCount; //Number of bytes to transfer. Bit 0 must be 0
|
||||
u32 TransferCount; //Number of bytes to transfer. Bit 0 must be 0
|
||||
|
||||
//DWORD 6
|
||||
uint32_t resvd; //Reserved
|
||||
u32 resvd; //Reserved
|
||||
|
||||
} FIS_DMA_SETUP;
|
||||
|
||||
|
||||
// ---- Memory structs (HBA memory registers) ----
|
||||
typedef volatile struct tagHBA_PORT {
|
||||
uint32_t clb; // 0x00, command list base address, 1K-byte aligned
|
||||
uint32_t clbu; // 0x04, command list base address upper 32 bits
|
||||
uint32_t fb; // 0x08, FIS base address, 256-byte aligned
|
||||
uint32_t fbu; // 0x0C, FIS base address upper 32 bits
|
||||
uint32_t is; // 0x10, interrupt status
|
||||
uint32_t ie; // 0x14, interrupt enable
|
||||
uint32_t cmd; // 0x18, command and status
|
||||
uint32_t rsv0; // 0x1C, Reserved
|
||||
uint32_t tfd; // 0x20, task file data
|
||||
uint32_t sig; // 0x24, signature
|
||||
uint32_t ssts; // 0x28, SATA status (SCR0:SStatus)
|
||||
uint32_t sctl; // 0x2C, SATA control (SCR2:SControl)
|
||||
uint32_t serr; // 0x30, SATA error (SCR1:SError)
|
||||
uint32_t sact; // 0x34, SATA active (SCR3:SActive)
|
||||
uint32_t ci; // 0x38, command issue
|
||||
uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification)
|
||||
uint32_t fbs; // 0x40, FIS-based switch control
|
||||
uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved
|
||||
uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific
|
||||
u32 clb; // 0x00, command list base address, 1K-byte aligned
|
||||
u32 clbu; // 0x04, command list base address upper 32 bits
|
||||
u32 fb; // 0x08, FIS base address, 256-byte aligned
|
||||
u32 fbu; // 0x0C, FIS base address upper 32 bits
|
||||
u32 is; // 0x10, interrupt status
|
||||
u32 ie; // 0x14, interrupt enable
|
||||
u32 cmd; // 0x18, command and status
|
||||
u32 rsv0; // 0x1C, Reserved
|
||||
u32 tfd; // 0x20, task file data
|
||||
u32 sig; // 0x24, signature
|
||||
u32 ssts; // 0x28, SATA status (SCR0:SStatus)
|
||||
u32 sctl; // 0x2C, SATA control (SCR2:SControl)
|
||||
u32 serr; // 0x30, SATA error (SCR1:SError)
|
||||
u32 sact; // 0x34, SATA active (SCR3:SActive)
|
||||
u32 ci; // 0x38, command issue
|
||||
u32 sntf; // 0x3C, SATA notification (SCR4:SNotification)
|
||||
u32 fbs; // 0x40, FIS-based switch control
|
||||
u32 rsv1[11]; // 0x44 ~ 0x6F, Reserved
|
||||
u32 vendor[4]; // 0x70 ~ 0x7F, vendor specific
|
||||
} HBA_PORT;
|
||||
|
||||
typedef volatile struct tagHBA_MEM {
|
||||
// 0x00 - 0x2B, Generic Host Control
|
||||
uint32_t cap; // 0x00, Host capability
|
||||
uint32_t ghc; // 0x04, Global host control
|
||||
uint32_t is; // 0x08, Interrupt status
|
||||
uint32_t pi; // 0x0C, Port implemented
|
||||
uint32_t vs; // 0x10, Version
|
||||
uint32_t ccc_ctl; // 0x14, Command completion coalescing control
|
||||
uint32_t ccc_pts; // 0x18, Command completion coalescing ports
|
||||
uint32_t em_loc; // 0x1C, Enclosure management location
|
||||
uint32_t em_ctl; // 0x20, Enclosure management control
|
||||
uint32_t cap2; // 0x24, Host capabilities extended
|
||||
uint32_t bohc; // 0x28, BIOS/OS handoff control and status
|
||||
u32 cap; // 0x00, Host capability
|
||||
u32 ghc; // 0x04, Global host control
|
||||
u32 is; // 0x08, Interrupt status
|
||||
u32 pi; // 0x0C, Port implemented
|
||||
u32 vs; // 0x10, Version
|
||||
u32 ccc_ctl; // 0x14, Command completion coalescing control
|
||||
u32 ccc_pts; // 0x18, Command completion coalescing ports
|
||||
u32 em_loc; // 0x1C, Enclosure management location
|
||||
u32 em_ctl; // 0x20, Enclosure management control
|
||||
u32 cap2; // 0x24, Host capabilities extended
|
||||
u32 bohc; // 0x28, BIOS/OS handoff control and status
|
||||
|
||||
// 0x2C - 0x9F, Reserved
|
||||
uint8_t rsv[0xA0-0x2C];
|
||||
u8 rsv[0xA0-0x2C];
|
||||
|
||||
// 0xA0 - 0xFF, Vendor specific registers
|
||||
uint8_t vendor[0x100-0xA0];
|
||||
u8 vendor[0x100-0xA0];
|
||||
|
||||
// 0x100 - 0x10FF, Port control registers
|
||||
HBA_PORT ports[1]; // 1 ~ 32
|
||||
|
@ -242,75 +238,75 @@ typedef volatile struct tagHBA_MEM {
|
|||
typedef volatile struct tagHBA_FIS {
|
||||
// 0x00
|
||||
FIS_DMA_SETUP dsfis; // DMA Setup FIS
|
||||
uint8_t pad0[4];
|
||||
u8 pad0[4];
|
||||
|
||||
// 0x20
|
||||
FIS_PIO_SETUP psfis; // PIO Setup FIS
|
||||
uint8_t pad1[12];
|
||||
u8 pad1[12];
|
||||
|
||||
// 0x40
|
||||
FIS_REG_D2H rfis; // Register – Device to Host FIS
|
||||
uint8_t pad2[4];
|
||||
u8 pad2[4];
|
||||
|
||||
// 0x58
|
||||
FIS_DEV_BITS sdbfis; // Set Device Bit FIS
|
||||
|
||||
// 0x60
|
||||
uint8_t ufis[64];
|
||||
u8 ufis[64];
|
||||
|
||||
// 0xA0
|
||||
uint8_t rsv[0x100-0xA0];
|
||||
u8 rsv[0x100-0xA0];
|
||||
} HBA_FIS;
|
||||
|
||||
// ---- Command List ----
|
||||
typedef struct tagHBA_CMD_HEADER {
|
||||
// DW0
|
||||
uint8_t cfl:5; // Command FIS length in DWORDS, 2 ~ 16
|
||||
uint8_t a:1; // ATAPI
|
||||
uint8_t w:1; // Write, 1: H2D, 0: D2H
|
||||
uint8_t p:1; // Prefetchable
|
||||
u8 cfl:5; // Command FIS length in DWORDS, 2 ~ 16
|
||||
u8 a:1; // ATAPI
|
||||
u8 w:1; // Write, 1: H2D, 0: D2H
|
||||
u8 p:1; // Prefetchable
|
||||
|
||||
uint8_t r:1; // Reset
|
||||
uint8_t b:1; // BIST
|
||||
uint8_t c:1; // Clear busy upon R_OK
|
||||
uint8_t rsv0:1; // Reserved
|
||||
uint8_t pmp:4; // Port multiplier port
|
||||
u8 r:1; // Reset
|
||||
u8 b:1; // BIST
|
||||
u8 c:1; // Clear busy upon R_OK
|
||||
u8 rsv0:1; // Reserved
|
||||
u8 pmp:4; // Port multiplier port
|
||||
|
||||
uint16_t prdtl; // Physical region descriptor table length in entries
|
||||
u16 prdtl; // Physical region descriptor table length in entries
|
||||
|
||||
// DW1
|
||||
volatile
|
||||
uint32_t prdbc; // Physical region descriptor byte count transferred
|
||||
u32 prdbc; // Physical region descriptor byte count transferred
|
||||
|
||||
// DW2, 3
|
||||
uint32_t ctba; // Command table descriptor base address
|
||||
uint32_t ctbau; // Command table descriptor base address upper 32 bits
|
||||
u32 ctba; // Command table descriptor base address
|
||||
u32 ctbau; // Command table descriptor base address upper 32 bits
|
||||
|
||||
// DW4 - 7
|
||||
uint32_t rsv1[4]; // Reserved
|
||||
u32 rsv1[4]; // Reserved
|
||||
} HBA_CMD_HEADER;
|
||||
|
||||
// ---- Command Table and Physical Region Descriptor Table ----
|
||||
typedef struct tagHBA_PRDT_ENTRY {
|
||||
uint32_t dba; // Data base address
|
||||
uint32_t dbau; // Data base address upper 32 bits
|
||||
uint32_t rsv0; // Reserved
|
||||
u32 dba; // Data base address
|
||||
u32 dbau; // Data base address upper 32 bits
|
||||
u32 rsv0; // Reserved
|
||||
|
||||
// DW3
|
||||
uint32_t dbc:22; // Byte count, 4M max
|
||||
uint32_t rsv1:9; // Reserved
|
||||
uint32_t i:1; // Interrupt on completion
|
||||
u32 dbc:22; // Byte count, 4M max
|
||||
u32 rsv1:9; // Reserved
|
||||
u32 i:1; // Interrupt on completion
|
||||
} HBA_PRDT_ENTRY;
|
||||
|
||||
typedef struct tagHBA_CMD_TBL {
|
||||
// 0x00
|
||||
uint8_t cfis[64]; // Command FIS
|
||||
u8 cfis[64]; // Command FIS
|
||||
|
||||
// 0x40
|
||||
uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes
|
||||
u8 acmd[16]; // ATAPI command, 12 or 16 bytes
|
||||
|
||||
// 0x50
|
||||
uint8_t rsv[48]; // Reserved
|
||||
u8 rsv[48]; // Reserved
|
||||
|
||||
// 0x80
|
||||
HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
|
||||
|
@ -345,7 +341,3 @@ typedef struct tagHBA_CMD_TBL {
|
|||
// ---- Functions ----
|
||||
|
||||
void ahci_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct device {
|
||||
void* (*write)(void* data);
|
||||
void* (*read)(void* data);
|
||||
|
@ -13,7 +9,3 @@ int push_device(struct device device);
|
|||
|
||||
void* read(int descriptor, void* data);
|
||||
void* write(int descriptor, void* data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <types.h>
|
||||
|
||||
// ----> IDE Driver
|
||||
// Source: https://wiki.osdev.org/PCI_IDE_Controller
|
||||
|
@ -103,8 +99,4 @@ extern "C" {
|
|||
// ---- Functions -----
|
||||
|
||||
void ide_init();
|
||||
uint8_t ide_write_sectors(unsigned char drive, unsigned int lba, uint8_t *buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
u8 ide_write_sectors(unsigned char drive, unsigned int lba, u8 *buf);
|
||||
|
|
|
@ -1,34 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include <std/util.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define KERNEL_CODE_SEGMENT_OFFSET 0x08
|
||||
#define KERNEL_CODE_SEGMENT_OFFSET 40
|
||||
#define INTERRUPT_GATE 0x8e
|
||||
|
||||
struct idt_entry {
|
||||
unsigned short int offset_lowerbits;
|
||||
unsigned short int selector;
|
||||
unsigned char zero;
|
||||
unsigned char type_attr;
|
||||
unsigned short int offset_higherbits;
|
||||
};
|
||||
typedef struct {
|
||||
u16 isr_low; // The lower 16 bits of the ISR's address
|
||||
u16 kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||
u8 ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
||||
u8 attributes; // Type and attributes; see the IDT page
|
||||
u16 isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
||||
u32 isr_high; // The higher 32 bits of the ISR's address
|
||||
u32 reserved; // Set to zero
|
||||
} __attribute__((packed)) idt_entry_t;
|
||||
|
||||
struct interrupt_frame {
|
||||
typedef struct {
|
||||
u16 limit;
|
||||
u64 base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
typedef struct {
|
||||
uintptr_t ip;
|
||||
uintptr_t cs;
|
||||
uintptr_t flags;
|
||||
uintptr_t sp;
|
||||
uintptr_t ss;
|
||||
};
|
||||
} interrupt_frame_t;
|
||||
|
||||
void idt_init();
|
||||
void idt_register_handler(uint8_t interrupt, unsigned long address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void idt_set_entry(u8 vector, void* isr, u8 flags);
|
||||
|
|
|
@ -2,12 +2,4 @@
|
|||
|
||||
#include <drivers/idt/idt.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void isr_install(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5,16 +5,8 @@
|
|||
#include <std/util.h>
|
||||
#include <std/string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define KBD_BUF_SIZE 256
|
||||
|
||||
int keyboard_init(void);
|
||||
uint8_t keyboard_enabled(void);
|
||||
u8 keyboard_enabled(void);
|
||||
unsigned char keyboard_get_key_from_scancode(unsigned char scancode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
#include <std/inline.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
#define PIC1_COMMAND PIC1
|
||||
|
@ -19,10 +15,6 @@ extern "C" {
|
|||
#define ICW4_8086 0x01
|
||||
|
||||
void pic_init();
|
||||
void pic_send_eoi(uint8_t no);
|
||||
void pic_irq_enable(uint8_t no);
|
||||
void pic_irq_disable(uint8_t no);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void pic_send_eoi(u8 no);
|
||||
void pic_irq_enable(u8 no);
|
||||
void pic_irq_disable(u8 no);
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct tar_header
|
||||
{
|
||||
char filename[100];
|
||||
|
@ -18,7 +14,3 @@ struct tar_header
|
|||
};
|
||||
|
||||
struct tar_header* tar_seek(int fd, char filename[100]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <types.h>
|
||||
#include <std/string.h>
|
||||
#include <std/inline.h>
|
||||
#include <drivers/ide/ide.h>
|
||||
#include <psf.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Hardware text mode color constants. */
|
||||
enum vga_color {
|
||||
VGA_COLOR_BLACK = 0,
|
||||
|
@ -31,33 +27,32 @@ enum vga_color {
|
|||
VGA_COLOR_WHITE = 15,
|
||||
};
|
||||
|
||||
static inline uint8_t vga_entry_color(const enum vga_color fg, const enum vga_color bg) {
|
||||
static inline u8 vga_entry_color(const enum vga_color fg, const enum vga_color bg) {
|
||||
return fg | (bg << 4);
|
||||
}
|
||||
|
||||
static inline uint16_t vga_entry(const uint8_t uc, const uint8_t color) {
|
||||
return (uint16_t) uc | (uint16_t) color << 8;
|
||||
static inline u16 vga_entry(const u8 uc, const u8 color) {
|
||||
return (u16) uc | (u16) color << 8;
|
||||
}
|
||||
|
||||
static const size_t VGA_WIDTH = 80;
|
||||
static const size_t VGA_HEIGHT = 25;
|
||||
static usize terminal_width;
|
||||
static usize terminal_height;
|
||||
|
||||
extern size_t terminal_row;
|
||||
extern size_t terminal_column;
|
||||
extern uint8_t terminal_color;
|
||||
extern uint16_t *terminal_buffer;
|
||||
extern usize terminal_row;
|
||||
extern usize terminal_column;
|
||||
extern u8 terminal_color;
|
||||
extern u16 *terminal_buffer;
|
||||
|
||||
void terminal_clear();
|
||||
int terminal_initialize(framebuffer_t *terminal_fb);
|
||||
void terminal_setcolor(uint8_t color);
|
||||
void terminal_clearline(size_t line);
|
||||
void terminal_clearlines(size_t from, size_t to);
|
||||
void terminal_setcolor(u8 color);
|
||||
void terminal_clearline(usize line);
|
||||
void terminal_clearlines(usize from, usize to);
|
||||
void terminal_updatecursor();
|
||||
void terminal_scrollup();
|
||||
void terminal_checknewline();
|
||||
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y);
|
||||
void terminal_putentryat(char c, u8 color, usize x, usize y);
|
||||
void terminal_putchar(char c);
|
||||
void terminal_write(const char* data, size_t size);
|
||||
void terminal_write(const char* data, usize size);
|
||||
|
||||
static inline void terminal_writestring(const char *data) {
|
||||
terminal_write(data, strlen(data));
|
||||
|
@ -67,7 +62,3 @@ static inline void terminal_writeline(const char *data) {
|
|||
terminal_writestring(data);
|
||||
terminal_putchar('\n');
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,24 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <types.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t *address;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t depth;
|
||||
uint32_t pitch;
|
||||
uint32_t pixelwidth;
|
||||
u8 *address;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 depth;
|
||||
u32 pitch;
|
||||
u32 pixelwidth;
|
||||
} framebuffer_t;
|
||||
|
||||
void putpixel(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint32_t color);
|
||||
void fillrect(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void putpixel(framebuffer_t *framebuffer, u16 x, u16 y, u32 color);
|
||||
void fillrect(framebuffer_t *framebuffer, u16 x, u16 y, u16 w, u16 h, u32 color);
|
||||
|
|
36
include/paging.h
Normal file
36
include/paging.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define PAGE_PRESENT 1 << 0
|
||||
#define PAGE_WRITABLE 1 << 1
|
||||
#define PAGE_USER 1 << 2
|
||||
#define PAGE_WRITE_THROUGH 1 << 3
|
||||
#define PAGE_CACHE_DISABLE 1 << 4
|
||||
#define PAGE_ACCESSED 1 << 5
|
||||
#define PAGE_DIRTY 1 << 6
|
||||
#define PAGE_GLOBAL 1 << 8
|
||||
#define PAGE_NO_EXECUTE 1 << 63
|
||||
|
||||
#define PAGE_ADDRESS_MASK 0x000FFFFFFFFFF000
|
||||
|
||||
typedef struct {
|
||||
u16 page_offset : 12;
|
||||
u16 pt_offset : 9;
|
||||
u16 pd_offset : 9;
|
||||
u16 pdp_offset : 9;
|
||||
u16 pml4_offset : 9;
|
||||
u16 sign_extend : 16;
|
||||
} __attribute__((packed)) parsed_address_t;
|
||||
|
||||
typedef union {
|
||||
u64 int_address;
|
||||
parsed_address_t parsed_address;
|
||||
} address_t;
|
||||
|
||||
static u64 PML4[512] __attribute__((aligned(4096)));
|
||||
|
||||
static bitmap_t *page_bitmap;
|
||||
|
||||
void setup_paging(u64 total_memory);
|
||||
void map_page(u64 physical, u64 virtual);
|
|
@ -1,24 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include <framebuffer.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PSF_FONT_MAGIC 0x864ab572
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic; /* magic bytes to identify PSF */
|
||||
uint32_t version; /* zero */
|
||||
uint32_t headersize; /* whereet of bitmaps in file, 32 */
|
||||
uint32_t flags; /* 0 if there's no unicode table */
|
||||
uint32_t numglyph; /* number of glyphs */
|
||||
uint32_t bytesperglyph; /* size of each glyph */
|
||||
uint32_t height; /* height in pixels */
|
||||
uint32_t width; /* width in pixels */
|
||||
u32 magic; /* magic bytes to identify PSF */
|
||||
u32 version; /* zero */
|
||||
u32 headersize; /* whereet of bitmaps in file, 32 */
|
||||
u32 flags; /* 0 if there's no unicode table */
|
||||
u32 numglyph; /* number of glyphs */
|
||||
u32 bytesperglyph; /* size of each glyph */
|
||||
u32 height; /* height in pixels */
|
||||
u32 width; /* width in pixels */
|
||||
} PSF_font;
|
||||
|
||||
// these are linked using objcopy
|
||||
|
@ -26,8 +21,4 @@ extern char _binary_font_psfu_start;
|
|||
extern char _binary_font_psfu_end;
|
||||
|
||||
// c is a unicode character, cx and cy are cursor position in characters
|
||||
void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t cy, uint32_t fg, uint32_t bg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void draw_psf_char(framebuffer_t *framebuffer, u32 c, u16 cx, u16 cy, u32 fg, u32 bg);
|
||||
|
|
|
@ -2,14 +2,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
inline int isdigit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void outportb(const uint16_t port, const uint8_t val) {
|
||||
static inline void outportb(const u16 port, const u8 val) {
|
||||
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
|
||||
}
|
||||
|
||||
static inline void outportw(const uint16_t port, const uint16_t val) {
|
||||
static inline void outportw(const u16 port, const u16 val) {
|
||||
asm volatile ( "outw %0, %1" : : "a"(val), "Nd"(port) );
|
||||
}
|
||||
|
||||
static inline void outportl(const uint16_t port, const uint32_t val) {
|
||||
static inline void outportl(const u16 port, const u32 val) {
|
||||
asm volatile ( "outl %0, %1" : : "a"(val), "Nd"(port) );
|
||||
}
|
||||
|
||||
|
@ -23,20 +19,20 @@ static inline void outportsm(unsigned short port, unsigned char* data, unsigned
|
|||
asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port));
|
||||
}
|
||||
|
||||
static inline uint8_t inportb(const uint16_t port) {
|
||||
uint8_t ret;
|
||||
static inline u8 inportb(const u16 port) {
|
||||
u8 ret;
|
||||
asm volatile ( "inb %1, %0" : "=a"(ret) : "Nd"(port) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint16_t inportw(const uint16_t port) {
|
||||
uint16_t ret;
|
||||
static inline u16 inportw(const u16 port) {
|
||||
u16 ret;
|
||||
asm volatile ( "inw %1, %0" : "=a"(ret) : "Nd"(port) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t inportl(const uint16_t port) {
|
||||
uint32_t ret;
|
||||
static inline u32 inportl(const u16 port) {
|
||||
u32 ret;
|
||||
asm volatile ( "inl %1, %0" : "=a"(ret) : "Nd"(port) );
|
||||
return ret;
|
||||
}
|
||||
|
@ -63,7 +59,3 @@ static inline void insl(unsigned reg, unsigned int *buffer, int quads) {
|
|||
buffer[index] = inportl(reg);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,16 +2,8 @@
|
|||
|
||||
#include <drivers/terminal/terminal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
inline void putchar(char c) {
|
||||
terminal_putchar(c);
|
||||
}
|
||||
|
||||
__attribute__ ((format (printf, 1, 2))) int printf (const char* format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int memcmp(const void* aptr, const void* bptr, size_t size);
|
||||
void* memcpy(void* __restrict dstptr, const void* __restrict srcptr, size_t size);
|
||||
void* memmove(void* dstptr, const void* srcptr, size_t size);
|
||||
void* memset(void* bufptr, int value, size_t size);
|
||||
size_t strlen(const char* str);
|
||||
int memcmp(const void* aptr, const void* bptr, usize size);
|
||||
void* memcpy(void* __restrict dstptr, const void* __restrict srcptr, usize size);
|
||||
void* memmove(void* dstptr, const void* srcptr, usize size);
|
||||
void* memset(void* bufptr, int value, usize size);
|
||||
usize strlen(const char* str);
|
||||
char* strcpy(char* dst, const char* src);
|
||||
char* strcat(char* dst, const char* src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define LOW_16(address) (u16)((address) & 0xFFFF)
|
||||
#define HIGH_16(address) (u16)(((address) >> 16) & 0xFFFF)
|
||||
|
||||
#define LOW_16(address) (uint16_t)((address) & 0xFFFF)
|
||||
#define HIGH_16(address) (uint16_t)(((address) >> 16) & 0xFFFF)
|
||||
|
||||
void* malloc(size_t amount);
|
||||
void* malloc(usize amount);
|
||||
|
||||
int rand(void);
|
||||
void srand(size_t seed);
|
||||
void srand(usize seed);
|
||||
char* itoa(int res);
|
||||
unsigned int atoi(const char *in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
inline bool bitmap_get(bitmap_t *bitmap, usize index) {
|
||||
if (index >= bitmap->size) return false;
|
||||
return (bitmap->contents[index / 8] >> (index % 8)) & 1;
|
||||
}
|
||||
|
||||
inline u8 bitmap_set(bitmap_t *bitmap, usize index, bool value) {
|
||||
if (index >= bitmap->size) return -1;
|
||||
bitmap->contents[index / 8] &= !value << (index % 8);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
#ifndef __STIVALE__STIVALE2_H__
|
||||
#define __STIVALE__STIVALE2_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
|
||||
struct stivale2_tag {
|
||||
uint64_t identifier;
|
||||
uint64_t next;
|
||||
u64 identifier;
|
||||
u64 next;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/* --- Header --------------------------------------------------------------- */
|
||||
/* Information passed from the kernel to the bootloader */
|
||||
|
||||
struct stivale2_header {
|
||||
uint64_t entry_point;
|
||||
uint64_t stack;
|
||||
uint64_t flags;
|
||||
uint64_t tags;
|
||||
u64 entry_point;
|
||||
u64 stack;
|
||||
u64 flags;
|
||||
u64 tags;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_HEADER_TAG_FRAMEBUFFER_ID 0x3ecc1bc43d0f7971
|
||||
|
||||
struct stivale2_header_tag_framebuffer {
|
||||
struct stivale2_tag tag;
|
||||
uint16_t framebuffer_width;
|
||||
uint16_t framebuffer_height;
|
||||
uint16_t framebuffer_bpp;
|
||||
u16 framebuffer_width;
|
||||
u16 framebuffer_height;
|
||||
u16 framebuffer_bpp;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_HEADER_TAG_FB_MTRR_ID 0x4c7bb07731282e00
|
||||
|
@ -33,14 +33,14 @@ struct stivale2_header_tag_framebuffer {
|
|||
|
||||
struct stivale2_header_tag_terminal {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t flags;
|
||||
u64 flags;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_HEADER_TAG_SMP_ID 0x1ab015085f3273df
|
||||
|
||||
struct stivale2_header_tag_smp {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t flags;
|
||||
u64 flags;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_HEADER_TAG_5LV_PAGING_ID 0x932f477032007e8f
|
||||
|
@ -57,14 +57,14 @@ struct stivale2_struct {
|
|||
#define STIVALE2_BOOTLOADER_VERSION_SIZE 64
|
||||
char bootloader_version[STIVALE2_BOOTLOADER_VERSION_SIZE];
|
||||
|
||||
uint64_t tags;
|
||||
u64 tags;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_CMDLINE_ID 0xe5e76a1b4597a781
|
||||
|
||||
struct stivale2_struct_tag_cmdline {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t cmdline;
|
||||
u64 cmdline;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_MEMMAP_ID 0x2187f79e8612de07
|
||||
|
@ -79,15 +79,15 @@ struct stivale2_struct_tag_cmdline {
|
|||
#define STIVALE2_MMAP_FRAMEBUFFER 0x1002
|
||||
|
||||
struct stivale2_mmap_entry {
|
||||
uint64_t base;
|
||||
uint64_t length;
|
||||
uint32_t type;
|
||||
uint32_t unused;
|
||||
u64 base;
|
||||
u64 length;
|
||||
u32 type;
|
||||
u32 unused;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct stivale2_struct_tag_memmap {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t entries;
|
||||
u64 entries;
|
||||
struct stivale2_mmap_entry memmap[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
|
@ -97,26 +97,26 @@ struct stivale2_struct_tag_memmap {
|
|||
|
||||
struct stivale2_struct_tag_framebuffer {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t framebuffer_addr;
|
||||
uint16_t framebuffer_width;
|
||||
uint16_t framebuffer_height;
|
||||
uint16_t framebuffer_pitch;
|
||||
uint16_t framebuffer_bpp;
|
||||
uint8_t memory_model;
|
||||
uint8_t red_mask_size;
|
||||
uint8_t red_mask_shift;
|
||||
uint8_t green_mask_size;
|
||||
uint8_t green_mask_shift;
|
||||
uint8_t blue_mask_size;
|
||||
uint8_t blue_mask_shift;
|
||||
u64 framebuffer_addr;
|
||||
u16 framebuffer_width;
|
||||
u16 framebuffer_height;
|
||||
u16 framebuffer_pitch;
|
||||
u16 framebuffer_bpp;
|
||||
u8 memory_model;
|
||||
u8 red_mask_size;
|
||||
u8 red_mask_shift;
|
||||
u8 green_mask_size;
|
||||
u8 green_mask_shift;
|
||||
u8 blue_mask_size;
|
||||
u8 blue_mask_shift;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_EDID_ID 0x968609d7af96b845
|
||||
|
||||
struct stivale2_struct_tag_edid {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t edid_size;
|
||||
uint8_t edid_information[];
|
||||
u64 edid_size;
|
||||
u8 edid_information[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_FB_MTRR_ID 0x6bc1a78ebe871172
|
||||
|
@ -125,17 +125,17 @@ struct stivale2_struct_tag_edid {
|
|||
|
||||
struct stivale2_struct_tag_terminal {
|
||||
struct stivale2_tag tag;
|
||||
uint32_t flags;
|
||||
uint16_t cols;
|
||||
uint16_t rows;
|
||||
uint64_t term_write;
|
||||
u32 flags;
|
||||
u16 cols;
|
||||
u16 rows;
|
||||
u64 term_write;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce
|
||||
|
||||
struct stivale2_module {
|
||||
uint64_t begin;
|
||||
uint64_t end;
|
||||
u64 begin;
|
||||
u64 end;
|
||||
|
||||
#define STIVALE2_MODULE_STRING_SIZE 128
|
||||
char string[STIVALE2_MODULE_STRING_SIZE];
|
||||
|
@ -143,7 +143,7 @@ struct stivale2_module {
|
|||
|
||||
struct stivale2_struct_tag_modules {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t module_count;
|
||||
u64 module_count;
|
||||
struct stivale2_module modules[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
|
@ -151,14 +151,14 @@ struct stivale2_struct_tag_modules {
|
|||
|
||||
struct stivale2_struct_tag_rsdp {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t rsdp;
|
||||
u64 rsdp;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_EPOCH_ID 0x566a7bed888e1407
|
||||
|
||||
struct stivale2_struct_tag_epoch {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t epoch;
|
||||
u64 epoch;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_FIRMWARE_ID 0x359d837855e3858c
|
||||
|
@ -167,55 +167,55 @@ struct stivale2_struct_tag_epoch {
|
|||
|
||||
struct stivale2_struct_tag_firmware {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t flags;
|
||||
u64 flags;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID 0x4bc5ec15845b558e
|
||||
|
||||
struct stivale2_struct_tag_efi_system_table {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t system_table;
|
||||
u64 system_table;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_KERNEL_FILE_ID 0xe599d90c2975584a
|
||||
|
||||
struct stivale2_struct_tag_kernel_file {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t kernel_file;
|
||||
u64 kernel_file;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID 0xee80847d01506c57
|
||||
|
||||
struct stivale2_struct_tag_kernel_slide {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t kernel_slide;
|
||||
u64 kernel_slide;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_SMBIOS_ID 0x274bd246c62bf7d1
|
||||
|
||||
struct stivale2_struct_tag_smbios {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t flags;
|
||||
uint64_t smbios_entry_32;
|
||||
uint64_t smbios_entry_64;
|
||||
u64 flags;
|
||||
u64 smbios_entry_32;
|
||||
u64 smbios_entry_64;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_SMP_ID 0x34d1d96339647025
|
||||
|
||||
struct stivale2_smp_info {
|
||||
uint32_t processor_id;
|
||||
uint32_t lapic_id;
|
||||
uint64_t target_stack;
|
||||
uint64_t goto_address;
|
||||
uint64_t extra_argument;
|
||||
u32 processor_id;
|
||||
u32 lapic_id;
|
||||
u64 target_stack;
|
||||
u64 goto_address;
|
||||
u64 extra_argument;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct stivale2_struct_tag_smp {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t flags;
|
||||
uint32_t bsp_lapic_id;
|
||||
uint32_t unused;
|
||||
uint64_t cpu_count;
|
||||
u64 flags;
|
||||
u32 bsp_lapic_id;
|
||||
u32 unused;
|
||||
u64 cpu_count;
|
||||
struct stivale2_smp_info smp_info[];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
|
@ -223,29 +223,29 @@ struct stivale2_struct_tag_smp {
|
|||
|
||||
struct stivale2_struct_tag_pxe_server_info {
|
||||
struct stivale2_tag tag;
|
||||
uint32_t server_ip;
|
||||
u32 server_ip;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_MMIO32_UART 0xb813f9b8dbc78797
|
||||
|
||||
struct stivale2_struct_tag_mmio32_uart {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t addr;
|
||||
u64 addr;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_DTB 0xabb29bd49a2833fa
|
||||
|
||||
struct stivale2_struct_tag_dtb {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t addr;
|
||||
uint64_t size;
|
||||
u64 addr;
|
||||
u64 size;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define STIVALE2_STRUCT_TAG_VMAP 0xb0ed257db18cb58f
|
||||
|
||||
struct stivale2_struct_vmap {
|
||||
struct stivale2_tag tag;
|
||||
uint64_t addr;
|
||||
u64 addr;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#endif
|
21
include/types.h
Normal file
21
include/types.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef size_t usize;
|
||||
|
||||
typedef int8_t i8;
|
||||
typedef int16_t i16;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i64;
|
||||
|
||||
typedef struct {
|
||||
u8 *contents;
|
||||
usize size;
|
||||
} bitmap_t;
|
|
@ -7,7 +7,9 @@ SECTIONS
|
|||
/* Since we are going to use PIE, this is just the base load address, but the */
|
||||
/* bootloader will be able to relocate us as it sees fit. */
|
||||
. = 0xffffffff80200000;
|
||||
|
||||
|
||||
_kernel_start = .;
|
||||
|
||||
/* We place the .stivale2hdr section containing the header in its own section, */
|
||||
/* and we use the KEEP directive on it to make sure it doesn't get discarded. */
|
||||
.stivale2hdr : {
|
||||
|
@ -31,4 +33,6 @@ SECTIONS
|
|||
*(COMMON)
|
||||
*(.bss*)
|
||||
}
|
||||
|
||||
_kernel_end = .;
|
||||
}
|
Loading…
Reference in a new issue