Skip to content

Commit

Permalink
Move paging related functions to paging.c
Browse files Browse the repository at this point in the history
  • Loading branch information
taikiy committed Dec 29, 2023
1 parent 459b80a commit ab34302
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 151 deletions.
1 change: 1 addition & 0 deletions doc/13_calling_kernel_space_routines_from_user_space.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ print:

- Interrupt 0x80 handler [commit](https://github.com/taikiy/kernel/commit/42c0b6374e21e096060d27e3255a2e007c55b0cd)
- Register 0x80 handler in IDT [commit](https://github.com/taikiy/kernel/commit/2020d58d9047f2584ab03d95ccfab2b221ff2ced)
- `sys_print` function [commit](https://github.com/taikiy/kernel/commit/459b80a2d26d9ff61d42f026305b79abbe5acf4f)
1 change: 1 addition & 0 deletions src/gdt/gdt.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "gdt.h"
#include "config.h"
#include "memory/memory.h"
#include "system/sys.h"
#include "task/tss.h"

struct tss tss;
Expand Down
1 change: 0 additions & 1 deletion src/gdt/gdt.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef GDT_H
#define GDT_H

#include "kernel.h"
#include <stdint.h>

/* clang-format off
Expand Down
1 change: 0 additions & 1 deletion src/idt/idt.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "idt.h"
#include "config.h"
#include "io/io.h"
#include "kernel.h"
#include "memory/memory.h"
#include "system/syscall.h"
#include "task/task.h"
Expand Down
9 changes: 0 additions & 9 deletions src/kernel.asm
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[BITS 32]

global _start
global set_kernel_segment_registers

extern kernel_main

Expand Down Expand Up @@ -39,14 +38,6 @@ _start:
; cli ; Disables interrupts
; hlt ; This hangs the computer

set_kernel_segment_registers:
mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
ret

times 512 - ($ - $$) db 0 ; Pad the kernel code sector to 512 bytes
; This ensures that any object files written in C and linked with this assembly
; will be correctly aligned.
28 changes: 1 addition & 27 deletions src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,18 @@
#include "memory/paging/paging.h"
#include "status.h"
#include "string/string.h"
#include "system/sys.h"
#include "system/syscall.h"
#include "task/process.h"
#include "task/task.h"
#include "task/tss.h"
#include "terminal/terminal.h"

extern void set_kernel_segment_registers();
void test_path_parser();
void test_file_system();
void test_user_space();
void test_syscall();

void
panic(const char* message)
{
print("PANIC: ");
print(message);
print("\n");
while (1) {};
}

static struct paging_map* kernel_page = 0;

void
initialize_kernel_space_paging()
{
kernel_page = new_paging_map(PAGING_IS_WRITABLE | PAGING_IS_PRESENT | PAGING_ACCESS_FROM_ALL);
switch_page(kernel_page);
enable_paging();
}

void
switch_to_kernel_page()
{
set_kernel_segment_registers();
switch_page(kernel_page);
}

void
kernel_main()
{
Expand Down
2 changes: 0 additions & 2 deletions src/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@
#define KERNEL_H

void kernel_main();
void switch_to_kernel_page();
void panic(const char* message);

#endif
21 changes: 21 additions & 0 deletions src/memory/paging/paging.asm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ section .asm

global load_directory
global enable_paging
global set_kernel_segment_registers
global set_user_segment_registers

KERNEL_DATA_SEG equ 0x10
USER_DATA_SEG equ 0x23 ; user data segment | flags: 0x3

load_directory:
push ebp
Expand All @@ -25,3 +30,19 @@ enable_paging:

pop ebp
ret

set_kernel_segment_registers:
mov ax, KERNEL_DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
ret

set_user_segment_registers:
mov ax, USER_DATA_SEG
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
ret
137 changes: 84 additions & 53 deletions src/memory/paging/paging.c
Original file line number Diff line number Diff line change
@@ -1,65 +1,21 @@
#include "paging.h"
#include "memory/heap/kheap.h"
#include "system/sys.h"
#include "task/task.h"

void load_directory(uint32_t* directory);
extern void load_directory(uint32_t* directory);
extern void enable_paging();

static struct paging_map* kernel_page = 0;
static uint32_t* current_directory = 0;

struct paging_map*
new_paging_map(uint8_t flags)
{
// allocate a linear memory space for a page directory (1024 entries)
uint32_t* directory = kzalloc(sizeof(uint32_t) * PAGING_TOTAL_ENTRIES);
int offset = 0;

for (int i = 0; i < PAGING_TOTAL_ENTRIES; i++) {
// allocate a linear memory for a page table (1024 entries)
uint32_t* table = kzalloc(sizeof(uint32_t) * PAGING_TOTAL_ENTRIES);

for (int j = 0; j < PAGING_TOTAL_ENTRIES; j++) {
// set the page table entry
// this is the virtual address of a 4K size page which is not allocated yet
table[j] = (offset + j * PAGING_PAGE_SIZE_BYTES) | flags;
}

offset += (PAGING_TOTAL_ENTRIES * PAGING_PAGE_SIZE_BYTES);
// set the page directory entry
// this is the virtual address of the beginning of the page table at index `i`
directory[i] = (uint32_t)table | flags | PAGING_IS_WRITABLE;
}

// this points to the first page directory entry, which will be fed to CR3 registry
struct paging_map* map = kzalloc(sizeof(struct paging_map));
map->directory = directory;

return map;
}

status_t
free_paging_map(struct paging_map* map)
static void
switch_page(struct paging_map* map)
{
status_t result = ALL_OK;

if (!map) {
result = ERROR(EINVARG);
goto out;
if (!map->directory) {
panic("Paging map directory is null");
}

for (int i = 0; i < PAGING_TOTAL_ENTRIES; i++) {
uint32_t* table = (uint32_t*)(map->directory[i] & 0xfffff000); // mask the flags to get the table address
kfree(table);
}

kfree(map->directory);
kfree(map);

out:
return result;
}

void
switch_page(struct paging_map* map)
{
load_directory(map->directory);
current_directory = map->directory;
}
Expand Down Expand Up @@ -130,6 +86,58 @@ map_page_frame(struct paging_map* map, uint32_t* physical_address, uint32_t* vir
return set_page_frame(map, virtual_address, (uint32_t)physical_address | flags);
}

struct paging_map*
new_paging_map(uint8_t flags)
{
// allocate a linear memory space for a page directory (1024 entries)
uint32_t* directory = kzalloc(sizeof(uint32_t) * PAGING_TOTAL_ENTRIES);
int offset = 0;

for (int i = 0; i < PAGING_TOTAL_ENTRIES; i++) {
// allocate a linear memory for a page table (1024 entries)
uint32_t* table = kzalloc(sizeof(uint32_t) * PAGING_TOTAL_ENTRIES);

for (int j = 0; j < PAGING_TOTAL_ENTRIES; j++) {
// set the page table entry
// this is the virtual address of a 4K size page which is not allocated yet
table[j] = (offset + j * PAGING_PAGE_SIZE_BYTES) | flags;
}

offset += (PAGING_TOTAL_ENTRIES * PAGING_PAGE_SIZE_BYTES);
// set the page directory entry
// this is the virtual address of the beginning of the page table at index `i`
directory[i] = (uint32_t)table | flags | PAGING_IS_WRITABLE;
}

// this points to the first page directory entry, which will be fed to CR3 registry
struct paging_map* map = kzalloc(sizeof(struct paging_map));
map->directory = directory;

return map;
}

status_t
free_paging_map(struct paging_map* map)
{
status_t result = ALL_OK;

if (!map) {
result = ERROR(EINVARG);
goto out;
}

for (int i = 0; i < PAGING_TOTAL_ENTRIES; i++) {
uint32_t* table = (uint32_t*)(map->directory[i] & 0xfffff000); // mask the flags to get the table address
kfree(table);
}

kfree(map->directory);
kfree(map);

out:
return result;
}

status_t
map_physical_address_to_pages(
struct paging_map* map,
Expand Down Expand Up @@ -174,3 +182,26 @@ map_physical_address_to_pages(
out:
return result;
}

void
initialize_kernel_space_paging()
{
kernel_page = new_paging_map(PAGING_IS_WRITABLE | PAGING_IS_PRESENT | PAGING_ACCESS_FROM_ALL);
switch_page(kernel_page);
enable_paging();
}

void
switch_to_kernel_page()
{
set_kernel_segment_registers();
switch_page(kernel_page);
}

void
switch_to_user_page()
{
set_user_segment_registers();
struct task* current_task = get_current_task();
switch_page(current_task->user_page);
}
8 changes: 6 additions & 2 deletions src/memory/paging/paging.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ struct paging_map
uint32_t* directory;
};

extern void set_kernel_segment_registers();
extern void set_user_segment_registers();

struct paging_map* new_paging_map(uint8_t flags);
status_t free_paging_map(struct paging_map* map);
void switch_page(struct paging_map* map);
void enable_paging();
status_t map_physical_address_to_pages(
struct paging_map* map,
void* physical_address,
void* virtual_address,
uint32_t size,
uint32_t flags
);
void initialize_kernel_space_paging();
void switch_to_kernel_page();
void switch_to_user_page();

#endif
11 changes: 11 additions & 0 deletions src/system/sys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "sys.h"
#include "terminal/terminal.h"

void
panic(const char* message)
{
print("PANIC: ");
print(message);
print("\n");
while (1) {};
}
6 changes: 6 additions & 0 deletions src/system/sys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef SYS_H
#define SYS_H

void panic(const char* message);

#endif
2 changes: 1 addition & 1 deletion src/system/syscall.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "syscall.h"
#include "config.h"
#include "kernel.h"
#include "sys.h"
#include "terminal/terminal.h"

static SYSCALL_HANDLER syscall_handlers[TOTAL_SYSCALL_COUNT];
Expand Down
15 changes: 3 additions & 12 deletions src/task/task.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

section .asm

global return_to_task
global set_user_segment_registers
global return_to_user_space

; void return_to_task(struct registers* registers);
return_to_task:
; void return_to_user_space(struct registers* registers);
return_to_user_space:
; here, we don't push the base pointer because we call `iretd` at the end
mov ebp, esp
mov ebx, [ebp + 4] ; +4 becuase we didn't push EBP
Expand Down Expand Up @@ -52,11 +51,3 @@ restore_general_purpose_registers:
mov ebx, [ebx + 20]
pop ebp
ret

set_user_segment_registers:
mov ax, 0x23 ; user data segment | flags: 0x3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
ret
Loading

0 comments on commit ab34302

Please sign in to comment.