map kernel memory area
This commit is contained in:
72
kernel.c
72
kernel.c
@@ -1,9 +1,41 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
extern char __bss[], __bss_end[], __stack_top[];
|
extern char __bss[], __bss_end[], __stack_top[];
|
||||||
extern char __free_ram[], __free_ram_end[];
|
extern char __free_ram[], __free_ram_end[];
|
||||||
|
extern char __kernel_base[];
|
||||||
|
|
||||||
|
paddr_t alloc_pages(uint32_t n) {
|
||||||
|
static paddr_t next_paddr = (paddr_t) __free_ram;
|
||||||
|
paddr_t paddr = next_paddr;
|
||||||
|
next_paddr += n * PAGE_SIZE;
|
||||||
|
|
||||||
|
if (next_paddr > (paddr_t) __free_ram_end)
|
||||||
|
PANIC("Out ow memowy~ :((");
|
||||||
|
|
||||||
|
memset((void *) paddr, 0, n * PAGE_SIZE);
|
||||||
|
return paddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_page(uint32_t *table1, uint32_t vaddr, paddr_t paddr, uint32_t flags) {
|
||||||
|
if (!is_aligned(vaddr, PAGE_SIZE))
|
||||||
|
PANIC("Unaligned vaddr %x", vaddr);
|
||||||
|
|
||||||
|
if (!is_aligned(paddr, PAGE_SIZE))
|
||||||
|
PANIC("Unaligned paddr %x", paddr);
|
||||||
|
|
||||||
|
uint32_t vpn1 = (vaddr >> 22) & 0x3ff;
|
||||||
|
if ((table1[vpn1] & PAGE_V) == 0) {
|
||||||
|
// Create the first level page
|
||||||
|
uint32_t pt_paddr = alloc_pages(1);
|
||||||
|
table1[vpn1] = ((pt_paddr / PAGE_SIZE) << 10) | PAGE_V;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the second level page table entry to map the physical page
|
||||||
|
uint32_t vpn0 = (vaddr >> 12) & 0x3ff;
|
||||||
|
uint32_t *table0 = (uint32_t *) ((table1[vpn1] >> 10) * PAGE_SIZE);
|
||||||
|
table0[vpn0] = ((paddr / PAGE_SIZE) << 10) | flags | PAGE_V;
|
||||||
|
}
|
||||||
|
|
||||||
struct sbiret sbi_call(long arg0, long arg1, long arg2, long arg3, long arg4,
|
struct sbiret sbi_call(long arg0, long arg1, long arg2, long arg3, long arg4,
|
||||||
long arg5, long fid, long eid) {
|
long arg5, long fid, long eid) {
|
||||||
@@ -24,18 +56,6 @@ struct sbiret sbi_call(long arg0, long arg1, long arg2, long arg3, long arg4,
|
|||||||
return (struct sbiret){.error = a0, .value = a1};
|
return (struct sbiret){.error = a0, .value = a1};
|
||||||
}
|
}
|
||||||
|
|
||||||
paddr_t alloc_pages(uint32_t n) {
|
|
||||||
static paddr_t next_paddr = (paddr_t) __free_ram;
|
|
||||||
paddr_t paddr = next_paddr;
|
|
||||||
next_paddr += n * PAGE_SIZE;
|
|
||||||
|
|
||||||
if (next_paddr > (paddr_t) __free_ram_end)
|
|
||||||
PANIC("Out ow memowy~ :((");
|
|
||||||
|
|
||||||
memset((void *) paddr, 0, n * PAGE_SIZE);
|
|
||||||
return paddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void putchar(char ch) {
|
void putchar(char ch) {
|
||||||
sbi_call(ch, 0, 0, 0, 0, 0, 0, 1 /* Console Putchar */);
|
sbi_call(ch, 0, 0, 0, 0, 0, 0, 1 /* Console Putchar */);
|
||||||
}
|
}
|
||||||
@@ -204,11 +224,17 @@ struct process *create_process(uint32_t pc) {
|
|||||||
*--sp = 0; // s0
|
*--sp = 0; // s0
|
||||||
*--sp = (uint32_t) pc; // ra
|
*--sp = (uint32_t) pc; // ra
|
||||||
|
|
||||||
|
// Map kernel pages
|
||||||
|
uint32_t *page_table = (uint32_t *) alloc_pages(1);
|
||||||
|
for (paddr_t paddr = (paddr_t) __kernel_base; paddr < (paddr_t) __free_ram_end; paddr += PAGE_SIZE) {
|
||||||
|
map_page(page_table, paddr, paddr, PAGE_R | PAGE_W | PAGE_X);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize fields
|
// Initialize fields
|
||||||
proc->pid = i + 1;
|
proc->pid = i + 1;
|
||||||
proc->state = PROC_RUNNABLE;
|
proc->state = PROC_RUNNABLE;
|
||||||
proc->sp = (uint32_t) sp;
|
proc->sp = (uint32_t) sp;
|
||||||
|
proc->page_table = page_table;
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,26 +292,6 @@ void proc_b_entry(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_page(uint32_t *table1, uint32_t vaddr, paddr_t paddr, uint32_t flags) {
|
|
||||||
if (!is_aligned(vaddr, PAGE_SIZE))
|
|
||||||
PANIC("Unaligned vaddr %x", vaddr);
|
|
||||||
|
|
||||||
if (!is_aligned(paddr, PAGE_SIZE))
|
|
||||||
PANIC("Unaligned paddr %x", paddr);
|
|
||||||
|
|
||||||
uint32_t vpn1 = (vaddr >> 22) & 0x3ff;
|
|
||||||
if ((table1[vpn1] & PAGE_V) == 0) {
|
|
||||||
// Create the first level page
|
|
||||||
uint32_t pt_paddr = alloc_pages(1);
|
|
||||||
table1[vpn1] = ((pt_paddr / PAGE_SIZE) << 10) | PAGE_V;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the second level page table entry to map the physical page
|
|
||||||
uint32_t vpn0 = (vaddr >> 12) & 0x3ff;
|
|
||||||
uint32_t *table0 = (uint32_t *) ((table1[vpn1] >> 10) * PAGE_SIZE);
|
|
||||||
table0[vpn0] = ((paddr / PAGE_SIZE) << 10) | flags | PAGE_V;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernel_main(void) {
|
void kernel_main(void) {
|
||||||
// printf("\n\nHello %s\n", "friend :3");
|
// printf("\n\nHello %s\n", "friend :3");
|
||||||
// printf("60 + 9 = %d, %x\n", 60 + 9, 0x1234abcd);
|
// printf("60 + 9 = %d, %x\n", 60 + 9, 0x1234abcd);
|
||||||
|
17
kernel.h
17
kernel.h
@@ -64,16 +64,19 @@ struct trap_frame {
|
|||||||
#define PROC_UNUSED 0 // Unused processes control structure
|
#define PROC_UNUSED 0 // Unused processes control structure
|
||||||
#define PROC_RUNNABLE 1 // Runnable proccess
|
#define PROC_RUNNABLE 1 // Runnable proccess
|
||||||
|
|
||||||
struct process {
|
// Page table
|
||||||
int pid; // ID of a process
|
|
||||||
int state; // State of the process: either PROC_UNUSED or PROC_RUNNABLE
|
|
||||||
vaddr_t sp; // Stack pointer
|
|
||||||
uint8_t stack[8192]; // Kernel stack
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SATP_SV32 (1u << 32)
|
#define SATP_SV32 (1u << 32)
|
||||||
#define PAGE_V (1 << 0) // "Valid" bit (entry is allowed)
|
#define PAGE_V (1 << 0) // "Valid" bit (entry is allowed)
|
||||||
#define PAGE_R (1 << 1) // Readable
|
#define PAGE_R (1 << 1) // Readable
|
||||||
#define PAGE_W (1 << 2) // Writable
|
#define PAGE_W (1 << 2) // Writable
|
||||||
#define PAGE_X (1 << 3) // Executable
|
#define PAGE_X (1 << 3) // Executable
|
||||||
#define PAGE_U (1 << 4) // User (accessible in user mode)
|
#define PAGE_U (1 << 4) // User (accessible in user mode)
|
||||||
|
|
||||||
|
struct process {
|
||||||
|
int pid; // ID of a process
|
||||||
|
int state; // State of the process: either PROC_UNUSED or PROC_RUNNABLE
|
||||||
|
vaddr_t sp; // Stack pointer
|
||||||
|
uint32_t *page_table;
|
||||||
|
uint8_t stack[8192]; // Kernel stack
|
||||||
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user