Browse Source

paging works

master
Mathieu Serandour 11 months ago
parent
commit
079939eb82
  1. 2
      Makefile
  2. 4
      kernel/acpi/acpi.c
  3. 70
      kernel/entry.c
  4. 9
      kernel/int/apic.c
  5. 2
      kernel/int/apic.h
  6. 1
      kernel/int/isr.c
  7. 2
      kernel/memory/gdt.c
  8. 39
      kernel/memory/paging.c
  9. 2
      kernel/memory/paging.h
  10. 14
      kernel/memory/physical_allocator.c
  11. 23
      kernel/memory/vmap.h
  12. 3
      kernel/video/terminal.c
  13. 7
      kernel/video/terminal.h
  14. 8
      kernel/video/video.c
  15. 3
      kernel/video/video.h

2
Makefile

@ -12,7 +12,7 @@ QEMU_PATH := qemu-system-x86_64
QEMU_ARGS := -monitor stdio \
-bios /usr/share/ovmf/OVMF.fd \
-m 114 \
-m 8192 \
-vga std \
-no-reboot \
-D qemu.log \

4
kernel/acpi/acpi.c

@ -12,7 +12,7 @@
#include "../int/apic.h"
extern struct APICConfig* apic_config;
extern volatile void* physical_config_base;
static bool __ATTR_PURE__ checksum(const void* table, size_t size) {
uint8_t sum = 0;
@ -93,7 +93,7 @@ static void parse_hpet(const struct HPET* table) {
static void parse_madt(const struct MADT* table) {
// checksum is already done
apic_config = (void*)(uint64_t)table->lAPIC_address;
physical_config_base = (void*)(uint64_t)table->lAPIC_address;
const void* ptr = table->entries;
const void* end = (const void*)table + table->header.length;

70
kernel/entry.c

@ -15,6 +15,7 @@
#include "int/idt.h"
#include "memory/physical_allocator.h"
#include "memory/paging.h"
#include "memory/vmap.h"
#define KERNEL_STACK_SIZE 8192
@ -130,48 +131,53 @@ void _start(struct stivale2_struct *stivale2_struct) {
}
// first initialize our terminal
initVideo(fbtag);
setup_terminal();
terminal_set_colors(0xf0f0f0, 0x007000);
terminal_clear();
kputs(&_binary_bootmessage_txt);
setup_isrs();
read_acpi_tables((void*)rsdp_tag_ptr->rsdp);
init_physical_allocator(memmap_tag);
init_paging(memmap_tag);
// cannot print anything around here: the framebuffer isn't mapped
// map MMIOs
map_pages(
early_virtual_to_physical(fbtag->framebuffer_addr),
0xffffffff00000000,
(fbtag->framebuffer_height * fbtag->framebuffer_pitch+0x0fff) / 0x1000,
PRESENT_ENTRY
);
// map lapic registers
map_pages(
get_apic_configuration_physical_space(),
APIC_VIRTUAL_ADDRESS,
1,
PRESENT_ENTRY | PCD
);
// first initialize our terminal
initVideo(fbtag, 0xffffffff00000000);
init_gdt_table();
// we cannot use stivale2 terminal
// after loading our gdt
// so we need to load our gdt after our
// terminal is successfully installed
init_gdt_table();
setup_isrs();
setup_terminal();
append_initialization();
read_acpi_tables((void*)rsdp_tag_ptr->rsdp);
//apic_setup_clock();
// initialize the memory
// as we reclaim the bootloader memory,
// we have to copy the structure to be able
// to use it still
// !!!! WARNING !!!!
// the memory map is allocated on the stack
// that is not a very good idea but it seems to work
struct {
struct stivale2_tag tag;
uint64_t entries;
struct stivale2_mmap_entry memmap[memmap_tag->entries];
} local_memmap_tag;
local_memmap_tag.entries = memmap_tag->entries,
memcpy(local_memmap_tag.memmap, memmap_tag,
sizeof(struct stivale2_mmap_entry) * local_memmap_tag.entries);
init_physical_allocator(&local_memmap_tag);
init_paging(&local_memmap_tag);
terminal_set_colors(0xf0f0f0, 0x007000);
terminal_clear();
kputs(&_binary_bootmessage_txt);
apic_setup_clock();
for(;;) {
asm volatile("hlt");

9
kernel/int/apic.c

@ -4,8 +4,10 @@
#include "idt.h"
#include "apic.h"
#include "../klib/sprintf.h"
#include "../memory/vmap.h"
volatile struct APICConfig* apic_config = NULL;
volatile struct APICConfig* apic_config = APIC_VIRTUAL_ADDRESS;
volatile void* physical_config_base = NULL;
static inline void outb(uint16_t port, uint8_t val)
@ -18,6 +20,11 @@ void set_rflags(uint64_t rf);
uint64_t get_rflags(void);
uint64_t get_apic_configuration_physical_space(void) {
return physical_config_base;
}
static unsigned read_pit_count(void) {
unsigned count = 0;

2
kernel/int/apic.h

@ -50,5 +50,7 @@ struct APICConfig
static_assert(sizeof(struct APICConfig) == 0x400);
uint64_t get_apic_configuration_physical_space(void);
void apic_setup_clock(void);
uint64_t clock(void);

1
kernel/int/isr.c

@ -94,6 +94,7 @@ __attribute__((interrupt)) void ISR_general_protection_fault_handler(struct IFra
}
__attribute__((interrupt)) void ISR_page_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
char buff[128];
//for(;;);
// the content of cr2 is the illegal address
sprintf(buff, "PAGE FAULT. illegal address: %16lx, error code %x\n", _cr2(), error_code);
panic_handler(buff, interrupt_frame);

2
kernel/memory/gdt.c

@ -101,12 +101,12 @@ struct GDTDescriptor gdt_descriptor = {
void init_gdt_table() {
// init GDT TSS entry
gdt[5].base1 = (uint64_t)&tss & 0xfffflu;
gdt[5].base2 = (uint64_t)&tss >> 16 & 0x00ffllu;
gdt[5].base3 = (uint64_t)&tss >> 24 & 0x00ffllu;
*(uint64_t *)(&gdt[6]) = (uint64_t)(&tss) >> 32;
kprintf("0x%16lx = 0x%2x %2x %4x\n", &tss, gdt[5].base3, gdt[5].base2, gdt[5].base1);
_lgdt(&gdt_descriptor);

39
kernel/memory/paging.c

@ -153,7 +153,9 @@ static void map_physical_memory(const struct stivale2_struct_tag_memmap* memmap)
for(unsigned i = 0; i < memmap->entries; i++) {
const struct stivale2_mmap_entry* e = &memmap->memmap[i];
if(e->type == STIVALE2_MMAP_USABLE || e->type == STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE) {
if(e->type == STIVALE2_MMAP_USABLE || e->type == STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE
|| e->type == STIVALE2_MMAP_ACPI_RECLAIMABLE ||
e->type == STIVALE2_MMAP_ACPI_NVS) {
// be inclusive!
uint64_t phys_addr = (uint64_t) (e->base / 0x1000) * 0x1000;
@ -323,24 +325,22 @@ void init_paging(const struct stivale2_struct_tag_memmap* memmap) {
// map the kernel
map_kernel(memmap);
}
// get the physical address of the pml4 table
uint64_t pml4_lower_half_ptr = early_virtual_to_physical(pml4);
void append_initialization(void) {
// enable PAE in cr4
// disable PCIDE
set_cr4((get_cr4() | CR4_PAE_BIT) & ~CR4_PCIDE);
// enable the PG bit
set_cr0(get_cr0() | CR0_PG_BIT);
_cr3(pml4_lower_half_ptr);
// get the physical address of the pml4 table
uint64_t pml4_lower_half_ptr = early_virtual_to_physical(pml4);
*((uint64_t*)0xffff800080000000) = 40;
while ((1));
// finaly set the pml4 to cr3
_cr3(pml4_lower_half_ptr);
kprintf("hello from the future\n");
}
@ -357,17 +357,16 @@ static void page_table_allocator_callback(uint64_t phys_addr,
uint64_t virt_addr,
size_t size) {
(void)(size+virt_addr); // the size is always one whatsoever...
assert(phys_addr < 0x80000000);
page_table_allocator_buffer[page_table_allocator_buffer_size++] = (void*)phys_addr;
}
/*
static void zero_page_table_page(void* physical_address) {
assert_aligned(physical_address, 0x1000);
memset(translate_address(physical_address), 0, 0x1000);
}
*/
// fill the page table allocator buffer
static void fill_page_table_allocator_buffer(size_t n) {
@ -381,8 +380,8 @@ static void fill_page_table_allocator_buffer(size_t n) {
int old_size = page_table_allocator_buffer_size;
physalloc(to_alloc, 0, page_table_allocator_callback);
//for(unsigned i = old_size; i < n; i++)
// zero_page_table_page(page_table_allocator_buffer[i]);
for(unsigned i = old_size; i < n; i++)
zero_page_table_page(page_table_allocator_buffer[i]);
page_table_allocator_buffer_size = n;
}
@ -399,8 +398,8 @@ static void* alloc_page_table(void) {
physalloc(16, 0, page_table_allocator_callback);
page_table_allocator_buffer_size = 16;
//for(int i = 0; i < 16; i++)
// zero_page_table_page(page_table_allocator_buffer[i]);
for(int i = 0; i < 16; i++)
zero_page_table_page(page_table_allocator_buffer[i]);
}
return page_table_allocator_buffer[--page_table_allocator_buffer_size];
@ -450,7 +449,13 @@ void map_pages(uint64_t physical_addr,
while(count > 0 && pti < 512) {
// create a new entry
uint64_t e = create_table_entry((void*)physical_addr,flags);
((void**)translate_address(pdentry))[pti] = e;
void** entry_ptr = (void**)translate_address(pdentry) + pti;
assert(!present_entry(*entry_ptr));
*entry_ptr = e;
pti++;
count--;

2
kernel/memory/paging.h

@ -13,7 +13,7 @@ struct stivale2_struct_tag_memmap;
* map the kernel executable to high half: 0xffffffff80000000 + phys
*/
void init_paging(const struct stivale2_struct_tag_memmap* memmap);
void append_initialization(void);
// page table flags

14
kernel/memory/physical_allocator.c

@ -104,15 +104,9 @@ static void init_memory_range(struct memory_range* range, uint64_t addr, size_t
struct MR_header* header = (struct MR_header *)addr;
kprintf("%x, %x\n", header, length);
// zero all the bit maps
memset(((uint8_t*)header), 0, 0x1000 * (length));
memset(header->bitmap_level3, 0, 128+256+512+2048);
kprintf("issse\n");
// we use one page per region for the header
header->available[0] = (length-1);
@ -131,9 +125,6 @@ static void init_memory_range(struct memory_range* range, uint64_t addr, size_t
mr_lists[i] = range;
break;
}
}
@ -190,9 +181,6 @@ void init_physical_allocator(const struct stivale2_struct_tag_memmap* memmap) {
n_ranges = j;
total_available_pages = total_pages - n_ranges;
kprintf("initializeed %u MB of memory, %u ranges, %u pages\n",
(total_pages - n_ranges) / 256, n_ranges, (total_pages - n_ranges));
}

23
kernel/memory/vmap.h

@ -29,8 +29,21 @@
*
*
*
* detailed MMIO address space:
*
* 0xffffffff00000000 | ---- PCIE ---- |
* | framebuffer |
* | ... |
* | -------------- |
* 0xffffffff1fffe000 | HPET |
* 0xffffffff1ffff000 | LAPIC |
* 0xffffffff20000000 |----------------|
*
*
*/
#define APIC_VIRTUAL_ADDRESS 0xffffffff20000000llu
/**
@ -77,12 +90,18 @@ static inline int is_mmio(uint64_t virtual_address) {
return (virtual_address & KERNEL_DATA_BEGIN) == MMIO_BEGIN;
}
// return the physical address of a
// stivale2 high half pointer
static inline uint64_t early_virtual_to_physical(
const void* virtual_address) {
return ~KERNEL_DATA_BEGIN & (uint64_t)virtual_address;
if((0xfffff00000000000llu & (uint64_t)virtual_address) ==
TRANSLATED_PHYSICAL_MEMORY_BEGIN)
return ~TRANSLATED_PHYSICAL_MEMORY_BEGIN & (uint64_t)virtual_address;
else
return ~KERNEL_DATA_BEGIN & (uint64_t)virtual_address;
}

3
kernel/video/terminal.c

@ -57,6 +57,7 @@ void setup_terminal(void) {
charmap = loadBMP_24b_1b(&_binary_charmap_bmp);
assert(charmap != NULL);
assert(charmap->bpp == 1);
assert(charmap->pitch == 1);
@ -80,8 +81,6 @@ void setup_terminal(void) {
nlines = TERMINAL_N_PAGES * term_nlines;
terminal_clear();
set_terminal_handler(write_string);
}

7
kernel/video/terminal.h

@ -26,6 +26,13 @@ typedef void (*terminal_handler_t)(const char *string, size_t length);
terminal_handler_t get_terminal_handler(void);
// assert everything the setup needs
// because printing error messages
// won't be possible between the change
// of memory paging and the end of the
// setup_function
void assert_terminal(void);
void setup_terminal(void);
void terminal_clear(void);

8
kernel/video/video.c

@ -21,7 +21,8 @@ inline void lower_blit(const Image* src, const Image* dst,
uint16_t dstx, uint16_t dsty,
uint16_t width, uint16_t height);
void initVideo(const struct stivale2_struct_tag_framebuffer* fbtag) {
void initVideo(const struct stivale2_struct_tag_framebuffer* fbtag,
void* frame_buffer_virtual_address) {
assert(fbtag != NULL);
@ -30,7 +31,7 @@ void initVideo(const struct stivale2_struct_tag_framebuffer* fbtag) {
.h = fbtag->framebuffer_height,
.pitch= fbtag->framebuffer_pitch,
.bpp = fbtag->framebuffer_bpp,
.pix = (void*)fbtag->framebuffer_addr
.pix = frame_buffer_virtual_address
};
assert(screen.bpp == 32);
@ -571,7 +572,6 @@ Image* loadBMP_24b_1b(const void* rawFile) {
loadBMP_24b_1b_ret.pitch = ((w+7) / 8);
loadBMP_24b_1b_ret.pix = &__image_pix;
kprintf("%d\n", loadBMP_24b_1b_ret.pitch);
assert(loadBMP_24b_1b_ret.pitch == 1);
assert(w == 6);
assert(h == 2048);
@ -582,11 +582,9 @@ Image* loadBMP_24b_1b(const void* rawFile) {
for(size_t y = 0; y < h; y++) {
uint8_t byte = 0;
for(size_t x = 0; x < w; x++) {
const uint8_t* src_ptr = (srcpix + 20 * (h-1 - y) + 3 * (w-1-x));
byte <<= 1;
// put 1 iif r channel > 128
byte |= *(src_ptr) >> 7;

3
kernel/video/video.h

@ -25,7 +25,8 @@ typedef struct
const Image *getScreenImage(void);
void initVideo(const struct stivale2_struct_tag_framebuffer* fbtag);
void initVideo(const struct stivale2_struct_tag_framebuffer* fbtag,
void* frame_buffer_virtual_address);
void imageDraw(const Image *img, const Pos *srcpos, const Rect *dstrect);
void imageLower_blit(

Loading…
Cancel
Save