fix idt and begin paging

This commit is contained in:
Tunacan 2021-08-17 12:45:35 +03:00
parent ef1ee78320
commit 624ffbe738
39 changed files with 704 additions and 823 deletions

View file

@ -5,7 +5,7 @@ CC = x86_64-elf-gcc
NASM = nasm NASM = nasm
# User controllable CFLAGS. # User controllable CFLAGS.
CFLAGS = -Wall -Wextra -O3 -pipe CFLAGS = -Wall -Wextra -O2 -pipe
NASMFLAGS = -felf64 NASMFLAGS = -felf64
# Internal link flags that should not be changed by the user. # 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. # Internal C flags that should not be changed by the user.
INTERNALCFLAGS := \ INTERNALCFLAGS := \
-Iinclude \ -Iinclude \
-std=gnu11 \ -std=gnu17 \
-ffreestanding \ -ffreestanding \
-fno-stack-protector \ -fno-stack-protector \
-fno-pic -fpie \ -fno-pic -fpie \
@ -40,7 +40,9 @@ OBJ += font.o
.PHONY: all clean run .PHONY: all clean run
run: $(ISO) 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) $(ISO): $(KERNEL)
mkdir -p sysroot mkdir -p sysroot

View file

@ -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

View file

@ -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;
}

View file

@ -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();
}

View file

