Start isolating processes
Kernel moved to a fixed range high in address space. Memory allocation now happens per process. Single kernel process added.
This commit is contained in:
+6
-6
@@ -10,7 +10,7 @@ void cat(process_t *proc, uint8_t argc, char **argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_t *path = path_open(proc->root, proc->cwd, argv[1]);
|
||||
path_t *path = path_open(proc, proc->cwd, argv[1]);
|
||||
if (!path) {
|
||||
WRITE_S("cat: invalid path\n");
|
||||
return;
|
||||
@@ -19,13 +19,13 @@ void cat(process_t *proc, uint8_t argc, char **argv) {
|
||||
fs_node_t *curr = path->depth ? path->stack[path->depth - 1] : proc->root;
|
||||
if (curr->is_dir) {
|
||||
WRITE_S("cat: can not print a directory\n");
|
||||
path_close(path);
|
||||
path_close(proc, path);
|
||||
return;
|
||||
}
|
||||
|
||||
char *content = memory_allocate(curr->size + 1);
|
||||
fs_read(curr, 0, curr->size, content);
|
||||
char *content = memory_allocate(proc, curr->size + 1);
|
||||
fs_read(proc, curr, 0, curr->size, content);
|
||||
proc->stdout->write(proc->stdout, content, curr->size);
|
||||
memory_free(content);
|
||||
path_close(path);
|
||||
memory_free(proc, content);
|
||||
path_close(proc, path);
|
||||
}
|
||||
|
||||
+6
-6
@@ -9,7 +9,7 @@ void ls(process_t *proc, uint8_t argc, char **argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_t *path = path_open(proc->root, proc->cwd, argc == 1 ? "." : argv[1]);
|
||||
path_t *path = path_open(proc, proc->cwd, argc == 1 ? "." : argv[1]);
|
||||
if (!path) {
|
||||
WRITE_S("ls: invalid path\n");
|
||||
return;
|
||||
@@ -18,17 +18,17 @@ void ls(process_t *proc, uint8_t argc, char **argv) {
|
||||
fs_node_t *curr = path->depth ? path->stack[path->depth - 1] : proc->root;
|
||||
if (!curr->is_dir) {
|
||||
WRITE_S("ls: can not list a file\n");
|
||||
path_close(path);
|
||||
path_close(proc, path);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t j = 0;
|
||||
fs_node_t *item = fs_open_at(curr, j++);
|
||||
fs_node_t *item = fs_open_at(proc, curr, j++);
|
||||
while (item) {
|
||||
WRITE_D(item->name);
|
||||
WRITE_S("\n");
|
||||
fs_close(item);
|
||||
item = fs_open_at(curr, j++);
|
||||
fs_close(proc, item);
|
||||
item = fs_open_at(proc, curr, j++);
|
||||
}
|
||||
path_close(path);
|
||||
path_close(proc, path);
|
||||
}
|
||||
|
||||
+3
-5
@@ -56,13 +56,13 @@ static void cd(process_t *proc, uint8_t argc, char **argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_t *new = path_open(proc->root, proc->cwd, argv[1]);
|
||||
path_t *new = path_open(proc, proc->cwd, argv[1]);
|
||||
if (!new) {
|
||||
WRITE_S("cd: path does not exist\n");
|
||||
return;
|
||||
}
|
||||
|
||||
path_close(proc->cwd);
|
||||
path_close(proc, proc->cwd);
|
||||
proc->cwd = new;
|
||||
}
|
||||
|
||||
@@ -270,9 +270,7 @@ void terminal(process_t *p, __attribute__((unused)) uint8_t argc, __attribute__(
|
||||
|
||||
proc = p;
|
||||
|
||||
char *greeting = string_format("Welcome to FreywarOS v%s!\n\n", VERSION);
|
||||
WRITE_D(greeting);
|
||||
memory_free(greeting);
|
||||
WRITE_D("Welcome to FreywarOS v" VERSION "!\n\n");
|
||||
|
||||
print_prompt();
|
||||
|
||||
|
||||
+14
-7
@@ -276,23 +276,30 @@ protected_mode:
|
||||
mov ss, ax
|
||||
mov esp, 0x00090000
|
||||
|
||||
; zero page table memory at 0x00010000 (3 pages = 768 dwords)
|
||||
; zero page table memory at 0x00010000
|
||||
mov edi, 0x00010000
|
||||
mov ecx, 768
|
||||
mov ecx, 256 * 5
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
; PML4[0] -> PDPT at 0x00011000
|
||||
mov dword [0x00010000], 0x00011003
|
||||
; PDPT[0] -> PD at 0x00012000
|
||||
mov dword [0x00011000], 0x00012003
|
||||
; PML4[511] -> PDPT at 0x00012000
|
||||
mov dword [0x00010FF8], 0x00012003
|
||||
; PML4[0].PDPT[0] -> PD at 0x00013000
|
||||
mov dword [0x00011000], 0x00013003
|
||||
; PML4[511].PDPT[510] -> PD at 0x00014000
|
||||
mov dword [0x00012FF0], 0x00014003
|
||||
; PD: fill 64 entries, each mapping 2MB
|
||||
mov edi, 0x00012000
|
||||
mov edi, 0x00013000
|
||||
mov eax, 0x00000083 ; present, writable, huge page, base 0
|
||||
mov ecx, 64
|
||||
|
||||
.fill_pd:
|
||||
mov ebx, edi
|
||||
add ebx, 0x1000
|
||||
mov dword [edi], eax
|
||||
mov dword [ebx], eax
|
||||
add edi, 8
|
||||
add eax, 0x00200000 ; next 2MB
|
||||
loop .fill_pd
|
||||
@@ -327,11 +334,11 @@ long_mode:
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
mov rsp, 0x0000000000090000
|
||||
mov rsp, 0xFFFFFFFF80090000
|
||||
|
||||
xor rax, rax
|
||||
xor rbx, rbx
|
||||
xor rcx, rcx
|
||||
xor rdx, rdx
|
||||
|
||||
jmp 0x00020000
|
||||
jmp 0xFFFFFFFF80020000
|
||||
|
||||
+30
-31
@@ -1,10 +1,9 @@
|
||||
#include "src/fat16.h"
|
||||
#include "src/ata.h"
|
||||
#include "src/fs.h"
|
||||
#include "src/memory.h"
|
||||
#include "src/process.h"
|
||||
#include "src/string.h"
|
||||
#include "src/util.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define FIRST_PARTITION_SECTOR 2048
|
||||
@@ -74,11 +73,11 @@ static void from_8_3(const char *name, const char *extension, char *output) {
|
||||
}
|
||||
}
|
||||
|
||||
fs_node_t *fat16_mount() { // Assuming one partition.
|
||||
fs_node_t *fat16_mount(process_t *kernel) { // Assuming one partition.
|
||||
uint8_t sector[512];
|
||||
ata_read_sectors(FIRST_PARTITION_SECTOR, 1, §or);
|
||||
memory_copy(sector + 11, sizeof(fat16_bpb_t), &bpb);
|
||||
fat16_node_t *node = memory_allocate(sizeof(fat16_node_t));
|
||||
fat16_node_t *node = memory_allocate(kernel, sizeof(fat16_node_t));
|
||||
node->base.type = FAT16;
|
||||
node->base.name[0] = node->entry.name[0] = '/';
|
||||
node->base.size = node->entry.size = sizeof(fat16_dir_entry_t) * bpb.root_entry_count;
|
||||
@@ -86,23 +85,23 @@ fs_node_t *fat16_mount() { // Assuming one partition.
|
||||
return fs = (fs_node_t *)node;
|
||||
}
|
||||
|
||||
static void ensure_fat() {
|
||||
static void ensure_fat(process_t *proc) {
|
||||
ASSERT(bpb.sectors_per_fat < 256, "ensure_fat: big FAT not implemented")
|
||||
if (!fat) {
|
||||
fat = memory_allocate(bpb.sectors_per_fat * SECTOR_SIZE);
|
||||
fat = memory_allocate(proc->kernel, bpb.sectors_per_fat * SECTOR_SIZE);
|
||||
ata_read_sectors(FIRST_PARTITION_SECTOR + bpb.reserved_sectors, (uint8_t)bpb.sectors_per_fat, fat);
|
||||
}
|
||||
}
|
||||
|
||||
static fat16_dir_entry_t *load_directory(fat16_node_t *directory) {
|
||||
static fat16_dir_entry_t *load_directory(process_t *proc, fat16_node_t *directory) {
|
||||
fat16_dir_entry_t *entries;
|
||||
|
||||
if (!directory->entry.first_cluster) {
|
||||
uint8_t sectors = (uint8_t)((directory->base.size + SECTOR_SIZE - 1) / SECTOR_SIZE);
|
||||
entries = memory_allocate(sectors * SECTOR_SIZE + sizeof(fat16_dir_entry_t)); // One extra as null terminator.
|
||||
entries = memory_allocate(proc, sectors * SECTOR_SIZE + sizeof(fat16_dir_entry_t)); // One extra as null terminator.
|
||||
ata_read_sectors(FIRST_PARTITION_SECTOR + bpb.reserved_sectors + bpb.fats_count * bpb.sectors_per_fat, sectors, entries);
|
||||
} else {
|
||||
ensure_fat();
|
||||
ensure_fat(proc);
|
||||
|
||||
uint16_t next_cluster = directory->entry.first_cluster;
|
||||
uint32_t cluster_count = 0;
|
||||
@@ -110,8 +109,8 @@ static fat16_dir_entry_t *load_directory(fat16_node_t *directory) {
|
||||
cluster_count++;
|
||||
next_cluster = fat[next_cluster];
|
||||
}
|
||||
entries =
|
||||
memory_allocate(cluster_count * bpb.sectors_per_cluster * SECTOR_SIZE + sizeof(fat16_dir_entry_t)); // One extra as null terminator.
|
||||
entries = memory_allocate(proc, cluster_count * bpb.sectors_per_cluster * SECTOR_SIZE +
|
||||
sizeof(fat16_dir_entry_t)); // One extra as null terminator.
|
||||
|
||||
uint8_t *chunk = (uint8_t *)entries;
|
||||
next_cluster = directory->entry.first_cluster;
|
||||
@@ -128,12 +127,12 @@ static fat16_dir_entry_t *load_directory(fat16_node_t *directory) {
|
||||
return entries;
|
||||
}
|
||||
|
||||
static fs_node_t *open_entry(const char *name, const fat16_dir_entry_t *entry) {
|
||||
static fs_node_t *open_entry(process_t *proc, const char *name, const fat16_dir_entry_t *entry) {
|
||||
if (!entry->name[0]) {
|
||||
return NUL;
|
||||
}
|
||||
|
||||
fat16_node_t *result = memory_allocate(sizeof(fat16_node_t));
|
||||
fat16_node_t *result = memory_allocate(proc, sizeof(fat16_node_t));
|
||||
memory_copy((char *)name, string_length(name) + 1, &(result->base.name));
|
||||
result->base.type = FAT16;
|
||||
result->base.size = entry->size;
|
||||
@@ -143,14 +142,14 @@ static fs_node_t *open_entry(const char *name, const fat16_dir_entry_t *entry) {
|
||||
return (fs_node_t *)result;
|
||||
}
|
||||
|
||||
fs_node_t *fat16_open_by(const fs_node_t *directory, const char *name) {
|
||||
fs_node_t *fat16_open_by(process_t *proc, const fs_node_t *directory, const char *name) {
|
||||
ASSERT(directory->type == FAT16, "fat16_open_by: directory is not FAT16");
|
||||
ASSERT(directory->is_dir, "fat16_open_by: directory is not a directory");
|
||||
|
||||
char name_8_3[12];
|
||||
to_8_3(name, name_8_3);
|
||||
|
||||
fat16_dir_entry_t *entries = load_directory((fat16_node_t *)directory);
|
||||
fat16_dir_entry_t *entries = load_directory(proc, (fat16_node_t *)directory);
|
||||
|
||||
fat16_dir_entry_t *entry = entries;
|
||||
while (entry->name[0]) {
|
||||
@@ -160,16 +159,16 @@ fs_node_t *fat16_open_by(const fs_node_t *directory, const char *name) {
|
||||
entry++;
|
||||
}
|
||||
|
||||
fs_node_t *result = open_entry(name, entry);
|
||||
memory_free(entries);
|
||||
fs_node_t *result = open_entry(proc, name, entry);
|
||||
memory_free(proc, entries);
|
||||
return result;
|
||||
}
|
||||
|
||||
fs_node_t *fat16_open_at(const fs_node_t *directory, uint64_t index) {
|
||||
fs_node_t *fat16_open_at(process_t *proc, const fs_node_t *directory, uint64_t index) {
|
||||
ASSERT(directory->type == FAT16, "fat16_open_at: directory is not FAT16");
|
||||
ASSERT(directory->is_dir, "fat16_open_at: directory is not a directory");
|
||||
|
||||
fat16_dir_entry_t *entries = load_directory((fat16_node_t *)directory);
|
||||
fat16_dir_entry_t *entries = load_directory(proc, (fat16_node_t *)directory);
|
||||
|
||||
uint64_t ei = 0, vi = 0;
|
||||
while (entries[ei].name[0]) {
|
||||
@@ -189,23 +188,23 @@ fs_node_t *fat16_open_at(const fs_node_t *directory, uint64_t index) {
|
||||
char name[13];
|
||||
from_8_3(entries[ei].name, entries[ei].ext, name);
|
||||
|
||||
fs_node_t *result = open_entry(name, entries + ei);
|
||||
memory_free(entries);
|
||||
fs_node_t *result = open_entry(proc, name, entries + ei);
|
||||
memory_free(proc, entries);
|
||||
return result;
|
||||
}
|
||||
|
||||
fs_node_t *fat16_open_again(const fs_node_t *source) {
|
||||
fs_node_t *result = memory_allocate(sizeof(fat16_node_t));
|
||||
fs_node_t *fat16_open_again(process_t *proc, const fs_node_t *source) {
|
||||
fs_node_t *result = memory_allocate(proc, sizeof(fat16_node_t));
|
||||
memory_copy(source, sizeof(fat16_node_t), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void fat16_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to) {
|
||||
void fat16_read(process_t *proc, const fs_node_t *file, uint64_t offset, uint64_t size, void *to) {
|
||||
ASSERT(file->type == FAT16, "fat16_read: file is not FAT16");
|
||||
ASSERT(!file->is_dir, "fat16_read: can not read directory");
|
||||
ASSERT(file->size >= offset + size, "fat16_read: offset/size are out of bounds");
|
||||
|
||||
ensure_fat();
|
||||
ensure_fat(proc);
|
||||
|
||||
fat16_node_t *fat_file = (fat16_node_t *)file;
|
||||
|
||||
@@ -221,7 +220,7 @@ void fat16_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to)
|
||||
|
||||
uint8_t *cursor = to;
|
||||
|
||||
uint8_t *tmp = memory_allocate(cluster_size);
|
||||
uint8_t *tmp = memory_allocate(proc, cluster_size);
|
||||
ata_read_sectors(FIRST_PARTITION_SECTOR + bpb.reserved_sectors + bpb.sectors_per_fat * bpb.fats_count +
|
||||
(bpb.root_entry_count * sizeof(fat16_dir_entry_t) + SECTOR_SIZE - 1) / SECTOR_SIZE +
|
||||
bpb.sectors_per_cluster * (next_cluster - 2),
|
||||
@@ -250,18 +249,18 @@ void fat16_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to)
|
||||
memory_copy(tmp, size, cursor);
|
||||
}
|
||||
|
||||
memory_free(tmp);
|
||||
memory_free(proc, tmp);
|
||||
}
|
||||
|
||||
void fat16_close(fs_node_t *node) {
|
||||
void fat16_close(process_t *proc, fs_node_t *node) {
|
||||
ASSERT(node->type == FAT16, "fat16_close: node is not FAT16");
|
||||
ASSERT(node != fs, "fat16_close: can not unmount FS");
|
||||
memory_free(node);
|
||||
memory_free(proc, node);
|
||||
}
|
||||
|
||||
void fat16_unmount(fs_node_t *node) {
|
||||
void fat16_unmount(process_t *kernel, fs_node_t *node) {
|
||||
ASSERT(node->type == FAT16, "fat16_unmount: node is not FAT16");
|
||||
ASSERT(node == fs, "fat16_unmount: node is not filesystem");
|
||||
memory_free(node);
|
||||
memory_free(kernel, node);
|
||||
fs = NUL;
|
||||
}
|
||||
|
||||
+9
-7
@@ -2,18 +2,20 @@
|
||||
|
||||
#include "src/fs.h"
|
||||
|
||||
typedef struct process process_t;
|
||||
|
||||
#define FAT16 1
|
||||
|
||||
fs_node_t *fat16_mount();
|
||||
fs_node_t *fat16_mount(process_t *kernel);
|
||||
|
||||
fs_node_t *fat16_open_by(const fs_node_t *directory, const char *name);
|
||||
fs_node_t *fat16_open_by(process_t *proc, const fs_node_t *directory, const char *name);
|
||||
|
||||
fs_node_t *fat16_open_at(const fs_node_t *directory, uint64_t index);
|
||||
fs_node_t *fat16_open_at(process_t *proc, const fs_node_t *directory, uint64_t index);
|
||||
|
||||
fs_node_t *fat16_open_again(const fs_node_t *source);
|
||||
fs_node_t *fat16_open_again(process_t *proc, const fs_node_t *source);
|
||||
|
||||
void fat16_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to);
|
||||
void fat16_read(process_t *proc, const fs_node_t *file, uint64_t offset, uint64_t size, void *to);
|
||||
|
||||
void fat16_close(fs_node_t *node);
|
||||
void fat16_close(process_t *proc, fs_node_t *node);
|
||||
|
||||
void fat16_unmount(fs_node_t *fs);
|
||||
void fat16_unmount(process_t *kernel, fs_node_t *fs);
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
#include "src/fs.h"
|
||||
#include "src/fat16.h"
|
||||
#include "src/process.h"
|
||||
|
||||
fs_node_t *fs_mount() {
|
||||
return fat16_mount();
|
||||
fs_node_t *fs_mount(process_t *kernel) {
|
||||
return fat16_mount(kernel);
|
||||
}
|
||||
|
||||
fs_node_t *fs_open_by(const fs_node_t *directory, const char *name) {
|
||||
return fat16_open_by(directory, name);
|
||||
fs_node_t *fs_open_by(process_t *proc, const fs_node_t *directory, const char *name) {
|
||||
return fat16_open_by(proc, directory, name);
|
||||
}
|
||||
|
||||
fs_node_t *fs_open_at(const fs_node_t *directory, uint64_t index) {
|
||||
return fat16_open_at(directory, index);
|
||||
fs_node_t *fs_open_at(process_t *proc, const fs_node_t *directory, uint64_t index) {
|
||||
return fat16_open_at(proc, directory, index);
|
||||
}
|
||||
|
||||
fs_node_t *fs_open_again(const fs_node_t *source) {
|
||||
return fat16_open_again(source);
|
||||
fs_node_t *fs_open_again(process_t *proc, const fs_node_t *source) {
|
||||
return fat16_open_again(proc, source);
|
||||
}
|
||||
|
||||
void fs_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to) {
|
||||
fat16_read(file, offset, size, to);
|
||||
void fs_read(process_t *proc, const fs_node_t *file, uint64_t offset, uint64_t size, void *to) {
|
||||
fat16_read(proc, file, offset, size, to);
|
||||
}
|
||||
|
||||
void fs_close(fs_node_t *node) {
|
||||
fat16_close(node);
|
||||
void fs_close(process_t *proc, fs_node_t *node) {
|
||||
fat16_close(proc, node);
|
||||
}
|
||||
|
||||
void fs_unmount(fs_node_t *fs) {
|
||||
fat16_unmount(fs);
|
||||
void fs_unmount(process_t *kernel, fs_node_t *fs) {
|
||||
fat16_unmount(kernel, fs);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#define FILENAME_SIZE_LIMIT 255
|
||||
|
||||
typedef struct process process_t;
|
||||
|
||||
typedef struct fs_node {
|
||||
char name[FILENAME_SIZE_LIMIT + 1];
|
||||
uint32_t size;
|
||||
@@ -12,16 +14,16 @@ typedef struct fs_node {
|
||||
} fs_node_t;
|
||||
|
||||
|
||||
fs_node_t *fs_mount();
|
||||
fs_node_t *fs_mount(process_t *kernel);
|
||||
|
||||
fs_node_t *fs_open_by(const fs_node_t *directory, const char *name);
|
||||
fs_node_t *fs_open_by(process_t *proc, const fs_node_t *directory, const char *name);
|
||||
|
||||
fs_node_t *fs_open_at(const fs_node_t *directory, uint64_t index);
|
||||
fs_node_t *fs_open_at(process_t *proc, const fs_node_t *directory, uint64_t index);
|
||||
|
||||
fs_node_t *fs_open_again(const fs_node_t *source);
|
||||
fs_node_t *fs_open_again(process_t *proc, const fs_node_t *source);
|
||||
|
||||
void fs_read(const fs_node_t *file, uint64_t offset, uint64_t size, void *to);
|
||||
void fs_read(process_t *proc, const fs_node_t *file, uint64_t offset, uint64_t size, void *to);
|
||||
|
||||
void fs_close(fs_node_t *node);
|
||||
void fs_close(process_t *proc, fs_node_t *node);
|
||||
|
||||
void fs_unmount(fs_node_t *fs);
|
||||
void fs_unmount(process_t *kernel, fs_node_t *fs);
|
||||
|
||||
+9
-7
@@ -32,6 +32,8 @@ __attribute__((interrupt)) void isr_ata_primary(__attribute__((unused)) struct i
|
||||
outb(0xA0, 0x20);
|
||||
}
|
||||
|
||||
static process_t kernel_process;
|
||||
|
||||
void kernel_main() {
|
||||
pic_init();
|
||||
idt_init();
|
||||
@@ -42,15 +44,15 @@ void kernel_main() {
|
||||
idt_set_entry(46, isr_ata_primary, 0x8E);
|
||||
__asm__ volatile("sti");
|
||||
|
||||
memory_init();
|
||||
memory_init(&kernel_process);
|
||||
kernel_process.root = fs_mount(&kernel_process);
|
||||
kernel_process.cwd = memory_allocate(&kernel_process, sizeof(path_t));
|
||||
kernel_process.stdin = keyboard_init();
|
||||
kernel_process.stdout = vga_init();
|
||||
|
||||
process_t *proc = memory_allocate(sizeof(process_t));
|
||||
proc->cwd = memory_allocate(sizeof(path_t));
|
||||
proc->root = fs_mount();
|
||||
proc->stdin = keyboard_init();
|
||||
proc->stdout = vga_init();
|
||||
terminal(&kernel_process, 0, NUL);
|
||||
|
||||
terminal(proc, 0, NUL);
|
||||
fs_unmount(&kernel_process, kernel_process.root);
|
||||
|
||||
outw(0x604, 0x2000); // TODO: parse ACPI tables for real hardware
|
||||
__asm__ volatile("cli; hlt");
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
ENTRY(kernel_main)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x0000000000020000;
|
||||
. = 0xFFFFFFFF80020000;
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
|
||||
+18
-20
@@ -1,9 +1,9 @@
|
||||
#include "src/memory.h"
|
||||
#include "src/panic.h"
|
||||
#include "src/process.h"
|
||||
#include "src/util.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MEMORY_SIZE 134217728
|
||||
#define MEMORY_SIZE 0x08000000
|
||||
#define PAGE_SIZE 4096
|
||||
#define PAGE_COUNT (MEMORY_SIZE / PAGE_SIZE)
|
||||
#define MAP_UNIT 64
|
||||
@@ -49,29 +49,27 @@ __attribute__((unused)) static void memory_page_free(void *address) {
|
||||
}
|
||||
}
|
||||
|
||||
#define KERNEL_VIRTUAL_BASE 0xFFFFFFFF80000000ULL
|
||||
#define PHYS_TO_VIRT(phys) ((void *)((uint64_t)(phys) + KERNEL_VIRTUAL_BASE))
|
||||
#define VIRT_TO_PHYS(virt) ((uint64_t)(virt) - KERNEL_VIRTUAL_BASE)
|
||||
#define HEAP_PAGE_COUNT 256
|
||||
|
||||
typedef struct free_chunk {
|
||||
uint64_t size; // header + data
|
||||
struct free_chunk *next;
|
||||
} free_chunk_t;
|
||||
|
||||
static free_chunk_t *free_list;
|
||||
|
||||
void memory_init() {
|
||||
free_list = memory_page_allocate();
|
||||
void memory_init(process_t *kernel) {
|
||||
kernel->pml4 = PHYS_TO_VIRT(0x00010000);
|
||||
// Assumes 0x0 -> KERNEL_VIRTUAL_BASE mapping and `memory_page_allocate` issuing continuous pages initially.
|
||||
kernel->heap = PHYS_TO_VIRT(memory_page_allocate());
|
||||
for (uint64_t i = 1; i < HEAP_PAGE_COUNT; i++) {
|
||||
memory_page_allocate(); // TODO Map the pages.
|
||||
memory_page_allocate();
|
||||
}
|
||||
free_list->size = HEAP_PAGE_COUNT * PAGE_SIZE;
|
||||
free_list->next = NUL;
|
||||
kernel->heap->size = HEAP_PAGE_COUNT * PAGE_SIZE;
|
||||
kernel->heap->next = NUL;
|
||||
}
|
||||
|
||||
void *memory_allocate(uint64_t size) {
|
||||
void *memory_allocate(process_t *proc, uint64_t size) {
|
||||
size = sizeof(free_chunk_t) + (size + 7) & (uint64_t)~7;
|
||||
|
||||
free_chunk_t *prev = NUL;
|
||||
free_chunk_t *curr = free_list;
|
||||
free_chunk_t *curr = proc->heap;
|
||||
|
||||
while (curr) {
|
||||
if (curr->size >= size + (sizeof(free_chunk_t) + 8)) {
|
||||
@@ -85,7 +83,7 @@ void *memory_allocate(uint64_t size) {
|
||||
if (prev) {
|
||||
prev->next = curr->next;
|
||||
} else {
|
||||
free_list = curr->next;
|
||||
proc->heap = curr->next;
|
||||
}
|
||||
void *result = (void *)((uint8_t *)curr + sizeof(free_chunk_t));
|
||||
memory_set(0, size - sizeof(free_chunk_t), result);
|
||||
@@ -99,9 +97,9 @@ void *memory_allocate(uint64_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void memory_free(void *pointer) {
|
||||
void memory_free(process_t *proc, void *pointer) {
|
||||
free_chunk_t *chunk = (free_chunk_t *)((uint8_t *)pointer - sizeof(free_chunk_t));
|
||||
chunk->next = free_list;
|
||||
free_list = chunk;
|
||||
chunk->next = proc->heap;
|
||||
proc->heap = chunk;
|
||||
// TODO Merge adjacent free chunks.
|
||||
}
|
||||
|
||||
+10
-3
@@ -3,11 +3,18 @@
|
||||
#include "src/panic.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void memory_init();
|
||||
typedef struct process process_t;
|
||||
|
||||
void *memory_allocate(uint64_t size);
|
||||
typedef struct free_chunk {
|
||||
uint64_t size; // header + data
|
||||
struct free_chunk *next;
|
||||
} free_chunk_t;
|
||||
|
||||
void memory_free(void *pointer);
|
||||
void memory_init(process_t *kernel);
|
||||
|
||||
void *memory_allocate(process_t *proc, uint64_t size);
|
||||
|
||||
void memory_free(process_t *proc, void *pointer);
|
||||
|
||||
static inline void memory_set(uint8_t value, uint64_t bytes, void *to) {
|
||||
__asm__ volatile("rep stosb" : "=D"(to), "=c"(bytes) : "D"(to), "a"(value), "c"(bytes) : "memory");
|
||||
|
||||
+11
-12
@@ -1,18 +1,17 @@
|
||||
#include "src/path.h"
|
||||
#include "src/fs.h"
|
||||
#include "src/memory.h"
|
||||
#include "src/process.h"
|
||||
#include "src/string.h"
|
||||
#include "src/util.h"
|
||||
#include <stdint.h>
|
||||
|
||||
path_t *path_open(const fs_node_t *root, const path_t *source, char *path) {
|
||||
path_t *result = memory_allocate(sizeof(path_t));
|
||||
path_t *path_open(process_t *proc, const path_t *source, char *path) {
|
||||
path_t *result = memory_allocate(proc, sizeof(path_t));
|
||||
|
||||
char *path_components[PATH_DEPTH];
|
||||
uint8_t path_length = (uint8_t)string_split(path, '/', PATH_DEPTH, path_components);
|
||||
if (!string_empty(path_components[0])) {
|
||||
for (uint8_t i = 0; i < source->depth; i++) {
|
||||
result->stack[result->depth++] = fs_open_again(source->stack[i]);
|
||||
result->stack[result->depth++] = fs_open_again(proc, source->stack[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +20,13 @@ path_t *path_open(const fs_node_t *root, const path_t *source, char *path) {
|
||||
continue;
|
||||
} else if (string_equal(path_components[i], "..")) {
|
||||
if (result->depth) {
|
||||
fs_close(result->stack[--result->depth]);
|
||||
fs_close(proc, result->stack[--result->depth]);
|
||||
}
|
||||
} else {
|
||||
const fs_node_t *prev = result->depth ? result->stack[result->depth - 1] : root;
|
||||
fs_node_t *next = prev->is_dir ? fs_open_by(prev, path_components[i]) : NUL;
|
||||
const fs_node_t *prev = result->depth ? result->stack[result->depth - 1] : proc->root;
|
||||
fs_node_t *next = prev->is_dir ? fs_open_by(proc, prev, path_components[i]) : NUL;
|
||||
if (!next || result->depth >= PATH_DEPTH) {
|
||||
path_close(result);
|
||||
path_close(proc, result);
|
||||
return NUL;
|
||||
} else {
|
||||
result->stack[result->depth++] = next;
|
||||
@@ -38,9 +37,9 @@ path_t *path_open(const fs_node_t *root, const path_t *source, char *path) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void path_close(path_t *path) {
|
||||
void path_close(process_t *proc, path_t *path) {
|
||||
for (uint64_t i = 0; i < path->depth; i++) {
|
||||
fs_close(path->stack[i]);
|
||||
fs_close(proc, path->stack[i]);
|
||||
}
|
||||
memory_free(path);
|
||||
memory_free(proc, path);
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/fs.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define PATH_DEPTH 255
|
||||
|
||||
typedef struct process process_t;
|
||||
|
||||
typedef struct {
|
||||
fs_node_t *stack[PATH_DEPTH];
|
||||
uint8_t depth;
|
||||
} path_t;
|
||||
|
||||
path_t *path_open(const fs_node_t *root, const path_t *source, char *path);
|
||||
path_t *path_open(process_t *proc, const path_t *source, char *path);
|
||||
|
||||
void path_close(path_t *path);
|
||||
void path_close(process_t *proc, path_t *path);
|
||||
|
||||
+8
-3
@@ -1,13 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/fs.h"
|
||||
#include "src/path.h"
|
||||
#include "src/stream.h"
|
||||
#include "src/string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
path_t *cwd;
|
||||
typedef struct free_chunk free_chunk_t;
|
||||
|
||||
typedef struct process {
|
||||
struct process *kernel;
|
||||
uint64_t *pml4;
|
||||
free_chunk_t *heap;
|
||||
fs_node_t *root;
|
||||
path_t *cwd;
|
||||
stream_t *stdin;
|
||||
stream_t *stdout;
|
||||
} process_t;
|
||||
|
||||
+18
-21
@@ -1,7 +1,5 @@
|
||||
#include "src/string.h"
|
||||
#include "src/memory.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t bytes_equal(const char *l, const char *r, uint64_t count) {
|
||||
while (count--) {
|
||||
@@ -164,41 +162,39 @@ uint64_t string_uint_to_hex(uint64_t value, uint64_t max, char *result) {
|
||||
return i;
|
||||
}
|
||||
|
||||
char *string_format(const char *format, ...) {
|
||||
uint64_t string_format(const char *format, uint64_t max, char *output, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
va_start(args, output);
|
||||
|
||||
uint64_t limit = 1023;
|
||||
|
||||
char *result = memory_allocate(limit + 1);
|
||||
uint64_t limit = max - 1;
|
||||
|
||||
uint64_t fi = 0, ri = 0;
|
||||
while (format[fi] && ri < limit) {
|
||||
if (format[fi] != '%') {
|
||||
result[ri++] = format[fi++];
|
||||
output[ri++] = format[fi++];
|
||||
} else {
|
||||
switch (format[fi + 1]) {
|
||||
case 'c':
|
||||
result[ri++] = (char)va_arg(args, int);
|
||||
output[ri++] = (char)va_arg(args, int);
|
||||
fi += 2;
|
||||
break;
|
||||
case 'd':
|
||||
string_int_to_decimal(va_arg(args, int64_t), limit - ri, result + ri);
|
||||
while (result[ri]) {
|
||||
string_int_to_decimal(va_arg(args, int64_t), limit - ri, output + ri);
|
||||
while (output[ri]) {
|
||||
ri++;
|
||||
}
|
||||
fi += 2;
|
||||
break;
|
||||
case 'u':
|
||||
string_uint_to_decimal(va_arg(args, uint64_t), limit - ri, result + ri);
|
||||
while (result[ri]) {
|
||||
string_uint_to_decimal(va_arg(args, uint64_t), limit - ri, output + ri);
|
||||
while (output[ri]) {
|
||||
ri++;
|
||||
}
|
||||
fi += 2;
|
||||
break;
|
||||
case 'x':
|
||||
string_uint_to_hex(va_arg(args, uint64_t), limit - ri, result + ri);
|
||||
while (result[ri]) {
|
||||
string_uint_to_hex(va_arg(args, uint64_t), limit - ri, output + ri);
|
||||
while (output[ri]) {
|
||||
ri++;
|
||||
}
|
||||
fi += 2;
|
||||
@@ -206,25 +202,26 @@ char *string_format(const char *format, ...) {
|
||||
case 's': {
|
||||
char *s = va_arg(args, char *);
|
||||
while (*s && ri < limit) {
|
||||
result[ri++] = *s;
|
||||
output[ri++] = *s;
|
||||
s++;
|
||||
}
|
||||
fi += 2;
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
result[ri++] = '%';
|
||||
output[ri++] = '%';
|
||||
fi += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result[ri++] = format[fi++];
|
||||
result[ri++] = format[fi++];
|
||||
output[ri++] = format[fi++];
|
||||
output[ri++] = format[fi++];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result[ri] = '\0';
|
||||
output[ri] = '\0';
|
||||
va_end(args);
|
||||
return result;
|
||||
|
||||
return ri;
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,4 +20,4 @@ uint64_t string_int_to_decimal(int64_t value, uint64_t max, char *result);
|
||||
|
||||
uint64_t string_uint_to_hex(uint64_t value, uint64_t max, char *result);
|
||||
|
||||
char *string_format(const char *format, ...);
|
||||
uint64_t string_format(const char *format, uint64_t max, char *output, ...);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "src/vga.h"
|
||||
#include "src/memory.h"
|
||||
#include "src/util.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static uint16_t *vga = (uint16_t *)0x000B8000;
|
||||
static uint16_t *vga = (uint16_t *)0xFFFFFFFF800B8000;
|
||||
static uint16_t color = (uint16_t)0x0F << 8;
|
||||
static uint16_t offset = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user