refactor, new arch dirs, (wip) page alloc on write, hsv screen (convert to userspace later), other fixes

This commit is contained in:
Freya Murphy 2024-02-03 00:50:07 -05:00
parent 6d7a563d36
commit 90a6065691
Signed by: freya
GPG key ID: 744AB800E383AE52
27 changed files with 320 additions and 129 deletions

11
include/bochs.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
#include <stdint.h>
/**
* Loads the framebuffer
* @param width - the width of the screen
* @param height - the height of the screen
*/
uint32_t *bochs_init(uint16_t w, uint16_t h, uint8_t b);

View file

@ -1,5 +0,0 @@
#pragma once
#include <stdint.h>
int fb_init(uint16_t res_x, uint16_t res_y);

13
include/screen.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#include <shim.h>
/**
* Initalizes the screen and framebuffer
*/
void screen_init(void);
/**
* Redraws the screen
*/
void screen_redraw(void);

View file

@ -15,16 +15,17 @@ struct memory_map {
struct memory_segment entries[MMAP_MAX_ENTRY];
};
//struct framebuffer {
// uint64_t addr;
// uint32_t pitch;
// uint32_t width;
// uint32_t height;
// uint8_t bit_depth;
//};
struct framebuffer {
uint64_t addr;
uint32_t pitch;
uint32_t width;
uint32_t height;
uint8_t bit_depth;
};
struct boot_info {
struct memory_map map;
struct framebuffer fb;
void *symbol_table;
void *acpi_table;
char cmdline[CMDLINE_MAX];

View file

@ -1,14 +1,12 @@
#include <acpi.h>
#include <lib.h>
#include <memory.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <panic.h>
#include "bindings.h"
#include "memory.h"
/* global state, idk a better way rn */
struct acpi_state state;
struct acpi_header {
char signature[4];
@ -20,7 +18,7 @@ struct acpi_header {
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
};
} __attribute__((packed));
// root system descriptor pointer
// ACPI 1.0
@ -30,7 +28,7 @@ struct rsdp {
char oemid[6];
uint8_t revision;
uint32_t rsdt_addr;
};
} __attribute__((packed));
// eXtended system descriptor pointer
// ACPI 2.0
@ -45,7 +43,7 @@ struct xsdp {
uint64_t xsdt_addr;
uint8_t extendeid_checksum;
uint8_t reserved[3];
};
} __attribute__((packed));
// root system descriptor table
// ACPI 1.0
@ -152,6 +150,9 @@ struct acpi_state {
uint16_t SCI_EN;
};
/* global state, idk a better way rn */
static struct acpi_state state;
static bool checksum(uint8_t *data, size_t len) {
unsigned char sum = 0;
for (size_t i = 0; i < len; i++)
@ -230,6 +231,9 @@ static void *acpi_find_table_xsdt(struct xsdt *xsdt, const char *identifier, int
}
int acpi_init_rsdt(struct rsdt *rsdt) {
kprintf("RSDT: %#016lx\n", (size_t)rsdt);
rsdt = mmap(rsdt, sizeof(struct rsdt));
state.dst.rsdt = rsdt;
@ -278,23 +282,35 @@ int acpi_init(void *rootsdp) {
if (!checksum((uint8_t *)rsdp, sizeof(struct rsdp)))
return -1;
if (strncmp(rsdp->signature, "RSD PTR ", 8) != 0) {
panic("invalid acpi rsdp signature: %.*s\n", 8, rsdp->signature);
}
int res;
if (rsdp->revision == 0) {
kprintf("ACPI 1.0\n");
kprintf("RSDP: %#016lx\n", (size_t)rsdp);
res = acpi_init_rsdt(
(struct rsdt *) (uintptr_t) rsdp->rsdt_addr
);
} else if (rsdp->revision == 2) {
struct xsdp *xsdp = (struct xsdp *) rsdp;
kprintf("ACPI 2.0\n");
kprintf("XSDP: %#016lx\n", (size_t)xsdp);
res = acpi_init_xsdt(
(struct xsdt *) (uintptr_t) xsdp->xsdt_addr
);
} else {
return -1;
panic("invalid acpi rev: %d\n", rsdp->revision);
}
if (res)
if (res) {
kprintf("...acpi failed to load\n\n");
return res;
}
kprintf("\n\n");
int ret = read_s5_addr(&state);
if (!ret)

View file

@ -2,6 +2,7 @@
#include <stddef.h>
#include <backtrace.h>
#include <serial.h>
#include "debugger.h"
struct dr6 {

View file

@ -2,10 +2,10 @@
#include <stddef.h>
#include <lib.h>
#include <panic.h>
#include "debugger.h"
#include "idt.h"
#include "pic.h"
#include "debugger.h"
#include "../paging.h"
#include "../drivers/pic.h"
#define IDT_SIZE 256
@ -148,7 +148,7 @@ void idt_pic_timer(void) {
// print a message once we know the timer works
// but avoid spamming the logs
if (counter == 3) {
kputs("pic timer!\n");
//kputs("pic timer!\n");
}
if (counter <= 3) {
counter++;
@ -158,4 +158,3 @@ void idt_pic_timer(void) {
void idt_pic_keyboard(void) {}
void idt_pic_mouse(void) {}

View file

@ -3,8 +3,9 @@
#include <stdint.h>
#include <panic.h>
#include <pci.h>
#include <bochs.h>
#include "bindings.h"
#include "../bindings.h"
#define INDEX 0x1CE
#define DATA 0x1CF
@ -52,38 +53,21 @@ static void set_mode(uint16_t width, uint16_t height, uint16_t bit_depth, int lf
(clear ? 0 : DATA_NO_CLEAR_MEM));
}
//static void set_bank(uint16_t bank) {
// write(INDEX_BANK, bank);
//}
uint32_t* bochs_init(uint16_t width, uint16_t height, uint8_t bit_depth) {
int fb_init(uint16_t width, uint16_t height) {
set_mode(width, height, 32, true, true);
set_mode(width, height, bit_depth, true, true);
if (!is_available())
panic("bochs framebuffer not avaliable");
return NULL;
struct pci_device bochs = {0};
bool found = pci_findby_id(&bochs, BOCHS_PCI_DEVICE, BOCHS_PCI_VENDOR, NULL);
if (!found)
panic("bochs pci device not avaliable");
return NULL;
uint32_t bar0 = pci_rcfg_d(bochs, PCI_BAR0_D);
uint32_t *fb = (uint32_t*) (uintptr_t) bar0;
fb = mmap(fb, width * height * 4);
uint32_t *addr = (uint32_t*) (uintptr_t) bar0;
addr = mmap(addr, width * height * bit_depth);
for (uint16_t y = 0; y < height; y++) {
for (uint16_t x = 0; x < width; x++) {
double dx = x / (double) width,
dy = y / (double) height,
dz = (2 - dx - dy) / 2;
uint32_t r = (uint32_t)(dx * 255),
g = (uint32_t)(dy * 255),
b = (uint32_t)(dz * 255);
fb[x + y * width] = (b << 0) | (g << 8) | (r << 16);
}
}
return 0;
return addr;
}

View file

@ -3,7 +3,7 @@
#include <panic.h>
#include <lib.h>
#include "bindings.h"
#include "../bindings.h"
#define CONF_ADDR 0xCF8
#define CONF_DATA 0xCFC

View file

@ -1,4 +1,4 @@
#include "bindings.h"
#include "../bindings.h"
#include "pic.h"
#define PIC1 0x20 /* IO base address for master PIC */

View file

@ -1,5 +1,6 @@
#include <serial.h>
#include "bindings.h"
#include "../bindings.h"
#define PORT 0x3F8

View file

@ -1,6 +1,7 @@
#include <fpu.h>
#include <stddef.h>
#include <stdint.h>
#include <lib.h>
void enable_fpu() {
size_t cr4;

View file

@ -1,38 +0,0 @@
ENTRY(start)
SECTIONS {
. = 1M;
kernel_start = .;
.boot BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
}
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
text_start = .;
.text BLOCK(4K) : ALIGN(4K)
{
*(.text)
}
text_end = .;
.bss BLOCK(4K) : ALIGN(4K)
{
*(.bss)
}
kernel_end = .;
}

View file

@ -9,6 +9,7 @@
#define MBOOT_CMDLINE 1
#define MBOOT_MEMORY_MAP 6
#define MBOOT_FRAMEBUFFER 8
#define MBOOT_ELF_SYMBOLS 9
#define MBOOT_OLD_RSDP 14
#define MBOOT_NEW_RSDP 15
@ -82,6 +83,18 @@ struct mboot_tag_cmdline {
uint8_t cmdline[];
};
struct mboot_tag_framebuffer {
uint32_t type;
uint32_t size;
uint64_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint8_t framebuffer_bpp;
uint8_t framebuffer_type;
uint16_t reserved;
};
static void read_symbols(
struct boot_info *shim_info,
struct mboot_tag_elf_sections *sections
@ -133,6 +146,17 @@ static void read_cmdline(
shim_info->cmdline[size] = '\0';
}
static void read_framebuffer(
struct boot_info *shim_info,
struct mboot_tag_framebuffer *framebuffer
) {
shim_info->fb.addr = framebuffer->framebuffer_addr;
shim_info->fb.width = framebuffer->framebuffer_width;
shim_info->fb.height = framebuffer->framebuffer_height;
shim_info->fb.pitch = framebuffer->framebuffer_pitch;
shim_info->fb.bit_depth = framebuffer->framebuffer_bpp;
}
static const char *segment_type[] = {
"Reserved",
"Free",
@ -217,6 +241,12 @@ void mboot_load_info(
(struct mboot_tag_cmdline *) tag
);
break;
case MBOOT_FRAMEBUFFER:
read_framebuffer(
shim_info,
(struct mboot_tag_framebuffer *) tag
);
break;
case MBOOT_MEMORY_MAP:
read_memory_map(
shim_info,

View file

@ -45,7 +45,8 @@ struct pde {
// PAGE TABLE ENTRY
struct pte {
uint64_t flags : 9;
uint64_t : 3;
uint64_t loaded : 1;
uint64_t : 2;
uint64_t address : 40;
uint64_t : 7;
uint64_t protection_key : 4;
@ -69,7 +70,7 @@ static struct pde *pd_mapped = (void *) (uintptr_t) 0x202000;
static struct pte *pt_mapped = (void *) (uintptr_t) 0x203000;
static inline void invlpg(void *addr) {
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
__asm__ volatile("invlpg (%0)" ::"r" (addr) : "memory");
}
static void load_addr(void *phys_addr) {
@ -297,6 +298,7 @@ static void unmap_page(
page->address = 0;
page->flags = 0;
page->loaded = 0;
try_unmap_pt();
@ -360,6 +362,7 @@ static void unmap_pages(
page->address = 0;
page->flags = 0;
page->loaded = 0;
}
@ -369,6 +372,31 @@ static void unmap_pages(
return;
}
static struct pte *get_page(
struct pml4e *root,
void *virt
) {
struct pdpte *pdpt;
struct pde *pd;
struct pte *pt;
struct pte *page;
unsigned int df = 0;
if (select_pdpt(virt, df, root, &pdpt, false))
return NULL;
if (select_pd(virt, df, pdpt, &pd, false))
return NULL;
if (select_pt(virt, df, pd, &pt, false))
return NULL;
select_page(virt, pt, &page);
return page;
}
static int map_page(
struct pml4e *root,
void *virt,
@ -382,6 +410,9 @@ static int map_page(
unsigned int df = F_WRITEABLE;
if (phys == NULL)
df = 0; // alloc page on fault
if (select_pdpt(virt, df, root, &pdpt, true))
return 1;
@ -393,9 +424,16 @@ static int map_page(
select_page(virt, pt, &page);
page->address = (uint64_t)phys >> 12;
page->flags = F_PRESENT | flags;
invlpg(virt);
if (phys) {
page->flags = F_PRESENT | flags;
page->address = (uint64_t)phys >> 12;
page->loaded = 1;
invlpg(virt);
} else {
page->flags = flags;
page->address = 0;
page->loaded = 0;
}
return 0;
}
@ -424,6 +462,9 @@ static int map_pages(
unsigned int df = F_WRITEABLE;
if (phys_start == NULL)
df = 0; // alloc page on fault
long i;
for (i = 0; i < page_count; i++) {
@ -454,15 +495,22 @@ static int map_pages(
select_page(virt, pt, &page);
page->address = (uint64_t)phys >> 12;
page->flags = F_PRESENT | flags;
if (phys_start) {
page->flags = F_PRESENT | flags;
page->address = (uint64_t)phys >> 12;
page->loaded = 1;
} else {
page->flags = flags;
page->address = 0;
page->loaded = 0;
}
if (flags & F_GLOBAL)
invlpg(virt);
}
__asm volatile("mov %cr3, %rax; mov %rax, %cr3;");
__asm__ volatile("mov %cr3, %rax; mov %rax, %cr3;");
return 0;
@ -575,3 +623,21 @@ int kunmap_page(void *virt_addr) {
unmap_page(kernel_pml4, virt_addr);
return 0;
}
int kload_page(void *virt_addr) {
struct pte *page = get_page(kernel_pml4, virt_addr);
if (page == NULL)
return -1;
if (page->loaded)
return -1;
void *phys = alloc_phys_page();
kprintf("0x%p\n", phys);
if (phys == NULL)
return -2;
page->loaded = 1;
page->address = (uint64_t)phys >> 12;
page->flags |= F_PRESENT | F_WRITEABLE;
invlpg(virt_addr);
__asm__ volatile ("movq %cr3, %rax; movq %rax, %cr3;");
return 0;
}

View file

@ -13,3 +13,4 @@
void paging_init(void);
int kmap_page(void *virt_addr, void *phys_addr, unsigned int flags);
int kunmap_page(void *virt_addr);
int kload_page(void *virt_addr);

View file

@ -6,8 +6,8 @@
#include "paging.h"
#include "mboot.h"
#include "idt.h"
#include "pic.h"
#include "cpu/idt.h"
#include "drivers/pic.h"
static struct boot_info boot_info;

View file

@ -1,28 +1,27 @@
#include "fpu.h"
#include <fpu.h>
#include <acpi.h>
#include <memory.h>
#include <lib.h>
#include <fb.h>
#include <serial.h>
#include <shim.h>
#include <panic.h>
#include <pci.h>
#include <screen.h>
void kmain(struct boot_info *info) {
enable_fpu();
memory_init(&info->map);
pci_init();
fb_init(1024, 768);
//acpi_init(info->acpi_table);
screen_init();
acpi_init(info->acpi_table);
kprintf("enterd kmain\n");
*(char *)(0xB8000 + 0x144) = 'h';
*(char *)(0xB8000 + 0x146) = 'i';
char *test = kalloc(5);
*test = 1;
while (1) {
__asm__("hlt;");
// loop so we dont halt
// this allows interrupts to fire
screen_redraw();
}
}

View file

@ -32,7 +32,9 @@ void *memmove(void *dest, const void *src, unsigned long n) {
void *memset(void *restrict dest, int c, unsigned long n) {
unsigned char *d = dest;
for (; n; n--) *d++ = c;
for (; n; n--) {
*d++ = c;
};
return dest;
}

View file

@ -51,7 +51,7 @@ void *kalloc_new(size_t size) {
node = 0;
}
memset(addr, 0, pages * PAGE_SIZE);
memcpy(addr, 0, pages * PAGE_SIZE);
struct page_header *header = addr;
header->magic = 0xBEEFCAFE;
header->used = size;

View file

@ -138,6 +138,7 @@ static struct format_precision read_precision(const char *format, const char **e
if (c == '*' && precision.defined == false) {
precision.defined = true;
precision.varys = true;
format++;
break;
}
@ -336,7 +337,7 @@ static void print_unum(
char buf[1024];
char *str = get_decimal(
num,
buf,
buf + 1023,
sign,
radix,
base
@ -457,11 +458,21 @@ void kvprintf(const char *format, va_list args) {
char c;
const char *str;
void *ptr;
} data;
} data = {0};
int radix = 0;
char base = 0;
if (width.varys) {
int len = va_arg(args, int);
width.value = len;
}
if (precision.varys) {
int len = va_arg(args, int);
precision.value = len;
}
switch (conversion) {
case FMT_INT:
if (modifier == MOD_NONE)
@ -475,7 +486,15 @@ void kvprintf(const char *format, va_list args) {
else if (modifier == MOD_LONG_LONG)
data.l = va_arg(args, long long);
radix = 10;
goto printnum;
print_num(
data.l,
flag,
width,
precision,
radix,
base
);
break;
case FMT_UINT:
case FMT_OCT:
case FMT_HEX_UPPER:
@ -503,6 +522,7 @@ void kvprintf(const char *format, va_list args) {
base = 'A';
}
goto printunum;
break;
case FMT_PTR:
case FMT_PTR_UPPER:
flag |= FLG_ZERO;
@ -513,15 +533,6 @@ void kvprintf(const char *format, va_list args) {
else
base = 'A';
goto printunum;
printnum:
print_num(
data.l,
flag,
width,
precision,
radix,
base
);
break;
printunum:
print_unum(

98
src/screen.c Normal file
View file

@ -0,0 +1,98 @@
#include <lib.h>
#include <screen.h>
#include <bochs.h>
#include <stddef.h>
#include <stdint.h>
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
#define SCREEN_BIT_DEPTH 32
struct rgb {
uint8_t r;
uint8_t g;
uint8_t b;
};
struct hsv {
uint16_t h;
uint16_t s;
uint16_t v;
};
static uint32_t *buffer = NULL;
static uint32_t width, height;
static uint8_t bit_depth;
static uint16_t angle;
static void set_pixel(struct rgb color, uint16_t x, uint16_t y) {
uint32_t offset = y * width + x;
buffer[offset] = (color.b << 0) | (color.g << 8) | (color.r << 16);
}
static float fmod(float f, float m) {
return f - (int)(f / m) * m;
}
static float fabs(float f) {
return f > 0 ? f : -f;
}
static struct rgb htor(struct hsv hsv) {
struct rgb rgb;
float s = hsv.s / 100.0;
float v = hsv.v / 100.0;
float c = s * v;
float x = c * (1-fabs(fmod(hsv.h/60.0, 2) - 1));
float m = v - c;
float r,g,b;
if (hsv.h < 60) {
r = c; g = x; b = 0;
} else if (hsv.h >= 60 && hsv.h < 120) {
r = x; g = c; b = 0;
} else if (hsv.h >= 120 && hsv.h < 180) {
r = 0; g = c; b = x;
} else if (hsv.h >= 180 && hsv.h < 240) {
r = 0; g = x; b = c;
} else if (hsv.h >= 240 && hsv.h < 300) {
r = x; g = 0; b = c;
} else {
r = c; g = 0; b = x;
}
rgb.r = (r + m) * 255;
rgb.g = (g + m) * 255;
rgb.b = (b + m) * 255;
return rgb;
}
static struct rgb get_color(uint16_t a, uint16_t x, uint16_t y) {
struct hsv hsv = {
.h = a,
.s = x * 100.0 / width,
.v = y * 100.0 / height,
};
return htor(hsv);
}
void screen_init(void) {
angle = 0;
width = SCREEN_WIDTH;
height = SCREEN_HEIGHT;
bit_depth = SCREEN_BIT_DEPTH;
buffer = bochs_init(width, height, bit_depth);
}
void screen_redraw(void) {
for (uint16_t y = 0; y < height; y++) {
for (uint16_t x = 0; x < width; x++) {
struct rgb color = get_color(angle, x, height - y);
set_pixel(color, x, y);
}
}
angle++;
angle %= 360;
}