working on reading elf from initrd, and getting it launched with the new scheduler
This commit is contained in:
@@ -3,3 +3,4 @@
|
|||||||
mkdir -p output
|
mkdir -p output
|
||||||
rm -rf output/*
|
rm -rf output/*
|
||||||
find . -depth -print | cpio -o -H newc > output/initrd.img
|
find . -depth -print | cpio -o -H newc > output/initrd.img
|
||||||
|
cp output/initrd.img ../isodir/boot
|
||||||
@@ -121,3 +121,5 @@ outsw:
|
|||||||
fetch_cr3:
|
fetch_cr3:
|
||||||
mov %cr3, %eax
|
mov %cr3, %eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.global set_cr3
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ static uint32_t cpio_read(struct vfs_node* node, uint32_t offset, uint32_t size,
|
|||||||
if (offset + size > node->size) {
|
if (offset + size > node->size) {
|
||||||
size = node->size - offset;
|
size = node->size - offset;
|
||||||
}
|
}
|
||||||
memcpy(buffer, (uint8_t*)(node->ptr) + offset, size);
|
memcpy((uint8_t*)(node->data) + offset, buffer, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ vfs_node_t* cpio_read_fs(uint32_t _vaddr) {
|
|||||||
|
|
||||||
current->flags = VFS_FILE;
|
current->flags = VFS_FILE;
|
||||||
current->read = cpio_read;
|
current->read = cpio_read;
|
||||||
current->ptr = (vfs_node_t*)file_data;
|
current->data = file_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t next_header_offset = file_data_offset + filesize;
|
uint32_t next_header_offset = file_data_offset + filesize;
|
||||||
|
|||||||
40
kernel/gdt.c
40
kernel/gdt.c
@@ -1,4 +1,4 @@
|
|||||||
#include <stdint.h>
|
#include <gdt.h>
|
||||||
|
|
||||||
#define SEG_DESCTYPE(x) ((x) << 0x04) // Descriptor type (0 for system, 1 for code/data)
|
#define SEG_DESCTYPE(x) ((x) << 0x04) // Descriptor type (0 for system, 1 for code/data)
|
||||||
#define SEG_PRES(x) ((x) << 0x07) // Present
|
#define SEG_PRES(x) ((x) << 0x07) // Present
|
||||||
@@ -46,40 +46,10 @@ typedef struct __attribute__((packed)) {
|
|||||||
uint32_t base;
|
uint32_t base;
|
||||||
} gdt_ptr_t;
|
} gdt_ptr_t;
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
|
||||||
uint32_t prev_tss;
|
|
||||||
uint32_t esp0;
|
|
||||||
uint32_t ss0;
|
|
||||||
uint32_t esp1;
|
|
||||||
uint32_t ss1;
|
|
||||||
uint32_t esp2;
|
|
||||||
uint32_t ss2;
|
|
||||||
uint32_t cr3;
|
|
||||||
uint32_t eip;
|
|
||||||
uint32_t eflags;
|
|
||||||
uint32_t eax;
|
|
||||||
uint32_t ecx;
|
|
||||||
uint32_t edx;
|
|
||||||
uint32_t ebx;
|
|
||||||
uint32_t esp;
|
|
||||||
uint32_t ebp;
|
|
||||||
uint32_t esi;
|
|
||||||
uint32_t edi;
|
|
||||||
uint32_t es;
|
|
||||||
uint32_t cs;
|
|
||||||
uint32_t ss;
|
|
||||||
uint32_t ds;
|
|
||||||
uint32_t fs;
|
|
||||||
uint32_t gs;
|
|
||||||
uint32_t ldt;
|
|
||||||
uint16_t trap;
|
|
||||||
uint16_t iomap_base;
|
|
||||||
} tss_entry;
|
|
||||||
|
|
||||||
uint64_t gdt[6];
|
uint64_t gdt[6];
|
||||||
gdt_ptr_t gdtr;
|
gdt_ptr_t gdtr;
|
||||||
|
|
||||||
tss_entry tss;
|
tss_entry_t tss;
|
||||||
|
|
||||||
extern void load_gdt();
|
extern void load_gdt();
|
||||||
extern void tss_flush();
|
extern void tss_flush();
|
||||||
@@ -126,14 +96,14 @@ void init_gdt() {
|
|||||||
gdt[3] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3));
|
gdt[3] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3));
|
||||||
gdt[4] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3));
|
gdt[4] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3));
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sizeof(tss_entry); i++) {
|
for (uint32_t i = 0; i < sizeof(tss_entry_t); i++) {
|
||||||
((char*)&tss)[i] = 0;
|
((char*)&tss)[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tss.ss0 = 0x10;
|
tss.ss0 = 0x10;
|
||||||
tss.iomap_base = sizeof(tss_entry);
|
tss.iomap_base = sizeof(tss_entry_t);
|
||||||
|
|
||||||
gdt[5] = create_tss_descriptor((uint32_t)&tss, sizeof(tss_entry) - 1);
|
gdt[5] = create_tss_descriptor((uint32_t)&tss, sizeof(tss_entry_t) - 1);
|
||||||
|
|
||||||
gdtr.limit = 6 * sizeof(uint64_t) - 1;
|
gdtr.limit = 6 * sizeof(uint64_t) - 1;
|
||||||
gdtr.base = (uint32_t)&gdt;
|
gdtr.base = (uint32_t)&gdt;
|
||||||
|
|||||||
34
kernel/gdt.h
34
kernel/gdt.h
@@ -1,6 +1,40 @@
|
|||||||
#ifndef KGDT_H
|
#ifndef KGDT_H
|
||||||
#define KGDT_H
|
#define KGDT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint32_t prev_tss;
|
||||||
|
uint32_t esp0;
|
||||||
|
uint32_t ss0;
|
||||||
|
uint32_t esp1;
|
||||||
|
uint32_t ss1;
|
||||||
|
uint32_t esp2;
|
||||||
|
uint32_t ss2;
|
||||||
|
uint32_t cr3;
|
||||||
|
uint32_t eip;
|
||||||
|
uint32_t eflags;
|
||||||
|
uint32_t eax;
|
||||||
|
uint32_t ecx;
|
||||||
|
uint32_t edx;
|
||||||
|
uint32_t ebx;
|
||||||
|
uint32_t esp;
|
||||||
|
uint32_t ebp;
|
||||||
|
uint32_t esi;
|
||||||
|
uint32_t edi;
|
||||||
|
uint32_t es;
|
||||||
|
uint32_t cs;
|
||||||
|
uint32_t ss;
|
||||||
|
uint32_t ds;
|
||||||
|
uint32_t fs;
|
||||||
|
uint32_t gs;
|
||||||
|
uint32_t ldt;
|
||||||
|
uint16_t trap;
|
||||||
|
uint16_t iomap_base;
|
||||||
|
} tss_entry_t;
|
||||||
|
|
||||||
void init_gdt();
|
void init_gdt();
|
||||||
|
|
||||||
|
extern tss_entry_t tss;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#include "initrd.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <lib/print.h>
|
|
||||||
#include <lib/memory.h>
|
|
||||||
|
|
||||||
void parse_cpio(void *initrd_start) {
|
|
||||||
cpio_header_t *head = (cpio_header_t *)initrd_start;
|
|
||||||
|
|
||||||
while (strncmp(head->c_magic, "070701", 6) == 0) {
|
|
||||||
// If we hit the trailer, we are done
|
|
||||||
char *filename = (char *)(head + 1);
|
|
||||||
if (strncmp(filename, "TRAILER!!!", 10) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t filesize = parse_hex(head->c_filesize);
|
|
||||||
uint32_t namesize = parse_hex(head->c_namesize);
|
|
||||||
|
|
||||||
kprintf("found file of size %d\n", filesize);
|
|
||||||
|
|
||||||
// Calculate where the data begins (accounting for 4-byte padding)
|
|
||||||
uint32_t header_plus_name = 110 + namesize;
|
|
||||||
header_plus_name = (header_plus_name + 3) & ~3; // Align to 4 bytes
|
|
||||||
|
|
||||||
char *file_data = (char *)head + header_plus_name;
|
|
||||||
|
|
||||||
uint32_t total_record_size = header_plus_name + filesize;
|
|
||||||
total_record_size = (total_record_size + 3) & ~3; // Align to 4 bytes
|
|
||||||
|
|
||||||
head = (cpio_header_t *)((char *)head + total_record_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#ifndef KINITRD_H
|
|
||||||
#define KINITRD_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char c_magic[6];
|
|
||||||
char c_ino[8];
|
|
||||||
char c_mode[8];
|
|
||||||
char c_uid[8];
|
|
||||||
char c_gid[8];
|
|
||||||
char c_nlink[8];
|
|
||||||
char c_mtime[8];
|
|
||||||
char c_filesize[8];
|
|
||||||
char c_devmajor[8];
|
|
||||||
char c_devminor[8];
|
|
||||||
char c_rdevmajor[8];
|
|
||||||
char c_rdevminor[8];
|
|
||||||
char c_namesize[8];
|
|
||||||
char c_check[8];
|
|
||||||
} cpio_header_t;
|
|
||||||
|
|
||||||
static inline uint32_t parse_hex(const char *s) {
|
|
||||||
uint32_t val = 0;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
val <<= 4;
|
|
||||||
if (s[i] >= '0' && s[i] <= '9') val += (s[i] - '0');
|
|
||||||
else if (s[i] >= 'A' && s[i] <= 'F') val += (s[i] - 'A' + 10);
|
|
||||||
else if (s[i] >= 'a' && s[i] <= 'f') val += (s[i] - 'a' + 10);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_cpio(void *initrd_start);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -44,15 +44,29 @@ ISR_ERRCODE 14 # Page Fault (Has Error Code!)
|
|||||||
.extern send_eoi_master # drivers/pic/pic.c
|
.extern send_eoi_master # drivers/pic/pic.c
|
||||||
isr32:
|
isr32:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
pushal
|
pushal
|
||||||
|
|
||||||
|
movw %ds, %ax
|
||||||
|
pushl %eax
|
||||||
|
|
||||||
|
movw $0x10, %ax # Load Kernel Data Segment descriptor
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call switch_context
|
call switch_context
|
||||||
movl %eax, %esp
|
movl %eax, %esp
|
||||||
|
|
||||||
call send_eoi_master
|
call send_eoi_master
|
||||||
|
|
||||||
|
popl %eax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
popal
|
popal
|
||||||
sti
|
sti
|
||||||
iret
|
iret
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
@@ -51,26 +52,73 @@ vfs_node_t* load_initrd() {
|
|||||||
return cpio_read_fs(initrd_module->mod_start);
|
return cpio_read_fs(initrd_module->mod_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_origin_program() {
|
void load_program(const char* path) {
|
||||||
vfs_node_t* vfs_root = vfs_create_root();
|
void* cr3 = create_task_pd();
|
||||||
vfs_node_t* initrd_root = load_initrd();
|
load_pd(cr3);
|
||||||
|
flush_tlb();
|
||||||
|
|
||||||
if (initrd_root) {
|
int fd = open(path, 0);
|
||||||
mount(vfs_root, initrd_root);
|
|
||||||
kprintf("initrd read, mounted @ /\n");
|
|
||||||
|
|
||||||
int fd = open("/origin.elf", 0);
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
kprintf("failed to read origin program\n");
|
kprintf("failed to open program: %s\n", path);
|
||||||
|
return;;
|
||||||
|
}
|
||||||
|
elf_header_t* e_hdr = kalloc(sizeof(elf_header_t));
|
||||||
|
memset((void*)e_hdr, 0, sizeof(elf_header_t));
|
||||||
|
|
||||||
|
uint32_t bytes_rd = read(fd, e_hdr, sizeof(elf_header_t));
|
||||||
|
if (bytes_rd <= 0) {
|
||||||
|
kprintf("failed to read program data for %s\n", path);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* buf = kalloc(512);
|
uint32_t ph_table_ptr = e_hdr->e_phoff;
|
||||||
int rd = read(fd, buf, 512);
|
elf_program_header_t* ph = kalloc(sizeof(elf_program_header_t));
|
||||||
if (rd > 0) {
|
uint32_t heap_start = 0;
|
||||||
kprintf("read %d bytes from origin.elf\n", rd);
|
|
||||||
|
for (uint32_t i = 0; i < e_hdr->e_phnum; i++) {
|
||||||
|
fseek(fd, ph_table_ptr);
|
||||||
|
memset((void*)ph, 0, sizeof(elf_program_header_t));
|
||||||
|
read(fd, ph, sizeof(elf_program_header_t));
|
||||||
|
|
||||||
|
if (ph->p_type == PT_LOAD) {
|
||||||
|
uint32_t vstart = ph->p_vaddr;
|
||||||
|
uint32_t vend = vstart + ph->p_memsz;
|
||||||
|
|
||||||
|
if (vend > heap_start) {
|
||||||
|
heap_start = vend;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t page_start = vstart & ~(PAGE_SIZE - 1);
|
||||||
|
uint32_t page_end = (vend + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||||
|
|
||||||
|
for (uint32_t v = page_start; v < page_end; v += PAGE_SIZE) {
|
||||||
|
void* phys_frame = p_alloc_frame();
|
||||||
|
map_page(v, (uint32_t)phys_frame, 0x07);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t data_ptr = ph->p_offset;
|
||||||
|
fseek(fd, data_ptr);
|
||||||
|
read(fd, (void*)vstart, ph->p_memsz);
|
||||||
|
|
||||||
|
// 0 out bss
|
||||||
|
if (ph->p_memsz > ph->p_filesz) {
|
||||||
|
size_t bss_size = ph->p_memsz - ph->p_filesz;
|
||||||
|
memset((void*)(vstart + ph->p_filesz), 0, bss_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit();
|
|
||||||
|
ph_table_ptr += sizeof(elf_program_header_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t esp = 0xBFFF0000;
|
||||||
|
void* pesp = p_alloc_frame();
|
||||||
|
map_page(esp - PAGE_SIZE, (uint32_t)pesp, 0x07);
|
||||||
|
|
||||||
|
create_task(e_hdr->e_entry, fetch_cr3(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_origin() {
|
||||||
|
load_program("/origin.elf");
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmain(uint32_t magic, multiboot_info* mbi) {
|
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||||
@@ -96,9 +144,19 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
|
|
||||||
kprintf("basic initializations complete\n");
|
kprintf("basic initializations complete\n");
|
||||||
|
|
||||||
|
vfs_node_t* vfs_root = vfs_create_root();
|
||||||
|
|
||||||
|
vfs_node_t* initrd_root = load_initrd();
|
||||||
|
if (!initrd_root) {
|
||||||
|
kprintf("failed to load initrd\n");
|
||||||
|
}
|
||||||
|
mount(vfs_root, initrd_root);
|
||||||
|
kprintf("initrd read, mounted @ /\n");
|
||||||
|
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
init_scheduler();
|
init_scheduler();
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
create_task((uint32_t)load_origin_program, fetch_cr3());
|
kprintf("loading user program\n");
|
||||||
|
start_origin();
|
||||||
}
|
}
|
||||||
|
|||||||
6
kernel/lib/string.h
Normal file
6
kernel/lib/string.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef KSTRING_H
|
||||||
|
#define KSTRING_H
|
||||||
|
|
||||||
|
char* strtok_r(char* str, const char* delim, char** saveptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
49
kernel/lib/strtok.c
Normal file
49
kernel/lib/strtok.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include <lib/string.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
static int is_delim(char c, const char* delim) {
|
||||||
|
while (*delim) {
|
||||||
|
if (c == *delim) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
delim++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strtok_r(char* str, const char* delim, char** saveptr) {
|
||||||
|
if (saveptr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* next_token = (str != NULL) ? str : *saveptr;
|
||||||
|
|
||||||
|
if (next_token == NULL || *next_token == '\0') {
|
||||||
|
*saveptr = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*next_token && is_delim(*next_token, delim)) {
|
||||||
|
next_token++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*next_token == '\0') {
|
||||||
|
*saveptr = next_token;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* token_start = next_token;
|
||||||
|
|
||||||
|
while (*next_token) {
|
||||||
|
if (is_delim(*next_token, delim)) {
|
||||||
|
*next_token = '\0'; // Destructively null-terminate the token
|
||||||
|
*saveptr = next_token + 1; // Save the position right after the null-terminator
|
||||||
|
return token_start;
|
||||||
|
}
|
||||||
|
next_token++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*saveptr = next_token;
|
||||||
|
return token_start;
|
||||||
|
}
|
||||||
@@ -8,8 +8,6 @@ extern uint8_t __kernel_start;
|
|||||||
extern uint8_t __kernel_end;
|
extern uint8_t __kernel_end;
|
||||||
|
|
||||||
extern uint32_t page_directory[1024];
|
extern uint32_t page_directory[1024];
|
||||||
extern void flush_tlb();
|
|
||||||
extern void disable_pae();
|
|
||||||
|
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
#define MAX_RAM 0xFFFFFFFF // 4GB
|
#define MAX_RAM 0xFFFFFFFF // 4GB
|
||||||
|
|||||||
@@ -24,4 +24,9 @@ void* create_task_pd();
|
|||||||
|
|
||||||
void map_page(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
void map_page(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
||||||
|
|
||||||
|
void load_pd(void* paddr);
|
||||||
|
|
||||||
|
void flush_tlb();
|
||||||
|
void disable_pae();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t pid;
|
uint32_t pid;
|
||||||
uint32_t esp;
|
uint32_t esp;
|
||||||
|
uint32_t esp0;
|
||||||
uint32_t cr3;
|
uint32_t cr3;
|
||||||
process_state_t state;
|
process_state_t state;
|
||||||
uint32_t sleep;
|
uint32_t sleep;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
#include "gdt.h"
|
||||||
|
|
||||||
static process_t* process_table;
|
static process_t* process_table;
|
||||||
|
|
||||||
@@ -68,9 +69,10 @@ uint32_t switch_context(uint32_t current_esp) {
|
|||||||
|
|
||||||
current_process = next_process;
|
current_process = next_process;
|
||||||
|
|
||||||
|
tss.esp0 = process_table[current_process].esp0;
|
||||||
|
|
||||||
if (fetch_cr3() != process_table[current_process].cr3) {
|
if (fetch_cr3() != process_table[current_process].cr3) {
|
||||||
extern void load_pd(uint32_t table);
|
load_pd((void*)process_table[current_process].cr3);
|
||||||
load_pd(process_table[current_process].cr3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return process_table[current_process].esp;
|
return process_table[current_process].esp;
|
||||||
@@ -88,12 +90,12 @@ void init_scheduler() {
|
|||||||
process->sleep = 0;
|
process->sleep = 0;
|
||||||
total_processes++;
|
total_processes++;
|
||||||
|
|
||||||
create_task((uint32_t)idle_task, fetch_cr3());
|
create_task((uint32_t)idle_task, fetch_cr3(), 0);
|
||||||
|
|
||||||
current_process = 0;
|
current_process = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_task(uint32_t entry_point, uint32_t cr3) {
|
int create_task(uint32_t entry_point, uint32_t cr3, int user) {
|
||||||
if (total_processes >= 16) {
|
if (total_processes >= 16) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -117,10 +119,20 @@ int create_task(uint32_t entry_point, uint32_t cr3) {
|
|||||||
|
|
||||||
void* stack_bottom = kalloc(4096);
|
void* stack_bottom = kalloc(4096);
|
||||||
uint32_t* esp = (uint32_t*)((uint32_t)stack_bottom + 4096);
|
uint32_t* esp = (uint32_t*)((uint32_t)stack_bottom + 4096);
|
||||||
|
process->esp0 = (uint32_t)esp;
|
||||||
|
|
||||||
*(--esp) = 0x0202; // EFLAGS
|
if (user) {
|
||||||
*(--esp) = 0x08; // CS
|
*(--esp) = 0x23; // User Data Segment (SS) with RPL 3 (0x20 | 3)
|
||||||
|
*(--esp) = 0xBFFFF000; // User Stack Pointer (ESP) - location mapped in user space
|
||||||
|
*(--esp) = 0x0202; // EFLAGS (Interrupts enabled)
|
||||||
|
*(--esp) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3)
|
||||||
*(--esp) = entry_point; // EIP
|
*(--esp) = entry_point; // EIP
|
||||||
|
} else {
|
||||||
|
// IRET values for Ring 0
|
||||||
|
*(--esp) = 0x0202; // EFLAGS
|
||||||
|
*(--esp) = 0x08; // Kernel Code Segment (CS)
|
||||||
|
*(--esp) = entry_point; // EIP
|
||||||
|
}
|
||||||
|
|
||||||
*(--esp) = 0; // EAX
|
*(--esp) = 0; // EAX
|
||||||
*(--esp) = 0; // ECX
|
*(--esp) = 0; // ECX
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
void init_scheduler();
|
void init_scheduler();
|
||||||
|
|
||||||
int create_task(uint32_t entry_point, uint32_t cr3);
|
int create_task(uint32_t entry_point, uint32_t cr3, int user);
|
||||||
process_t* current_task();
|
process_t* current_task();
|
||||||
|
|
||||||
void sleep(uint32_t ms);
|
void sleep(uint32_t ms);
|
||||||
|
|||||||
32
kernel/vfs.c
32
kernel/vfs.c
@@ -22,22 +22,22 @@ vfs_node_t* vfs_create_root() {
|
|||||||
|
|
||||||
void mount(vfs_node_t* _mnt, vfs_node_t* _fs) {
|
void mount(vfs_node_t* _mnt, vfs_node_t* _fs) {
|
||||||
if (!_fs || !_mnt || !(_mnt->flags & VFS_DIRECTORY)) return;
|
if (!_fs || !_mnt || !(_mnt->flags & VFS_DIRECTORY)) return;
|
||||||
_mnt->ptr = _fs;
|
_mnt->mnt = _fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vfs_node_t* lookup(const char* path) {
|
static vfs_node_t* lookup(const char* path) {
|
||||||
if (path[0] != '/') return NULL;
|
if (path[0] != '/') return NULL;
|
||||||
vfs_node_t* current = root;
|
vfs_node_t* current = root;
|
||||||
|
|
||||||
if (current->ptr) {
|
if (current->mnt) {
|
||||||
current = current->ptr;
|
current = current->mnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* component = path + 1;
|
const char* cmp = path + 1;
|
||||||
if (*component == '\0') return current;
|
if (*cmp == '\0') return current;
|
||||||
|
|
||||||
if (current->finddir) {
|
if (current->finddir) {
|
||||||
return current->finddir(current, component);
|
return current->finddir(current, cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -72,6 +72,22 @@ int read(int fd, void* buf, size_t sz) {
|
|||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fseek(int fd) {
|
int fstat(int fd, file_t* dst) {
|
||||||
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !fd_table[fd].node) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_t* src = &fd_table[fd];
|
||||||
|
memcpy(src, dst, sizeof(file_t));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fseek(int fd, size_t offset) {
|
||||||
|
if (fd < 0 || fd >= MAX_PROCESS_FDS || !fd_table[fd].node) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_t* file = &fd_table[fd];
|
||||||
|
file->offset = offset;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,8 @@ typedef struct vfs_node {
|
|||||||
write_type_t write;
|
write_type_t write;
|
||||||
finddir_type_t finddir;
|
finddir_type_t finddir;
|
||||||
|
|
||||||
struct vfs_node* ptr;
|
struct vfs_node* mnt;
|
||||||
|
void* data;
|
||||||
} vfs_node_t;
|
} vfs_node_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -40,4 +41,7 @@ void mount(vfs_node_t* _mnt, vfs_node_t* _fs);
|
|||||||
int open(const char* path, int flags);
|
int open(const char* path, int flags);
|
||||||
int read(int fd, void* buf, size_t sz);
|
int read(int fd, void* buf, size_t sz);
|
||||||
|
|
||||||
|
int fstat(int fd, file_t* _f);
|
||||||
|
int fseek(int fd, size_t offset);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
CC = i686-elf-gcc
|
CC = i686-elf-gcc
|
||||||
LD = i686-elf-ld
|
LD = i686-elf-ld
|
||||||
|
|
||||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra -I../rocklibc/include
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra -ffunction-sections -fdata-sections -I../rocklibc/include
|
||||||
LDFLAGS = -m elf_i386 -nostdlib
|
LDFLAGS = -m elf_i386 -nostdlib --gc-sections
|
||||||
|
|
||||||
TARGET = origin.elf
|
TARGET = origin.elf
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ main.o: main.c
|
|||||||
|
|
||||||
$(TARGET): crt0.o main.o ../rocklibc/rlibc.a
|
$(TARGET): crt0.o main.o ../rocklibc/rlibc.a
|
||||||
$(LD) $(LDFLAGS) -T linker.ld crt0.o main.o ../rocklibc/rlibc.a $(shell $(CC) -print-libgcc-file-name) -o $(TARGET)
|
$(LD) $(LDFLAGS) -T linker.ld crt0.o main.o ../rocklibc/rlibc.a $(shell $(CC) -print-libgcc-file-name) -o $(TARGET)
|
||||||
|
cp $(TARGET) ../initrd
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o $(TARGET)
|
rm -f *.o $(TARGET)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
CC = i686-elf-gcc
|
CC = i686-elf-gcc
|
||||||
AR = i686-elf-ar
|
AR = i686-elf-ar
|
||||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra -Iinclude -DHAVE_MMAP=0 -DLACKS_SYS_MMAN_H=1 -DUSE_LOCKS=0 -DLACKS_SYS_PARAM_H=1
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra -Iinclude -DHAVE_MMAP=0 -DLACKS_SYS_MMAN_H=1 -DUSE_LOCKS=0 -DLACKS_SYS_PARAM_H=1
|
||||||
|
CFLAGS += -ffunction-sections -fdata-sections
|
||||||
TARGET = rlibc.a
|
TARGET = rlibc.a
|
||||||
|
|
||||||
SRCS = $(shell find src -name "*.c")
|
SRCS = $(shell find src -name "*.c")
|
||||||
|
|||||||
Reference in New Issue
Block a user