got some of the pty actually working in userspace
This commit is contained in:
@@ -67,6 +67,23 @@
|
|||||||
"file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.c",
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.c",
|
||||||
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.c.o"
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.c.o"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/devfs/devfs.c.o",
|
||||||
|
"kernel/drivers/devfs/devfs.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/devfs/devfs.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/devfs/devfs.c.o"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <lib/memory.h>
|
#include <lib/memory.h>
|
||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
|
#include <lib/print.h>
|
||||||
|
|
||||||
#define MAX_INITRD_FILES 64
|
#define MAX_INITRD_FILES 64
|
||||||
|
|
||||||
@@ -17,9 +18,16 @@ static uint32_t parse_hex_ascii(const char *str, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static vfs_node_t* cpio_find(vfs_node_t* _dir, const char* name) {
|
static vfs_node_t* cpio_find(vfs_node_t* _dir, const char* name) {
|
||||||
|
if (strcmp(name, "tvga") == 0) {
|
||||||
|
kprintf("looking for tvga\n");
|
||||||
|
}
|
||||||
if (!(_dir->flags & VFS_DIRECTORY)) return NULL;
|
if (!(_dir->flags & VFS_DIRECTORY)) return NULL;
|
||||||
|
vfs_node_t* root = _dir;
|
||||||
|
if (_dir->mnt) {
|
||||||
|
root = _dir->mnt;
|
||||||
|
}
|
||||||
|
|
||||||
vfs_node_t* child = _dir->first_child;
|
vfs_node_t* child = root->first_child;
|
||||||
while (child != NULL) {
|
while (child != NULL) {
|
||||||
if (strcmp(child->name, name) == 0) {
|
if (strcmp(child->name, name) == 0) {
|
||||||
return child;
|
return child;
|
||||||
@@ -39,7 +47,7 @@ static uint32_t cpio_read(struct vfs_node* node, uint32_t offset, uint32_t size,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vfs_node_t* cpio_get_or_create(vfs_node_t* root_node, const char* path) {
|
static vfs_node_t* cpio_find_or_create(vfs_node_t* root_node, const char* path) {
|
||||||
vfs_node_t* current = root_node;
|
vfs_node_t* current = root_node;
|
||||||
|
|
||||||
char path_cpy[256];
|
char path_cpy[256];
|
||||||
@@ -49,8 +57,6 @@ static vfs_node_t* cpio_get_or_create(vfs_node_t* root_node, const char* path) {
|
|||||||
char* tkn = strtok_r(path_cpy, "/", &sav);
|
char* tkn = strtok_r(path_cpy, "/", &sav);
|
||||||
|
|
||||||
while (tkn != NULL) {
|
while (tkn != NULL) {
|
||||||
char* next_tkn = strtok_r(NULL, "/", &sav);
|
|
||||||
|
|
||||||
vfs_node_t* next_node = cpio_find(current, tkn);
|
vfs_node_t* next_node = cpio_find(current, tkn);
|
||||||
if (!next_node) {
|
if (!next_node) {
|
||||||
next_node = kalloc(sizeof(vfs_node_t));
|
next_node = kalloc(sizeof(vfs_node_t));
|
||||||
@@ -65,7 +71,7 @@ static vfs_node_t* cpio_get_or_create(vfs_node_t* root_node, const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
current = next_node;
|
current = next_node;
|
||||||
tkn = next_tkn;
|
tkn = strtok_r(NULL, "/", &sav);
|
||||||
}
|
}
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
@@ -99,26 +105,7 @@ vfs_node_t* cpio_read_fs(uint32_t _vaddr) {
|
|||||||
uint8_t* file_data = (uint8_t*)header + file_data_offset;
|
uint8_t* file_data = (uint8_t*)header + file_data_offset;
|
||||||
|
|
||||||
if (strcmp(".", filename) != 0) {
|
if (strcmp(".", filename) != 0) {
|
||||||
vfs_node_t* parent = cpio_get_or_create(cpio_root, filename);
|
vfs_node_t* current = cpio_find_or_create(cpio_root, filename);
|
||||||
|
|
||||||
char* base_name = filename;
|
|
||||||
for (int i = strlen(filename) - 1; i >= 0; i--) {
|
|
||||||
if (filename[i] == '/') {
|
|
||||||
base_name = &filename[i + 1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vfs_node_t* current = cpio_find(parent, base_name);
|
|
||||||
if (!current) {
|
|
||||||
current = kalloc(sizeof(vfs_node_t));
|
|
||||||
memset((void*)current, 0, sizeof(vfs_node_t));
|
|
||||||
strcpy(current->name, base_name);
|
|
||||||
|
|
||||||
current->next_sibling = parent->first_child;
|
|
||||||
parent->first_child = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mode & 0xF000) == 0x4000) {
|
if ((mode & 0xF000) == 0x4000) {
|
||||||
current->flags = VFS_DIRECTORY;
|
current->flags = VFS_DIRECTORY;
|
||||||
current->find = cpio_find;
|
current->find = cpio_find;
|
||||||
|
|||||||
40
kernel/drivers/devfs/devfs.c
Normal file
40
kernel/drivers/devfs/devfs.c
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#include "vfs.h"
|
||||||
|
#include <drivers/devfs/devfs.h>
|
||||||
|
|
||||||
|
#include <lib/memory.h>
|
||||||
|
#include <lib/string.h>
|
||||||
|
#include <lib/print.h>
|
||||||
|
|
||||||
|
static vfs_node_t* devfs_find(vfs_node_t* parent, const char* name) {
|
||||||
|
vfs_node_t* cur = parent->first_child;
|
||||||
|
if (!cur) return NULL;
|
||||||
|
|
||||||
|
while (cur) {
|
||||||
|
if (strcmp(cur->name, name) == 0) break;
|
||||||
|
cur = cur->next_sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vfs_node_t* devfs_create(vfs_node_t* parent, const char* name) {
|
||||||
|
vfs_node_t* node = kalloc(sizeof(vfs_node_t*));
|
||||||
|
memset((void*)node, 0, sizeof(vfs_node_t));
|
||||||
|
strcpy(node->name, name);
|
||||||
|
node->flags = VFS_CHARDEVICE;
|
||||||
|
if (parent->first_child) {
|
||||||
|
node->next_sibling = parent->first_child;
|
||||||
|
}
|
||||||
|
parent->first_child = node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfs_node_t* create_devfs() {
|
||||||
|
vfs_node_t* root = kalloc(sizeof(vfs_node_t*));
|
||||||
|
memset((void*)root, 0, sizeof(vfs_node_t));
|
||||||
|
strcpy(root->name, "dev");
|
||||||
|
root->find = devfs_find;
|
||||||
|
root->flags = VFS_DIRECTORY;
|
||||||
|
root->create = devfs_create;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
8
kernel/drivers/devfs/devfs.h
Normal file
8
kernel/drivers/devfs/devfs.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef D_DEVFS_H
|
||||||
|
#define D_DEVFS_H
|
||||||
|
|
||||||
|
#include <vfs.h>
|
||||||
|
|
||||||
|
vfs_node_t* create_devfs();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "lib/ringbuf.h"
|
#include "lib/ringbuf.h"
|
||||||
|
|
||||||
#include <drivers/pty/pty.h>
|
#include <drivers/pty/pty.h>
|
||||||
|
|
||||||
|
#include <lib/print.h>
|
||||||
|
|
||||||
uint32_t pty_master_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
|
uint32_t pty_master_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
|
||||||
pty_t* pty = (pty_t*)node->data;
|
pty_t* pty = (pty_t*)node->data;
|
||||||
uint32_t bytes_read = 0;
|
uint32_t bytes_read = 0;
|
||||||
|
|||||||
@@ -78,3 +78,14 @@ void vga_putchar(char c) {
|
|||||||
terminal_row = 0;
|
terminal_row = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) {
|
||||||
|
terminal_row = offset / VGA_WIDTH;
|
||||||
|
terminal_column = offset % VGA_WIDTH;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
|
vga_putchar((char)buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "memory/mm.h"
|
#include "memory/mm.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "scheduler.h"
|
||||||
|
|
||||||
#include <lib/memory.h>
|
#include <lib/memory.h>
|
||||||
|
#include <lib/print.h>
|
||||||
|
|
||||||
uint32_t load_elf_program(const char* prgm) {
|
uint32_t load_elf_program(const char* prgm) {
|
||||||
int fd = vfs_open(prgm, 0);
|
int fd = vfs_open(prgm, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
elf_header_t* e_hdr = kalloc(sizeof(elf_header_t));
|
elf_header_t* e_hdr = kalloc(sizeof(elf_header_t));
|
||||||
@@ -15,7 +18,7 @@ uint32_t load_elf_program(const char* prgm) {
|
|||||||
|
|
||||||
uint32_t bytes_rd = vfs_read(fd, e_hdr, sizeof(elf_header_t));
|
uint32_t bytes_rd = vfs_read(fd, e_hdr, sizeof(elf_header_t));
|
||||||
if (bytes_rd <= 0) {
|
if (bytes_rd <= 0) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ph_table_ptr = e_hdr->e_phoff;
|
uint32_t ph_table_ptr = e_hdr->e_phoff;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <drivers/pit/pit.h>
|
#include <drivers/pit/pit.h>
|
||||||
#include <drivers/vga/vga.h>
|
#include <drivers/vga/vga.h>
|
||||||
#include <drivers/cpio/cpio.h>
|
#include <drivers/cpio/cpio.h>
|
||||||
|
#include <drivers/devfs/devfs.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -65,6 +66,10 @@ void load_root_program(const char* path) {
|
|||||||
flush_tlb();
|
flush_tlb();
|
||||||
|
|
||||||
uint32_t eip = load_elf_program(path);
|
uint32_t eip = load_elf_program(path);
|
||||||
|
if (eip == 0) {
|
||||||
|
kprintf("Failed to load elf program file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t stack_sz = PAGE_SIZE * 16;
|
uint32_t stack_sz = PAGE_SIZE * 16;
|
||||||
uint32_t stack_top = 0xBFFF0000;
|
uint32_t stack_top = 0xBFFF0000;
|
||||||
@@ -122,12 +127,26 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
vfs_mount(vfs_root, initrd_root);
|
vfs_mount(vfs_root, initrd_root);
|
||||||
kprintf("initrd read, mounted @ /\n");
|
kprintf("initrd read, mounted @ /\n");
|
||||||
|
|
||||||
|
vfs_node_t* devfs = create_devfs();
|
||||||
|
if (!devfs) {
|
||||||
|
kprintf("failed to create devfs\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfs_node_t* vga_dev = devfs->create(devfs, "tvga");
|
||||||
|
vga_dev->write = vga_write;
|
||||||
|
|
||||||
|
vfs_node_t* dev = vfs_find("/dev");
|
||||||
|
if (dev) {
|
||||||
|
dev->mnt = devfs;
|
||||||
|
}
|
||||||
|
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
init_scheduler();
|
init_scheduler();
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
kprintf("loading terminal program\n");
|
kprintf("loading terminal program\n");
|
||||||
load_root_program("/vga_text_term.elf");
|
load_root_program("/bin/vga_text_term.elf");
|
||||||
|
|
||||||
kprintf("kernel going to sleep...\n");
|
kprintf("kernel going to sleep...\n");
|
||||||
}
|
}
|
||||||
|
|||||||
11
kernel/vfs.c
11
kernel/vfs.c
@@ -28,9 +28,11 @@ void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs) {
|
|||||||
|
|
||||||
vfs_node_t* vfs_find(const char* path) {
|
vfs_node_t* vfs_find(const char* path) {
|
||||||
vfs_node_t* current = root;
|
vfs_node_t* current = root;
|
||||||
|
if (current->mnt) {
|
||||||
|
current = current->mnt;
|
||||||
|
}
|
||||||
|
|
||||||
char* sav = NULL;
|
char* sav = NULL;
|
||||||
|
|
||||||
size_t path_sz = strlen(path) + 1;
|
size_t path_sz = strlen(path) + 1;
|
||||||
char* path_cpy = kalloc(path_sz);
|
char* path_cpy = kalloc(path_sz);
|
||||||
memset((uint8_t*)path_cpy, 0, path_sz);
|
memset((uint8_t*)path_cpy, 0, path_sz);
|
||||||
@@ -38,24 +40,27 @@ vfs_node_t* vfs_find(const char* path) {
|
|||||||
|
|
||||||
char* tkn = strtok_r(path_cpy, "/", &sav);
|
char* tkn = strtok_r(path_cpy, "/", &sav);
|
||||||
while (tkn != NULL) {
|
while (tkn != NULL) {
|
||||||
|
if (current && current->mnt) {
|
||||||
|
current = current->mnt;
|
||||||
|
}
|
||||||
|
|
||||||
if (!current || !current->find) {
|
if (!current || !current->find) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = current->find(current, tkn);
|
current = current->find(current, tkn);
|
||||||
tkn = strtok_r(NULL, "/", &sav);
|
|
||||||
|
|
||||||
if (current == NULL) {
|
if (current == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tkn = strtok_r(NULL, "/", &sav);
|
||||||
if (tkn && !(current->flags & VFS_DIRECTORY)) {
|
if (tkn && !(current->flags & VFS_DIRECTORY)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(path_cpy);
|
kfree(path_cpy);
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef uint32_t (*read_type_t)(struct vfs_node* node, uint32_t offset, uint32_t
|
|||||||
typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
|
||||||
typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name);
|
typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name);
|
||||||
typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name);
|
typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name);
|
||||||
|
typedef struct vfs_node* (*create_type_t)(struct vfs_node* node, const char* name);
|
||||||
|
|
||||||
typedef struct vfs_node {
|
typedef struct vfs_node {
|
||||||
char name[128];
|
char name[128];
|
||||||
@@ -29,6 +30,7 @@ typedef struct vfs_node {
|
|||||||
write_type_t write;
|
write_type_t write;
|
||||||
finddir_type_t find;
|
finddir_type_t find;
|
||||||
mkdir_type_t mkdir;
|
mkdir_type_t mkdir;
|
||||||
|
create_type_t create;
|
||||||
|
|
||||||
struct vfs_node* mnt;
|
struct vfs_node* mnt;
|
||||||
void* data;
|
void* data;
|
||||||
@@ -43,6 +45,8 @@ typedef struct {
|
|||||||
vfs_node_t* vfs_create_root();
|
vfs_node_t* vfs_create_root();
|
||||||
vfs_node_t* vfs_mkdir(vfs_node_t* parent, const char* name);
|
vfs_node_t* vfs_mkdir(vfs_node_t* parent, const char* name);
|
||||||
|
|
||||||
|
vfs_node_t* vfs_find(const char* path);
|
||||||
|
|
||||||
void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs);
|
void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs);
|
||||||
int vfs_open(const char* path, int flags);
|
int vfs_open(const char* path, int flags);
|
||||||
int vfs_read(int fd, void* buf, size_t sz);
|
int vfs_read(int fd, void* buf, size_t sz);
|
||||||
|
|||||||
12
make_img.sh
12
make_img.sh
@@ -1,14 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
mkdir -p initrd
|
mkdir -p initrd
|
||||||
rm -f initrd/*.elf
|
rm -f initrd/bin/*.elf
|
||||||
|
|
||||||
cp programs/bin/* initrd
|
mkdir -p initrd/dev
|
||||||
|
mkdir -p initrd/bin
|
||||||
|
cp programs/bin/* initrd/bin
|
||||||
|
|
||||||
cd initrd
|
cd initrd
|
||||||
mkdir -p dev
|
find . -depth -print | cpio -o -H newc > ../initrd.img
|
||||||
mkdir -p output
|
|
||||||
find . -depth -print | cpio -o -H newc > output/initrd.img
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
cp initrd/output/*.img isodir/boot
|
cp initrd.img isodir/boot
|
||||||
Binary file not shown.
@@ -9,5 +9,5 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
printf(shell_prompt);
|
printf(shell_prompt);
|
||||||
|
|
||||||
return 3;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ int main(int argc, char *argv[]) {
|
|||||||
dup2(0, 1);
|
dup2(0, 1);
|
||||||
dup2(0, 2);
|
dup2(0, 2);
|
||||||
|
|
||||||
exec("/rocksh.elf");
|
exec("/bin/rocksh.elf");
|
||||||
}
|
}
|
||||||
|
|
||||||
close(ptys);
|
close(ptys);
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "memory/mm.h"
|
|
||||||
#include "process.h"
|
|
||||||
#include "scheduler.h"
|
|
||||||
#include "kbd.h"
|
|
||||||
|
|
||||||
#include <drivers/vga/vga.h>
|
|
||||||
|
|
||||||
#include <lib/print.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int32_t sys_exit(int status) {
|
|
||||||
process_t* task = current_task();
|
|
||||||
task->state = STATE_DEAD;
|
|
||||||
kprintf("Process %d exited with status %d\n", task->pid, status);
|
|
||||||
exit();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t sys_write(int fd, const void* buf, size_t count) {
|
|
||||||
if (fd == 1 || fd == 2) { // stdout or stderr
|
|
||||||
const char* cbuf = (const char*)buf;
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
|
||||||
vga_putchar(cbuf[i]);
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t sys_read(int fd, void* buf, size_t count) {
|
|
||||||
if (fd == 0) {
|
|
||||||
char* cbuf = (char*)buf;
|
|
||||||
size_t bytes_read = 0;
|
|
||||||
|
|
||||||
while (bytes_read < count) {
|
|
||||||
kbd_wait();
|
|
||||||
|
|
||||||
if (kbd_ready()) {
|
|
||||||
char c = kbd_read();
|
|
||||||
cbuf[bytes_read++] = c;
|
|
||||||
if (c == '\n') break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bytes_read;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t sys_open(const char* filename, int flags) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t sys_close(int fd) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t sys_brk(uint32_t new_break) {
|
|
||||||
process_t* current = current_task();
|
|
||||||
|
|
||||||
if (new_break == 0) {
|
|
||||||
return current->heap_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_break < current->heap_end) {
|
|
||||||
current->heap_end = new_break;
|
|
||||||
return current->heap_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t page_start = (current->heap_end + 4095) & ~4095;
|
|
||||||
uint32_t page_end = (new_break + 4095) & ~4095;
|
|
||||||
|
|
||||||
for (uint32_t addr = page_start; addr < page_end; addr += 4096) {
|
|
||||||
// 1. Allocate a physical frame using your PMM (Physical Memory Manager)
|
|
||||||
void* phys = p_alloc_frame();
|
|
||||||
|
|
||||||
// 2. Map it into the current page directory using your VMM (Virtual Memory Manager)
|
|
||||||
map_page(addr, (uint32_t)phys, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
current->heap_end = new_break;
|
|
||||||
return current->heap_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct registers {
|
|
||||||
uint32_t gs, fs, es, ds; // Pushed manually
|
|
||||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
|
|
||||||
uint32_t int_no, err_code; // Pushed manually
|
|
||||||
uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU
|
|
||||||
} registers_t;
|
|
||||||
int32_t syscall(registers_t* regs) {
|
|
||||||
switch(regs->eax) {
|
|
||||||
case 1: return sys_exit(regs->ebx);
|
|
||||||
case 3: return sys_read(regs->ebx, (void*)regs->ecx, regs->edx);
|
|
||||||
case 4: return sys_write(regs->ebx, (const void*)regs->ecx, regs->edx);
|
|
||||||
case 5: return sys_open((const char*)regs->ebx, regs->ecx);
|
|
||||||
case 6: return sys_close(regs->ebx);
|
|
||||||
case 12: return sys_brk(regs->ebx);
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,7 @@ void exit(int status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int open(const char* path) {
|
int open(const char* path) {
|
||||||
return syscall1(SYS_OPEN, (uint32_t)path);
|
return syscall3(SYS_OPEN, (uint32_t)path, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write(int fd, const void* buf, size_t cnt) {
|
int write(int fd, const void* buf, size_t cnt) {
|
||||||
|
|||||||
Reference in New Issue
Block a user