@ -1,21 +1,21 @@
#include <framebuffer.h> #include <framebuffer.h>
#include <std/stdio.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; 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] = (color >> 8) & 255; // BLUE
framebuffer->address[where + 1] = (color >> 16) & 255; // GREEN framebuffer->address[where + 1] = (color >> 16) & 255; // GREEN
framebuffer->address[where + 2] = (color >> 24) & 255; // RED 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; if (color & 255 == 0) return;
uint8_t* where; u8 *where;
uint32_t pw = framebuffer->pixelwidth; u32 pw = framebuffer->pixelwidth;
for (uint16_t i = y; i < h + y; i++) { for (u16 i = y; i < h + y; i++) {
where = (uint8_t*)((uint64_t)framebuffer->address + framebuffer->pitch * i); where = (u8*)((u64)framebuffer->address + framebuffer->pitch * i);
for (uint16_t j = x; j < w + x; j++) { for (u16 j = x; j < w + x; j++) {
where[j * pw] = (color >> 8) & 255; // BLUE where[j * pw] = (color >> 8) & 255; // BLUE
where[j * pw + 1] = (color >> 16) & 255; // GREEN where[j * pw + 1] = (color >> 16) & 255; // GREEN
where[j * pw + 2] = (color >> 24) & 255; // RED where[j * pw + 2] = (color >> 24) & 255; // RED

View file

@ -7,7 +7,7 @@
// NOTE(hippoz): The function below is actually a joke. It's temporary. I'll // NOTE(hippoz): The function below is actually a joke. It's temporary. I'll
// implement the timer soon. // implement the timer soon.
uint8_t sleep(int h) { u8 sleep(int h) {
if (h != 1) if (h != 1)
return 1; return 1;
for (unsigned long long i = 0; i < 99999999999; i++) 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; return result;
} }
void ide_read_buffer(unsigned char channel, unsigned char reg, void ide_read_buffer(u8 channel, u8 reg, u32 *buffer, u32 quads) {
unsigned int *buffer, unsigned int quads) {
/* WARNING: This code contains a serious bug. The inline assembly trashes ES /* 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 * and ESP for all of the code the compiler generates between the inline
* assembly blocks. * assembly blocks.
@ -308,7 +307,7 @@ void ide_wait_irq() {
} }
unsigned char ide_ata_access(unsigned char direction, unsigned char drive, 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 */, unsigned char lba_mode /* 0: CHS, 1:LBA28, 2: LBA48 */,
dma /* 0: No DMA, 1: DMA */, cmd; dma /* 0: No DMA, 1: DMA */, cmd;
unsigned char lba_io[6]; 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 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: // Check if the drive is present:
if (drive > 3 || ide_devices[drive].Reserved == 0) if (drive > 3 || ide_devices[drive].Reserved == 0)
return 0x01; // Drive not present 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); 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) if (drive > 3 || ide_devices[drive].Reserved == 0)
return 0x01; // Drive not present return 0x01; // Drive not present
if (((lba + 1) > ide_devices[drive].Size) && if (((lba + 1) > ide_devices[drive].Size) &&
@ -494,7 +493,7 @@ void ide_init() {
sleep(1); sleep(1);
printf("Testing IDE drive...\n"); printf("Testing IDE drive...\n");
uint8_t buf[512] = {0}; u8 buf[512] = {0};
memcpy(buf, "Hello world", sizeof("Hello world")); memcpy(buf, "Hello world", sizeof("Hello world"));
ide_write_sectors(0, 1, buf); ide_write_sectors(0, 1, buf);
@ -502,14 +501,14 @@ void ide_init() {
sleep(1); sleep(1);
sleep(1); sleep(1);
uint8_t outbuf[512] = {0}; u8 outbuf[512] = {0};
ide_read_sectors(0, 1, outbuf); ide_read_sectors(0, 1, outbuf);
sleep(1); sleep(1);
sleep(1); 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("%d: %c | ", i, outbuf[i]);
} }
printf("\n"); printf("\n");

View 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;
}
*/

View 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();
}

View file

@ -44,15 +44,15 @@ unsigned char kbdus[128] = {
0, /* All other keys are undefined */ 0, /* All other keys are undefined */
}; };
uint8_t lastkey = 0; u8 lastkey = 0;
uint8_t __kbd_enabled = 0; u8 __kbd_enabled = 0;
void keyboard_buffer_push_key(unsigned char scancode) { void keyboard_buffer_push_key(unsigned char scancode) {
kbdbuf[lastkey++] = scancode; kbdbuf[lastkey++] = scancode;
} }
unsigned char keyboard_buffer_pop_key() { unsigned char keyboard_buffer_pop_key() {
uint8_t index = lastkey--; u8 index = lastkey--;
unsigned char scancode = kbdbuf[index]; unsigned char scancode = kbdbuf[index];
kbdbuf[index] = 0; kbdbuf[index] = 0;
return scancode; return scancode;
@ -62,7 +62,7 @@ unsigned char keyboard_get_key_from_scancode(unsigned char scancode) {
return kbdus[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); unsigned char scancode = inportb(0x60);
if (scancode & 128) { if (scancode & 128) {
@ -75,7 +75,7 @@ __attribute__((interrupt)) static void keyboard_irq(struct interrupt_frame* fram
pic_send_eoi(1); pic_send_eoi(1);
} }
uint8_t keyboard_enabled(void) { u8 keyboard_enabled(void) {
return __kbd_enabled; return __kbd_enabled;
} }
@ -89,7 +89,7 @@ void* keyboard_write() {
int keyboard_init(void) { int keyboard_init(void) {
pic_irq_enable(1); pic_irq_enable(1);
idt_register_handler(33, (uint32_t)keyboard_irq); idt_set_entry(33, (void*)keyboard_irq, INTERRUPT_GATE);
__kbd_enabled = 1; __kbd_enabled = 1;

View file

@ -1,7 +1,7 @@
#include <drivers/pic/pic.h> #include <drivers/pic/pic.h>
static uint8_t pic1_mask = 0xff; static u8 pic1_mask = 0xff;
static uint8_t pic2_mask = 0xff; static u8 pic2_mask = 0xff;
void pic_init() { void pic_init() {
outportb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); outportb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
@ -25,14 +25,14 @@ void pic_init() {
pic_irq_enable(2); pic_irq_enable(2);
} }
void pic_send_eoi(uint8_t no) { void pic_send_eoi(u8 no) {
if (no >= 8) { if (no >= 8) {
outportb(PIC2_COMMAND, PIC_EOI); outportb(PIC2_COMMAND, PIC_EOI);
} }
outportb(PIC1_COMMAND, PIC_EOI); outportb(PIC1_COMMAND, PIC_EOI);
} }
void pic_irq_enable(uint8_t no) { void pic_irq_enable(u8 no) {
if (no >= 8) { if (no >= 8) {
no -= 8; no -= 8;
pic2_mask &= ~(1 << no); 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) { if (no >= 8) {
no -= 8; no -= 8;
pic2_mask |= (1 << no); pic2_mask |= (1 << no);

View file

@ -1,13 +1,13 @@
#include <psf.h> #include <psf.h>
// c is a unicode character, cx and cy are cursor position in characters // 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; PSF_font *font = (PSF_font*)&_binary_font_psfu_start;
// we need to know how many bytes encode one row // we need to know how many bytes encode one row
int bytesperline = (font->width + 7) / 8; int bytesperline = (font->width + 7) / 8;
// get the glyph for the character. If there's no // get the glyph for the character. If there's no
// glyph for a given character, we'll display the first glyph. // 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; (c > 0 && c < font->numglyph ? c : 0) * font->bytesperglyph;
// calculate the upper left corner on screen where we want to display. // 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. // 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); mask = 1 << (font->width - 1);
// display a row // display a row
for (x = 0; x < font->width; x++) { 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 // adjust to the next pixel
mask >>= 1; mask >>= 1;
line += 4; line += framebuffer->pixelwidth;
} }
// adjust to the next line // adjust to the next line
glyph += bytesperline; glyph += bytesperline;

View file

@ -1,17 +1,16 @@
#include <drivers/terminal/terminal.h> #include <drivers/terminal/terminal.h>
#include <drivers/device/device.h> #include <drivers/device/device.h>
size_t terminal_row; usize terminal_row;
size_t terminal_column; usize terminal_column;
uint8_t terminal_color; u8 terminal_color;
uint16_t *terminal_buffer;
framebuffer_t *terminal_framebuffer; framebuffer_t *terminal_framebuffer;
void terminal_clear() { void terminal_clear() {
for (size_t y = 0; y < VGA_HEIGHT; y++) { for (usize y = 0; y < terminal_height; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) { for (usize x = 0; x < terminal_width; x++) {
const size_t index = y * VGA_WIDTH + x; const usize index = y * terminal_width + x;
terminal_buffer[index] = vga_entry(' ', terminal_color); //terminal_buffer[index] = vga_entry(' ', terminal_color);
} }
} }
} }
@ -38,10 +37,10 @@ void* terminal_devwrite(void* data) {
int terminal_initialize(framebuffer_t *terminal_fb) { int terminal_initialize(framebuffer_t *terminal_fb) {
terminal_framebuffer = terminal_fb; terminal_framebuffer = terminal_fb;
terminal_width = terminal_framebuffer->width / 8;
terminal_height = terminal_framebuffer->height / 16;
terminal_row = 0; terminal_row = 0;
terminal_column = 0; terminal_column = 0;
terminal_color = vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE);
terminal_buffer = (uint16_t*) 0xB8000;
terminal_clear(); terminal_clear();
struct device terminal_device = { struct device terminal_device = {
@ -52,56 +51,45 @@ int terminal_initialize(framebuffer_t *terminal_fb) {
return push_device(terminal_device); return push_device(terminal_device);
} }
void terminal_setcolor(uint8_t color) { void terminal_setcolor(u8 color) {
terminal_color = color; terminal_color = color;
} }
void terminal_clearline(size_t line) { void terminal_clearline(usize line) {
for (size_t x = 0; x < VGA_WIDTH; x++) { for (usize x = 0; x < terminal_width; x++) {
const size_t index = line * VGA_WIDTH + x; const usize index = line * terminal_width + x;
terminal_buffer[index] = vga_entry(' ', terminal_color); //terminal_buffer[index] = vga_entry(' ', terminal_color);
} }
} }
void terminal_clearlines(size_t from, size_t to) { void terminal_clearlines(usize from, usize to) {
for (size_t y = from; y <= to; y++) { for (usize y = from; y <= to; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) { for (usize x = 0; x < terminal_width; x++) {
const size_t index = y * VGA_WIDTH + x; const usize index = y * terminal_width + x;
terminal_buffer[index] = vga_entry(' ', terminal_color); //terminal_buffer[index] = vga_entry(' ', terminal_color);
} }
} }
} }
void terminal_updatecursor() { void terminal_updatecursor() {
size_t temp = terminal_row * VGA_WIDTH + terminal_column; /*
usize temp = terminal_row * terminal_width + terminal_column;
outportb(0x3D4, 14); outportb(0x3D4, 14);
outportb(0x3D5, temp >> 8); outportb(0x3D5, temp >> 8);
outportb(0x3D4, 15); outportb(0x3D4, 15);
outportb(0x3D5, temp); 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() { void terminal_checknewline() {
if (terminal_row >= VGA_HEIGHT - 1) { if (terminal_row >= terminal_height - 1) {
terminal_scrollup(); //terminal_scrollup();
} }
} }
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) {
//terminal_buffer[y * VGA_WIDTH + x] = vga_entry(c, color); //terminal_buffer[y * terminal_width + x] = vga_entry(c, color);
draw_psf_char(terminal_framebuffer, c, x, y, 0xFFFFFFFF, 0); draw_psf_char(terminal_framebuffer, c, x, y, 0xFFFFFFFF, 0);
} }
@ -111,7 +99,7 @@ void terminal_putchar(char c) {
case '\b': case '\b':
if (--terminal_column < 0) { if (--terminal_column < 0) {
if (terminal_row-- > 0) { if (terminal_row-- > 0) {
terminal_column = VGA_WIDTH - 1; terminal_column = terminal_width - 1;
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row); terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
} }
} else { } else {
@ -131,7 +119,7 @@ void terminal_putchar(char c) {
terminal_column++; terminal_column++;
} }
if (terminal_column >= VGA_WIDTH) { if (terminal_column >= terminal_width) {
terminal_column = 0; terminal_column = 0;
terminal_row++; terminal_row++;
} }
@ -140,7 +128,7 @@ void terminal_putchar(char c) {
terminal_checknewline(); terminal_checknewline();
} }
void terminal_write(const char* data, size_t size) { void terminal_write(const char* data, usize size) {
for (size_t i = 0; i < size; i++) for (usize i = 0; i < size; i++)
terminal_putchar(data[i]); terminal_putchar(data[i]);
} }

View file

@ -1,5 +1,5 @@
#include <stdint.h> #include <types.h>
#include <stddef.h>
#include <stivale2.h> #include <stivale2.h>
#include <std/inline.h> #include <std/inline.h>
#include <std/util.h> #include <std/util.h>
@ -12,11 +12,9 @@
#include <drivers/ide/ide.h> #include <drivers/ide/ide.h>
#include <framebuffer.h> #include <framebuffer.h>
#include <psf.h> #include <psf.h>
#include <paging.h>
// We need to tell the stivale bootloader where we want our stack to be. static u8 stack[16384];
// We are going to allocate our stack as an uninitialised array in .bss.
static uint8_t stack[4096];
void kmain();
bool is_running = true; bool is_running = true;
int keyboard_descriptor = 0; int keyboard_descriptor = 0;
@ -42,7 +40,7 @@ static struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = {
.framebuffer_height = 600, .framebuffer_height = 600,
.framebuffer_bpp = 32 .framebuffer_bpp = 32
}; };
// The stivale2 specification says we need to define a "header structure". // The stivale2 specification says we need to define a "header structure".
// This structure needs to reside in the .stivale2hdr ELF section in order // This structure needs to reside in the .stivale2hdr ELF section in order
// for the bootloader to find it. We use this __attribute__ directive to // 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. // points to the first one in the linked list.
.tags = (uintptr_t)&framebuffer_hdr_tag .tags = (uintptr_t)&framebuffer_hdr_tag
}; };
// We will now write a helper function which will allow us to scan for tags void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, u64 id) {
// that we want FROM the bootloader (structure tags).
void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) {
struct stivale2_tag *current_tag = (void *)stivale2_struct->tags; struct stivale2_tag *current_tag = (void *)stivale2_struct->tags;
for (;;) { for (;;) {
// If the tag pointer is NULL (end of linked list), we did not find // 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; 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) { 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..."); printf("Requested stivale2 tags were not found, hanging...");
for (;;) { for (;;) {
asm ("hlt"); asm ("hlt");
} }
} }
framebuffer->address = (uint8_t*)tagfb->framebuffer_addr;
framebuffer->width = tagfb->framebuffer_width; framebuffer->address = (u8*)tag_fb->framebuffer_addr;
framebuffer->height = tagfb->framebuffer_height; framebuffer->width = tag_fb->framebuffer_width;
framebuffer->depth = tagfb->framebuffer_bpp; framebuffer->height = tag_fb->framebuffer_height;
framebuffer->pitch = tagfb->framebuffer_pitch; framebuffer->depth = tag_fb->framebuffer_bpp;
framebuffer->pixelwidth = tagfb->framebuffer_bpp / 8; framebuffer->pitch = tag_fb->framebuffer_pitch;
framebuffer->pixelwidth = tag_fb->framebuffer_bpp / 8;
terminal_descriptor = terminal_initialize(framebuffer); terminal_descriptor = terminal_initialize(framebuffer);
printf("Terminal initialized, descriptor: %d\n", terminal_descriptor); 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); printf("Framebuffer | addr: %#lX, width: %d, height: %d, depth: %d, pitch: %d\n", (usize)framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch);
kmain();
}
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"); printf("hello yes");
while (is_running) { while (is_running) {
printf("\n> "); printf("\n> ");
while (true) { while (true) {
uint32_t scancode = (uint32_t)read(keyboard_descriptor, NULL); usize scancode = (usize)read(keyboard_descriptor, NULL);
if (!scancode) continue; if (!scancode) continue;
bool special = true; 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
View 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);
}

View file

@ -2,7 +2,7 @@
#include <std/string.h> #include <std/string.h>
#include <std/ctype.h> #include <std/ctype.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <types.h>
#include <stdarg.h> #include <stdarg.h>
// shamelessly stolen from https://wiki.osdev.org/User:A22347/Printf // shamelessly stolen from https://wiki.osdev.org/User:A22347/Printf
@ -253,7 +253,7 @@ int vprintf (const char* format, va_list list)
} }
case 'z': 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); __int_str(integer, intStrBuffer, base, plusSign, spaceNoSign, lengthSpec, leftJustify, zeroPad);
displayString(intStrBuffer, &chars); displayString(intStrBuffer, &chars);
break; break;
@ -319,7 +319,7 @@ int vprintf (const char* format, va_list list)
} }
case 'z': 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); __int_str(integer, intStrBuffer, base, plusSign, spaceNoSign, lengthSpec, leftJustify, zeroPad);
displayString(intStrBuffer, &chars); displayString(intStrBuffer, &chars);
break; break;
@ -380,7 +380,7 @@ int vprintf (const char* format, va_list list)
*(va_arg(list, intmax_t*)) = chars; *(va_arg(list, intmax_t*)) = chars;
break; break;
case 'z': case 'z':
*(va_arg(list, size_t*)) = chars; *(va_arg(list, usize*)) = chars;
break; break;
case 't': case 't':
*(va_arg(list, ptrdiff_t*)) = chars; *(va_arg(list, ptrdiff_t*)) = chars;

View file

@ -1,9 +1,9 @@
#include <std/string.h> #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* a = (const unsigned char*) aptr;
const unsigned char* b = (const unsigned char*) bptr; 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]) if (a[i] < b[i])
return -1; return -1;
else if (b[i] < a[i]) else if (b[i] < a[i])
@ -12,36 +12,36 @@ int memcmp(const void* aptr, const void* bptr, size_t size) {
return 0; 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; unsigned char* dst = (unsigned char*) dstptr;
const unsigned char* src = (const unsigned char*) srcptr; 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]; dst[i] = src[i];
return dstptr; 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; unsigned char* dst = (unsigned char*) dstptr;
const unsigned char* src = (const unsigned char*) srcptr; const unsigned char* src = (const unsigned char*) srcptr;
if (dst < src) { if (dst < src) {
for (size_t i = 0; i < size; i++) for (usize i = 0; i < size; i++)
dst[i] = src[i]; dst[i] = src[i];
} else { } else {
for (size_t i = size; i != 0; i--) for (usize i = size; i != 0; i--)
dst[i-1] = src[i-1]; dst[i-1] = src[i-1];
} }
return dstptr; 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; 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; buf[i] = (unsigned char) value;
return bufptr; return bufptr;
} }
size_t strlen(const char* str) { usize strlen(const char* str) {
size_t len = 0; usize len = 0;
while (str[len]) while (str[len])
len++; len++;
return len; return len;

View file

@ -1,18 +1,13 @@
#include <std/util.h> #include <std/util.h>
void* malloc(size_t amount) { static usize rand_next = 1;
char variable[amount];
return &variable;
}
static size_t rand_next = 1;
int rand(void) { int rand(void) {
rand_next = rand_next * 1103515245 + 12345; 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; rand_next = seed;
} }
@ -47,4 +42,4 @@ unsigned int atoi(const char *in) {
size += ((in[j - 1] - '0') * count); size += ((in[j - 1] - '0') * count);
return size; return size;
} }

View file

@ -1,9 +1,5 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
// AHCI driver, source: https://wiki.osdev.org/AHCI // AHCI driver, source: https://wiki.osdev.org/AHCI
// FIS = Frame Information Structure // FIS = Frame Information Structure
@ -23,51 +19,51 @@ typedef enum {
// ---- Various other FIS things (this struct was not found in OSDev wiki) // ---- Various other FIS things (this struct was not found in OSDev wiki)
typedef struct tagFIS_SET_DEVICE_BITS { typedef struct tagFIS_SET_DEVICE_BITS {
uint8_t fis_type; u8 fis_type;
uint8_t pmport:4; u8 pmport:4;
uint8_t rsvd:2; u8 rsvd:2;
uint8_t i:1; u8 i:1;
uint8_t n:1; u8 n:1;
uint8_t statusl:3; u8 statusl:3;
uint8_t rsvd2:1; u8 rsvd2:1;
uint8_t statush:3; u8 statush:3;
uint8_t rsvd3:1; u8 rsvd3:1;
uint8_t error; u8 error;
} FIS_DEV_BITS; } FIS_DEV_BITS;
// ---- Register FIS - Host to Device ---- // ---- Register FIS - Host to Device ----
typedef struct tagFIS_REG_H2D typedef struct tagFIS_REG_H2D
{ {
// DWORD 0 // DWORD 0
uint8_t fis_type; // FIS_TYPE_REG_H2D u8 fis_type; // FIS_TYPE_REG_H2D
uint8_t pmport:4; // Port multiplier u8 pmport:4; // Port multiplier
uint8_t rsv0:3; // Reserved u8 rsv0:3; // Reserved
uint8_t c:1; // 1: Command, 0: Control u8 c:1; // 1: Command, 0: Control
uint8_t command; // Command register u8 command; // Command register
uint8_t featurel; // Feature register, 7:0 u8 featurel; // Feature register, 7:0
// DWORD 1 // DWORD 1
uint8_t lba0; // LBA low register, 7:0 u8 lba0; // LBA low register, 7:0
uint8_t lba1; // LBA mid register, 15:8 u8 lba1; // LBA mid register, 15:8
uint8_t lba2; // LBA high register, 23:16 u8 lba2; // LBA high register, 23:16
uint8_t device; // Device register u8 device; // Device register
// DWORD 2 // DWORD 2
uint8_t lba3; // LBA register, 31:24 u8 lba3; // LBA register, 31:24
uint8_t lba4; // LBA register, 39:32 u8 lba4; // LBA register, 39:32
uint8_t lba5; // LBA register, 47:40 u8 lba5; // LBA register, 47:40
uint8_t featureh; // Feature register, 15:8 u8 featureh; // Feature register, 15:8
// DWORD 3 // DWORD 3
uint8_t countl; // Count register, 7:0 u8 countl; // Count register, 7:0
uint8_t counth; // Count register, 15:8 u8 counth; // Count register, 15:8
uint8_t icc; // Isochronous command completion u8 icc; // Isochronous command completion
uint8_t control; // Control register u8 control; // Control register
// DWORD 4 // DWORD 4
uint8_t rsv1[4]; // Reserved u8 rsv1[4]; // Reserved
} FIS_REG_H2D; } FIS_REG_H2D;
// ---- Register FIS Device to Host ---- // ---- Register FIS Device to Host ----
@ -75,164 +71,164 @@ typedef struct tagFIS_REG_H2D
typedef struct tagFIS_REG_D2H typedef struct tagFIS_REG_D2H
{ {
// DWORD 0 // DWORD 0
uint8_t fis_type; // FIS_TYPE_REG_D2H u8 fis_type; // FIS_TYPE_REG_D2H
uint8_t pmport:4; // Port multiplier u8 pmport:4; // Port multiplier
uint8_t rsv0:2; // Reserved u8 rsv0:2; // Reserved
uint8_t i:1; // Interrupt bit u8 i:1; // Interrupt bit
uint8_t rsv1:1; // Reserved u8 rsv1:1; // Reserved
uint8_t status; // Status register u8 status; // Status register
uint8_t error; // Error register u8 error; // Error register
// DWORD 1 // DWORD 1
uint8_t lba0; // LBA low register, 7:0 u8 lba0; // LBA low register, 7:0
uint8_t lba1; // LBA mid register, 15:8 u8 lba1; // LBA mid register, 15:8
uint8_t lba2; // LBA high register, 23:16 u8 lba2; // LBA high register, 23:16
uint8_t device; // Device register u8 device; // Device register
// DWORD 2 // DWORD 2
uint8_t lba3; // LBA register, 31:24 u8 lba3; // LBA register, 31:24
uint8_t lba4; // LBA register, 39:32 u8 lba4; // LBA register, 39:32
uint8_t lba5; // LBA register, 47:40 u8 lba5; // LBA register, 47:40
uint8_t rsv2; // Reserved u8 rsv2; // Reserved
// DWORD 3 // DWORD 3
uint8_t countl; // Count register, 7:0 u8 countl; // Count register, 7:0
uint8_t counth; // Count register, 15:8 u8 counth; // Count register, 15:8
uint8_t rsv3[2]; // Reserved u8 rsv3[2]; // Reserved
// DWORD 4 // DWORD 4
uint8_t rsv4[4]; // Reserved u8 rsv4[4]; // Reserved
} FIS_REG_D2H; } FIS_REG_D2H;
// ---- Data FIS Bidirectional ---- // ---- Data FIS Bidirectional ----
// This FIS is used by the host or device to send data payload. The data size can be varied. // This FIS is used by the host or device to send data payload. The data size can be varied.
typedef struct tagFIS_DATA { typedef struct tagFIS_DATA {
// DWORD 0 // DWORD 0
uint8_t fis_type; // FIS_TYPE_DATA u8 fis_type; // FIS_TYPE_DATA
uint8_t pmport:4; // Port multiplier u8 pmport:4; // Port multiplier
uint8_t rsv0:4; // Reserved u8 rsv0:4; // Reserved
uint8_t rsv1[2]; // Reserved u8 rsv1[2]; // Reserved
// DWORD 1 ~ N // DWORD 1 ~ N
uint32_t data[1]; // Payload u32 data[1]; // Payload
} FIS_DATA; } FIS_DATA;
// ---- PIO Setup Device to Host ---- // ---- PIO Setup Device to Host ----
// This FIS is used by the device to tell the host that its about to send or ready to receive a PIO data payload. // This FIS is used by the device to tell the host that its about to send or ready to receive a PIO data payload.
typedef struct tagFIS_PIO_SETUP { typedef struct tagFIS_PIO_SETUP {
// DWORD 0 // DWORD 0
uint8_t fis_type; // FIS_TYPE_PIO_SETUP u8 fis_type; // FIS_TYPE_PIO_SETUP
uint8_t pmport:4; // Port multiplier u8 pmport:4; // Port multiplier
uint8_t rsv0:1; // Reserved u8 rsv0:1; // Reserved
uint8_t d:1; // Data transfer direction, 1 - device to host u8 d:1; // Data transfer direction, 1 - device to host
uint8_t i:1; // Interrupt bit u8 i:1; // Interrupt bit
uint8_t rsv1:1; u8 rsv1:1;
uint8_t status; // Status register u8 status; // Status register
uint8_t error; // Error register u8 error; // Error register
// DWORD 1 // DWORD 1
uint8_t lba0; // LBA low register, 7:0 u8 lba0; // LBA low register, 7:0
uint8_t lba1; // LBA mid register, 15:8 u8 lba1; // LBA mid register, 15:8
uint8_t lba2; // LBA high register, 23:16 u8 lba2; // LBA high register, 23:16
uint8_t device; // Device register u8 device; // Device register
// DWORD 2 // DWORD 2
uint8_t lba3; // LBA register, 31:24 u8 lba3; // LBA register, 31:24
uint8_t lba4; // LBA register, 39:32 u8 lba4; // LBA register, 39:32
uint8_t lba5; // LBA register, 47:40 u8 lba5; // LBA register, 47:40
uint8_t rsv2; // Reserved u8 rsv2; // Reserved
// DWORD 3 // DWORD 3
uint8_t countl; // Count register, 7:0 u8 countl; // Count register, 7:0
uint8_t counth; // Count register, 15:8 u8 counth; // Count register, 15:8
uint8_t rsv3; // Reserved u8 rsv3; // Reserved
uint8_t e_status; // New value of status register u8 e_status; // New value of status register
// DWORD 4 // DWORD 4
uint16_t tc; // Transfer count u16 tc; // Transfer count
uint8_t rsv4[2]; // Reserved u8 rsv4[2]; // Reserved
} FIS_PIO_SETUP; } FIS_PIO_SETUP;
// ---- DMA Setup Device to Host ---- // ---- DMA Setup Device to Host ----
typedef struct tagFIS_DMA_SETUP { typedef struct tagFIS_DMA_SETUP {
// DWORD 0 // DWORD 0
uint8_t fis_type; // FIS_TYPE_DMA_SETUP u8 fis_type; // FIS_TYPE_DMA_SETUP
uint8_t pmport:4; // Port multiplier u8 pmport:4; // Port multiplier
uint8_t rsv0:1; // Reserved u8 rsv0:1; // Reserved
uint8_t d:1; // Data transfer direction, 1 - device to host u8 d:1; // Data transfer direction, 1 - device to host
uint8_t i:1; // Interrupt bit u8 i:1; // Interrupt bit
uint8_t a:1; // Auto-activate. Specifies if DMA Activate FIS is needed u8 a:1; // Auto-activate. Specifies if DMA Activate FIS is needed
uint8_t rsved[2]; // Reserved u8 rsved[2]; // Reserved
//DWORD 1&2 //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 //DWORD 3
uint32_t rsvd; //More reserved u32 rsvd; //More reserved
//DWORD 4 //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 //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 //DWORD 6
uint32_t resvd; //Reserved u32 resvd; //Reserved
} FIS_DMA_SETUP; } FIS_DMA_SETUP;
// ---- Memory structs (HBA memory registers) ---- // ---- Memory structs (HBA memory registers) ----
typedef volatile struct tagHBA_PORT { typedef volatile struct tagHBA_PORT {
uint32_t clb; // 0x00, command list base address, 1K-byte aligned u32 clb; // 0x00, command list base address, 1K-byte aligned
uint32_t clbu; // 0x04, command list base address upper 32 bits u32 clbu; // 0x04, command list base address upper 32 bits
uint32_t fb; // 0x08, FIS base address, 256-byte aligned u32 fb; // 0x08, FIS base address, 256-byte aligned
uint32_t fbu; // 0x0C, FIS base address upper 32 bits u32 fbu; // 0x0C, FIS base address upper 32 bits
uint32_t is; // 0x10, interrupt status u32 is; // 0x10, interrupt status
uint32_t ie; // 0x14, interrupt enable u32 ie; // 0x14, interrupt enable
uint32_t cmd; // 0x18, command and status u32 cmd; // 0x18, command and status
uint32_t rsv0; // 0x1C, Reserved u32 rsv0; // 0x1C, Reserved
uint32_t tfd; // 0x20, task file data u32 tfd; // 0x20, task file data
uint32_t sig; // 0x24, signature u32 sig; // 0x24, signature
uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) u32 ssts; // 0x28, SATA status (SCR0:SStatus)
uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) u32 sctl; // 0x2C, SATA control (SCR2:SControl)
uint32_t serr; // 0x30, SATA error (SCR1:SError) u32 serr; // 0x30, SATA error (SCR1:SError)
uint32_t sact; // 0x34, SATA active (SCR3:SActive) u32 sact; // 0x34, SATA active (SCR3:SActive)
uint32_t ci; // 0x38, command issue u32 ci; // 0x38, command issue
uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification) u32 sntf; // 0x3C, SATA notification (SCR4:SNotification)
uint32_t fbs; // 0x40, FIS-based switch control u32 fbs; // 0x40, FIS-based switch control
uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved u32 rsv1[11]; // 0x44 ~ 0x6F, Reserved
uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific u32 vendor[4]; // 0x70 ~ 0x7F, vendor specific
} HBA_PORT; } HBA_PORT;
typedef volatile struct tagHBA_MEM { typedef volatile struct tagHBA_MEM {
// 0x00 - 0x2B, Generic Host Control // 0x00 - 0x2B, Generic Host Control
uint32_t cap; // 0x00, Host capability u32 cap; // 0x00, Host capability
uint32_t ghc; // 0x04, Global host control u32 ghc; // 0x04, Global host control
uint32_t is; // 0x08, Interrupt status u32 is; // 0x08, Interrupt status
uint32_t pi; // 0x0C, Port implemented u32 pi; // 0x0C, Port implemented
uint32_t vs; // 0x10, Version u32 vs; // 0x10, Version
uint32_t ccc_ctl; // 0x14, Command completion coalescing control u32 ccc_ctl; // 0x14, Command completion coalescing control
uint32_t ccc_pts; // 0x18, Command completion coalescing ports u32 ccc_pts; // 0x18, Command completion coalescing ports
uint32_t em_loc; // 0x1C, Enclosure management location u32 em_loc; // 0x1C, Enclosure management location
uint32_t em_ctl; // 0x20, Enclosure management control u32 em_ctl; // 0x20, Enclosure management control
uint32_t cap2; // 0x24, Host capabilities extended u32 cap2; // 0x24, Host capabilities extended
uint32_t bohc; // 0x28, BIOS/OS handoff control and status u32 bohc; // 0x28, BIOS/OS handoff control and status
// 0x2C - 0x9F, Reserved // 0x2C - 0x9F, Reserved
uint8_t rsv[0xA0-0x2C]; u8 rsv[0xA0-0x2C];
// 0xA0 - 0xFF, Vendor specific registers // 0xA0 - 0xFF, Vendor specific registers
uint8_t vendor[0x100-0xA0]; u8 vendor[0x100-0xA0];
// 0x100 - 0x10FF, Port control registers // 0x100 - 0x10FF, Port control registers
HBA_PORT ports[1]; // 1 ~ 32 HBA_PORT ports[1]; // 1 ~ 32
@ -242,75 +238,75 @@ typedef volatile struct tagHBA_MEM {
typedef volatile struct tagHBA_FIS { typedef volatile struct tagHBA_FIS {
// 0x00 // 0x00
FIS_DMA_SETUP dsfis; // DMA Setup FIS FIS_DMA_SETUP dsfis; // DMA Setup FIS
uint8_t pad0[4]; u8 pad0[4];
// 0x20 // 0x20
FIS_PIO_SETUP psfis; // PIO Setup FIS FIS_PIO_SETUP psfis; // PIO Setup FIS
uint8_t pad1[12]; u8 pad1[12];
// 0x40 // 0x40
FIS_REG_D2H rfis; // Register Device to Host FIS FIS_REG_D2H rfis; // Register Device to Host FIS
uint8_t pad2[4]; u8 pad2[4];
// 0x58 // 0x58
FIS_DEV_BITS sdbfis; // Set Device Bit FIS FIS_DEV_BITS sdbfis; // Set Device Bit FIS
// 0x60 // 0x60
uint8_t ufis[64]; u8 ufis[64];
// 0xA0 // 0xA0
uint8_t rsv[0x100-0xA0]; u8 rsv[0x100-0xA0];
} HBA_FIS; } HBA_FIS;
// ---- Command List ---- // ---- Command List ----
typedef struct tagHBA_CMD_HEADER { typedef struct tagHBA_CMD_HEADER {
// DW0 // DW0
uint8_t cfl:5; // Command FIS length in DWORDS, 2 ~ 16 u8 cfl:5; // Command FIS length in DWORDS, 2 ~ 16
uint8_t a:1; // ATAPI u8 a:1; // ATAPI
uint8_t w:1; // Write, 1: H2D, 0: D2H u8 w:1; // Write, 1: H2D, 0: D2H
uint8_t p:1; // Prefetchable u8 p:1; // Prefetchable
uint8_t r:1; // Reset u8 r:1; // Reset
uint8_t b:1; // BIST u8 b:1; // BIST
uint8_t c:1; // Clear busy upon R_OK u8 c:1; // Clear busy upon R_OK
uint8_t rsv0:1; // Reserved u8 rsv0:1; // Reserved
uint8_t pmp:4; // Port multiplier port 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 // DW1
volatile volatile
uint32_t prdbc; // Physical region descriptor byte count transferred u32 prdbc; // Physical region descriptor byte count transferred
// DW2, 3 // DW2, 3
uint32_t ctba; // Command table descriptor base address u32 ctba; // Command table descriptor base address
uint32_t ctbau; // Command table descriptor base address upper 32 bits u32 ctbau; // Command table descriptor base address upper 32 bits
// DW4 - 7 // DW4 - 7
uint32_t rsv1[4]; // Reserved u32 rsv1[4]; // Reserved
} HBA_CMD_HEADER; } HBA_CMD_HEADER;
// ---- Command Table and Physical Region Descriptor Table ---- // ---- Command Table and Physical Region Descriptor Table ----
typedef struct tagHBA_PRDT_ENTRY { typedef struct tagHBA_PRDT_ENTRY {
uint32_t dba; // Data base address u32 dba; // Data base address
uint32_t dbau; // Data base address upper 32 bits u32 dbau; // Data base address upper 32 bits
uint32_t rsv0; // Reserved u32 rsv0; // Reserved
// DW3 // DW3
uint32_t dbc:22; // Byte count, 4M max u32 dbc:22; // Byte count, 4M max
uint32_t rsv1:9; // Reserved u32 rsv1:9; // Reserved
uint32_t i:1; // Interrupt on completion u32 i:1; // Interrupt on completion
} HBA_PRDT_ENTRY; } HBA_PRDT_ENTRY;
typedef struct tagHBA_CMD_TBL { typedef struct tagHBA_CMD_TBL {
// 0x00 // 0x00
uint8_t cfis[64]; // Command FIS u8 cfis[64]; // Command FIS
// 0x40 // 0x40
uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes u8 acmd[16]; // ATAPI command, 12 or 16 bytes
// 0x50 // 0x50
uint8_t rsv[48]; // Reserved u8 rsv[48]; // Reserved
// 0x80 // 0x80
HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535 HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
@ -345,7 +341,3 @@ typedef struct tagHBA_CMD_TBL {
// ---- Functions ---- // ---- Functions ----
void ahci_init(void); void ahci_init(void);
#ifdef __cplusplus
}
#endif

View file

@ -1,9 +1,5 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct device { struct device {
void* (*write)(void* data); void* (*write)(void* data);
void* (*read)(void* data); void* (*read)(void* data);
@ -13,7 +9,3 @@ int push_device(struct device device);
void* read(int descriptor, void* data); void* read(int descriptor, void* data);
void* write(int descriptor, void* data); void* write(int descriptor, void* data);
#ifdef __cplusplus
}
#endif

View file

@ -1,11 +1,7 @@
#pragma once #pragma once
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus #include <types.h>
extern "C" {
#endif
// ----> IDE Driver // ----> IDE Driver
// Source: https://wiki.osdev.org/PCI_IDE_Controller // Source: https://wiki.osdev.org/PCI_IDE_Controller
@ -103,8 +99,4 @@ extern "C" {
// ---- Functions ----- // ---- Functions -----
void ide_init(); void ide_init();
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);
#ifdef __cplusplus
}
#endif

View file

@ -1,34 +1,33 @@
#pragma once #pragma once
#include <stdint.h> #include <types.h>
#include <std/util.h> #include <std/util.h>
#ifdef __cplusplus #define KERNEL_CODE_SEGMENT_OFFSET 40
extern "C" {
#endif
#define KERNEL_CODE_SEGMENT_OFFSET 0x08
#define INTERRUPT_GATE 0x8e #define INTERRUPT_GATE 0x8e
struct idt_entry { typedef struct {
unsigned short int offset_lowerbits; u16 isr_low; // The lower 16 bits of the ISR's address
unsigned short int selector; u16 kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
unsigned char zero; u8 ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
unsigned char type_attr; u8 attributes; // Type and attributes; see the IDT page
unsigned short int offset_higherbits; 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 ip;
uintptr_t cs; uintptr_t cs;
uintptr_t flags; uintptr_t flags;
uintptr_t sp; uintptr_t sp;
uintptr_t ss; uintptr_t ss;
}; } interrupt_frame_t;
void idt_init(); void idt_init();
void idt_register_handler(uint8_t interrupt, unsigned long address); void idt_set_entry(u8 vector, void* isr, u8 flags);
#ifdef __cplusplus
}
#endif

View file

@ -2,12 +2,4 @@
#include <drivers/idt/idt.h> #include <drivers/idt/idt.h>
#ifdef __cplusplus
extern "C" {
#endif
void isr_install(void); void isr_install(void);
#ifdef __cplusplus
}
#endif

View file

@ -5,16 +5,8 @@
#include <std/util.h> #include <std/util.h>
#include <std/string.h> #include <std/string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define KBD_BUF_SIZE 256 #define KBD_BUF_SIZE 256
int keyboard_init(void); int keyboard_init(void);
uint8_t keyboard_enabled(void); u8 keyboard_enabled(void);
unsigned char keyboard_get_key_from_scancode(unsigned char scancode); unsigned char keyboard_get_key_from_scancode(unsigned char scancode);
#ifdef __cplusplus
}
#endif

View file

@ -2,10 +2,6 @@
#include <std/inline.h> #include <std/inline.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PIC1 0x20 #define PIC1 0x20
#define PIC2 0xA0 #define PIC2 0xA0
#define PIC1_COMMAND PIC1 #define PIC1_COMMAND PIC1
@ -19,10 +15,6 @@ extern "C" {
#define ICW4_8086 0x01 #define ICW4_8086 0x01
void pic_init(); void pic_init();
void pic_send_eoi(uint8_t no); void pic_send_eoi(u8 no);
void pic_irq_enable(uint8_t no); void pic_irq_enable(u8 no);
void pic_irq_disable(uint8_t no); void pic_irq_disable(u8 no);
#ifdef __cplusplus
}
#endif

View file

@ -1,9 +1,5 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct tar_header struct tar_header
{ {
char filename[100]; char filename[100];
@ -18,7 +14,3 @@ struct tar_header
}; };
struct tar_header* tar_seek(int fd, char filename[100]); struct tar_header* tar_seek(int fd, char filename[100]);
#ifdef __cplusplus
}
#endif

View file

@ -1,16 +1,12 @@
#pragma once #pragma once
#include <stddef.h>
#include <stdint.h> #include <types.h>
#include <std/string.h> #include <std/string.h>
#include <std/inline.h> #include <std/inline.h>
#include <drivers/ide/ide.h> #include <drivers/ide/ide.h>
#include <psf.h> #include <psf.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Hardware text mode color constants. */ /* Hardware text mode color constants. */
enum vga_color { enum vga_color {
VGA_COLOR_BLACK = 0, VGA_COLOR_BLACK = 0,
@ -31,33 +27,32 @@ enum vga_color {
VGA_COLOR_WHITE = 15, 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); return fg | (bg << 4);
} }
static inline uint16_t vga_entry(const uint8_t uc, const uint8_t color) { static inline u16 vga_entry(const u8 uc, const u8 color) {
return (uint16_t) uc | (uint16_t) color << 8; return (u16) uc | (u16) color << 8;
} }
static const size_t VGA_WIDTH = 80; static usize terminal_width;
static const size_t VGA_HEIGHT = 25; static usize terminal_height;
extern size_t terminal_row; extern usize terminal_row;
extern size_t terminal_column; extern usize terminal_column;
extern uint8_t terminal_color; extern u8 terminal_color;
extern uint16_t *terminal_buffer; extern u16 *terminal_buffer;
void terminal_clear(); void terminal_clear();
int terminal_initialize(framebuffer_t *terminal_fb); int terminal_initialize(framebuffer_t *terminal_fb);
void terminal_setcolor(uint8_t color); void terminal_setcolor(u8 color);
void terminal_clearline(size_t line); void terminal_clearline(usize line);
void terminal_clearlines(size_t from, size_t to); void terminal_clearlines(usize from, usize to);
void terminal_updatecursor(); void terminal_updatecursor();
void terminal_scrollup();
void terminal_checknewline(); 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_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) { static inline void terminal_writestring(const char *data) {
terminal_write(data, strlen(data)); terminal_write(data, strlen(data));
@ -67,7 +62,3 @@ static inline void terminal_writeline(const char *data) {
terminal_writestring(data); terminal_writestring(data);
terminal_putchar('\n'); terminal_putchar('\n');
} }
#ifdef __cplusplus
}
#endif

View file

@ -1,24 +1,16 @@
#pragma once #pragma once
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus #include <types.h>
extern "C" {
#endif
typedef struct { typedef struct {
uint8_t *address; u8 *address;
uint32_t width; u32 width;
uint32_t height; u32 height;
uint32_t depth; u32 depth;
uint32_t pitch; u32 pitch;
uint32_t pixelwidth; u32 pixelwidth;
} framebuffer_t; } framebuffer_t;
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);
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);
#ifdef __cplusplus
}
#endif

36
include/paging.h Normal file
View 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);

View file

@ -1,24 +1,19 @@
#pragma once #pragma once
#include <stddef.h> #include <types.h>
#include <stdint.h>
#include <framebuffer.h> #include <framebuffer.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PSF_FONT_MAGIC 0x864ab572 #define PSF_FONT_MAGIC 0x864ab572
typedef struct { typedef struct {
uint32_t magic; /* magic bytes to identify PSF */ u32 magic; /* magic bytes to identify PSF */
uint32_t version; /* zero */ u32 version; /* zero */
uint32_t headersize; /* whereet of bitmaps in file, 32 */ u32 headersize; /* whereet of bitmaps in file, 32 */
uint32_t flags; /* 0 if there's no unicode table */ u32 flags; /* 0 if there's no unicode table */
uint32_t numglyph; /* number of glyphs */ u32 numglyph; /* number of glyphs */
uint32_t bytesperglyph; /* size of each glyph */ u32 bytesperglyph; /* size of each glyph */
uint32_t height; /* height in pixels */ u32 height; /* height in pixels */
uint32_t width; /* width in pixels */ u32 width; /* width in pixels */
} PSF_font; } PSF_font;
// these are linked using objcopy // these are linked using objcopy
@ -26,8 +21,4 @@ extern char _binary_font_psfu_start;
extern char _binary_font_psfu_end; extern char _binary_font_psfu_end;
// c is a unicode character, cx and cy are cursor position in characters // 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);
#ifdef __cplusplus
}
#endif

View file

@ -2,14 +2,6 @@
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
inline int isdigit(int c) { inline int isdigit(int c) {
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
#ifdef __cplusplus
}
#endif

View file

@ -1,21 +1,17 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <types.h>
#ifdef __cplusplus static inline void outportb(const u16 port, const u8 val) {
extern "C" {
#endif
static inline void outportb(const uint16_t port, const uint8_t val) {
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); 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) ); 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) ); 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)); asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port));
} }
static inline uint8_t inportb(const uint16_t port) { static inline u8 inportb(const u16 port) {
uint8_t ret; u8 ret;
asm volatile ( "inb %1, %0" : "=a"(ret) : "Nd"(port) ); asm volatile ( "inb %1, %0" : "=a"(ret) : "Nd"(port) );
return ret; return ret;
} }
static inline uint16_t inportw(const uint16_t port) { static inline u16 inportw(const u16 port) {
uint16_t ret; u16 ret;
asm volatile ( "inw %1, %0" : "=a"(ret) : "Nd"(port) ); asm volatile ( "inw %1, %0" : "=a"(ret) : "Nd"(port) );
return ret; return ret;
} }
static inline uint32_t inportl(const uint16_t port) { static inline u32 inportl(const u16 port) {
uint32_t ret; u32 ret;
asm volatile ( "inl %1, %0" : "=a"(ret) : "Nd"(port) ); asm volatile ( "inl %1, %0" : "=a"(ret) : "Nd"(port) );
return ret; return ret;
} }
@ -63,7 +59,3 @@ static inline void insl(unsigned reg, unsigned int *buffer, int quads) {
buffer[index] = inportl(reg); buffer[index] = inportl(reg);
} }
} }
#ifdef __cplusplus
}
#endif

View file

@ -2,16 +2,8 @@
#include <drivers/terminal/terminal.h> #include <drivers/terminal/terminal.h>
#ifdef __cplusplus
extern "C" {
#endif
inline void putchar(char c) { inline void putchar(char c) {
terminal_putchar(c); terminal_putchar(c);
} }
__attribute__ ((format (printf, 1, 2))) int printf (const char* format, ...); __attribute__ ((format (printf, 1, 2))) int printf (const char* format, ...);
#ifdef __cplusplus
}
#endif

View file

@ -1,19 +1,11 @@
#pragma once #pragma once
#include <stddef.h> #include <types.h>
#ifdef __cplusplus int memcmp(const void* aptr, const void* bptr, usize size);
extern "C" { void* memcpy(void* __restrict dstptr, const void* __restrict srcptr, usize size);
#endif void* memmove(void* dstptr, const void* srcptr, usize size);
void* memset(void* bufptr, int value, usize size);
int memcmp(const void* aptr, const void* bptr, size_t size); usize strlen(const char* str);
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);
char* strcpy(char* dst, const char* src); char* strcpy(char* dst, const char* src);
char* strcat(char* dst, const char* src); char* strcat(char* dst, const char* src);
#ifdef __cplusplus
}
#endif

View file

@ -1,21 +1,24 @@
#pragma once #pragma once
#include <stddef.h> #include <types.h>
#ifdef __cplusplus #define LOW_16(address) (u16)((address) & 0xFFFF)
extern "C" { #define HIGH_16(address) (u16)(((address) >> 16) & 0xFFFF)
#endif
#define LOW_16(address) (uint16_t)((address) & 0xFFFF) void* malloc(usize amount);
#define HIGH_16(address) (uint16_t)(((address) >> 16) & 0xFFFF)
void* malloc(size_t amount);
int rand(void); int rand(void);
void srand(size_t seed); void srand(usize seed);
char* itoa(int res); char* itoa(int res);
unsigned int atoi(const char *in); 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

View file

@ -1,30 +1,30 @@
#ifndef __STIVALE__STIVALE2_H__ #ifndef __STIVALE__STIVALE2_H__
#define __STIVALE__STIVALE2_H__ #define __STIVALE__STIVALE2_H__
#include <stdint.h> #include <types.h>
struct stivale2_tag { struct stivale2_tag {
uint64_t identifier; u64 identifier;
uint64_t next; u64 next;
} __attribute__((__packed__)); } __attribute__((__packed__));
/* --- Header --------------------------------------------------------------- */ /* --- Header --------------------------------------------------------------- */
/* Information passed from the kernel to the bootloader */ /* Information passed from the kernel to the bootloader */
struct stivale2_header { struct stivale2_header {
uint64_t entry_point; u64 entry_point;
uint64_t stack; u64 stack;
uint64_t flags; u64 flags;
uint64_t tags; u64 tags;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_HEADER_TAG_FRAMEBUFFER_ID 0x3ecc1bc43d0f7971 #define STIVALE2_HEADER_TAG_FRAMEBUFFER_ID 0x3ecc1bc43d0f7971
struct stivale2_header_tag_framebuffer { struct stivale2_header_tag_framebuffer {
struct stivale2_tag tag; struct stivale2_tag tag;
uint16_t framebuffer_width; u16 framebuffer_width;
uint16_t framebuffer_height; u16 framebuffer_height;
uint16_t framebuffer_bpp; u16 framebuffer_bpp;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_HEADER_TAG_FB_MTRR_ID 0x4c7bb07731282e00 #define STIVALE2_HEADER_TAG_FB_MTRR_ID 0x4c7bb07731282e00
@ -33,14 +33,14 @@ struct stivale2_header_tag_framebuffer {
struct stivale2_header_tag_terminal { struct stivale2_header_tag_terminal {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t flags; u64 flags;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_HEADER_TAG_SMP_ID 0x1ab015085f3273df #define STIVALE2_HEADER_TAG_SMP_ID 0x1ab015085f3273df
struct stivale2_header_tag_smp { struct stivale2_header_tag_smp {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t flags; u64 flags;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_HEADER_TAG_5LV_PAGING_ID 0x932f477032007e8f #define STIVALE2_HEADER_TAG_5LV_PAGING_ID 0x932f477032007e8f
@ -57,14 +57,14 @@ struct stivale2_struct {
#define STIVALE2_BOOTLOADER_VERSION_SIZE 64 #define STIVALE2_BOOTLOADER_VERSION_SIZE 64
char bootloader_version[STIVALE2_BOOTLOADER_VERSION_SIZE]; char bootloader_version[STIVALE2_BOOTLOADER_VERSION_SIZE];
uint64_t tags; u64 tags;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_CMDLINE_ID 0xe5e76a1b4597a781 #define STIVALE2_STRUCT_TAG_CMDLINE_ID 0xe5e76a1b4597a781
struct stivale2_struct_tag_cmdline { struct stivale2_struct_tag_cmdline {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t cmdline; u64 cmdline;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_MEMMAP_ID 0x2187f79e8612de07 #define STIVALE2_STRUCT_TAG_MEMMAP_ID 0x2187f79e8612de07
@ -79,15 +79,15 @@ struct stivale2_struct_tag_cmdline {
#define STIVALE2_MMAP_FRAMEBUFFER 0x1002 #define STIVALE2_MMAP_FRAMEBUFFER 0x1002
struct stivale2_mmap_entry { struct stivale2_mmap_entry {
uint64_t base; u64 base;
uint64_t length; u64 length;
uint32_t type; u32 type;
uint32_t unused; u32 unused;
} __attribute__((__packed__)); } __attribute__((__packed__));
struct stivale2_struct_tag_memmap { struct stivale2_struct_tag_memmap {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t entries; u64 entries;
struct stivale2_mmap_entry memmap[]; struct stivale2_mmap_entry memmap[];
} __attribute__((__packed__)); } __attribute__((__packed__));
@ -97,26 +97,26 @@ struct stivale2_struct_tag_memmap {
struct stivale2_struct_tag_framebuffer { struct stivale2_struct_tag_framebuffer {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t framebuffer_addr; u64 framebuffer_addr;
uint16_t framebuffer_width; u16 framebuffer_width;
uint16_t framebuffer_height; u16 framebuffer_height;
uint16_t framebuffer_pitch; u16 framebuffer_pitch;
uint16_t framebuffer_bpp; u16 framebuffer_bpp;
uint8_t memory_model; u8 memory_model;
uint8_t red_mask_size; u8 red_mask_size;
uint8_t red_mask_shift; u8 red_mask_shift;
uint8_t green_mask_size; u8 green_mask_size;
uint8_t green_mask_shift; u8 green_mask_shift;
uint8_t blue_mask_size; u8 blue_mask_size;
uint8_t blue_mask_shift; u8 blue_mask_shift;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_EDID_ID 0x968609d7af96b845 #define STIVALE2_STRUCT_TAG_EDID_ID 0x968609d7af96b845
struct stivale2_struct_tag_edid { struct stivale2_struct_tag_edid {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t edid_size; u64 edid_size;
uint8_t edid_information[]; u8 edid_information[];
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_FB_MTRR_ID 0x6bc1a78ebe871172 #define STIVALE2_STRUCT_TAG_FB_MTRR_ID 0x6bc1a78ebe871172
@ -125,17 +125,17 @@ struct stivale2_struct_tag_edid {
struct stivale2_struct_tag_terminal { struct stivale2_struct_tag_terminal {
struct stivale2_tag tag; struct stivale2_tag tag;
uint32_t flags; u32 flags;
uint16_t cols; u16 cols;
uint16_t rows; u16 rows;
uint64_t term_write; u64 term_write;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce #define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce
struct stivale2_module { struct stivale2_module {
uint64_t begin; u64 begin;
uint64_t end; u64 end;
#define STIVALE2_MODULE_STRING_SIZE 128 #define STIVALE2_MODULE_STRING_SIZE 128
char string[STIVALE2_MODULE_STRING_SIZE]; char string[STIVALE2_MODULE_STRING_SIZE];
@ -143,7 +143,7 @@ struct stivale2_module {
struct stivale2_struct_tag_modules { struct stivale2_struct_tag_modules {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t module_count; u64 module_count;
struct stivale2_module modules[]; struct stivale2_module modules[];
} __attribute__((__packed__)); } __attribute__((__packed__));
@ -151,14 +151,14 @@ struct stivale2_struct_tag_modules {
struct stivale2_struct_tag_rsdp { struct stivale2_struct_tag_rsdp {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t rsdp; u64 rsdp;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_EPOCH_ID 0x566a7bed888e1407 #define STIVALE2_STRUCT_TAG_EPOCH_ID 0x566a7bed888e1407
struct stivale2_struct_tag_epoch { struct stivale2_struct_tag_epoch {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t epoch; u64 epoch;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_FIRMWARE_ID 0x359d837855e3858c #define STIVALE2_STRUCT_TAG_FIRMWARE_ID 0x359d837855e3858c
@ -167,55 +167,55 @@ struct stivale2_struct_tag_epoch {
struct stivale2_struct_tag_firmware { struct stivale2_struct_tag_firmware {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t flags; u64 flags;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID 0x4bc5ec15845b558e #define STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID 0x4bc5ec15845b558e
struct stivale2_struct_tag_efi_system_table { struct stivale2_struct_tag_efi_system_table {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t system_table; u64 system_table;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_KERNEL_FILE_ID 0xe599d90c2975584a #define STIVALE2_STRUCT_TAG_KERNEL_FILE_ID 0xe599d90c2975584a
struct stivale2_struct_tag_kernel_file { struct stivale2_struct_tag_kernel_file {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t kernel_file; u64 kernel_file;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID 0xee80847d01506c57 #define STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID 0xee80847d01506c57
struct stivale2_struct_tag_kernel_slide { struct stivale2_struct_tag_kernel_slide {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t kernel_slide; u64 kernel_slide;
} __attribute__((packed)); } __attribute__((packed));
#define STIVALE2_STRUCT_TAG_SMBIOS_ID 0x274bd246c62bf7d1 #define STIVALE2_STRUCT_TAG_SMBIOS_ID 0x274bd246c62bf7d1
struct stivale2_struct_tag_smbios { struct stivale2_struct_tag_smbios {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t flags; u64 flags;
uint64_t smbios_entry_32; u64 smbios_entry_32;
uint64_t smbios_entry_64; u64 smbios_entry_64;
} __attribute__((packed)); } __attribute__((packed));
#define STIVALE2_STRUCT_TAG_SMP_ID 0x34d1d96339647025 #define STIVALE2_STRUCT_TAG_SMP_ID 0x34d1d96339647025
struct stivale2_smp_info { struct stivale2_smp_info {
uint32_t processor_id; u32 processor_id;
uint32_t lapic_id; u32 lapic_id;
uint64_t target_stack; u64 target_stack;
uint64_t goto_address; u64 goto_address;
uint64_t extra_argument; u64 extra_argument;
} __attribute__((__packed__)); } __attribute__((__packed__));
struct stivale2_struct_tag_smp { struct stivale2_struct_tag_smp {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t flags; u64 flags;
uint32_t bsp_lapic_id; u32 bsp_lapic_id;
uint32_t unused; u32 unused;
uint64_t cpu_count; u64 cpu_count;
struct stivale2_smp_info smp_info[]; struct stivale2_smp_info smp_info[];
} __attribute__((__packed__)); } __attribute__((__packed__));
@ -223,29 +223,29 @@ struct stivale2_struct_tag_smp {
struct stivale2_struct_tag_pxe_server_info { struct stivale2_struct_tag_pxe_server_info {
struct stivale2_tag tag; struct stivale2_tag tag;
uint32_t server_ip; u32 server_ip;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_MMIO32_UART 0xb813f9b8dbc78797 #define STIVALE2_STRUCT_TAG_MMIO32_UART 0xb813f9b8dbc78797
struct stivale2_struct_tag_mmio32_uart { struct stivale2_struct_tag_mmio32_uart {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t addr; u64 addr;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_DTB 0xabb29bd49a2833fa #define STIVALE2_STRUCT_TAG_DTB 0xabb29bd49a2833fa
struct stivale2_struct_tag_dtb { struct stivale2_struct_tag_dtb {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t addr; u64 addr;
uint64_t size; u64 size;
} __attribute__((__packed__)); } __attribute__((__packed__));
#define STIVALE2_STRUCT_TAG_VMAP 0xb0ed257db18cb58f #define STIVALE2_STRUCT_TAG_VMAP 0xb0ed257db18cb58f
struct stivale2_struct_vmap { struct stivale2_struct_vmap {
struct stivale2_tag tag; struct stivale2_tag tag;
uint64_t addr; u64 addr;
} __attribute__((__packed__)); } __attribute__((__packed__));
#endif #endif

21
include/types.h Normal file
View 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;

View file

@ -7,7 +7,9 @@ SECTIONS
/* Since we are going to use PIE, this is just the base load address, but the */ /* 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. */ /* bootloader will be able to relocate us as it sees fit. */
. = 0xffffffff80200000; . = 0xffffffff80200000;
_kernel_start = .;
/* We place the .stivale2hdr section containing the header in its own section, */ /* 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. */ /* and we use the KEEP directive on it to make sure it doesn't get discarded. */
.stivale2hdr : { .stivale2hdr : {
@ -31,4 +33,6 @@ SECTIONS
*(COMMON) *(COMMON)
*(.bss*) *(.bss*)
} }
_kernel_end = .;
} }