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

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

View file

@ -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");

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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
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
#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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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
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 */
/* 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 = .;
}