almost got the term emu working and shell
This commit is contained in:
@@ -20,10 +20,4 @@ bear -- make
|
|||||||
cp vga_text_term.elf ../bin
|
cp vga_text_term.elf ../bin
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
cd test
|
|
||||||
make clean
|
|
||||||
bear -- make
|
|
||||||
cp test.elf ../bin
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
@@ -254,6 +254,23 @@
|
|||||||
"file": "/home/slinky/source/RockOS/kernel/interrupts.c",
|
"file": "/home/slinky/source/RockOS/kernel/interrupts.c",
|
||||||
"output": "/home/slinky/source/RockOS/obj/kernel/interrupts.c.o"
|
"output": "/home/slinky/source/RockOS/obj/kernel/interrupts.c.o"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/elf.c.o",
|
||||||
|
"kernel/elf.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/elf.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/elf.c.o"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
|||||||
65
kernel/elf.c
Normal file
65
kernel/elf.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#include "elf.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
#include "memory/mm.h"
|
||||||
|
|
||||||
|
#include <lib/memory.h>
|
||||||
|
|
||||||
|
uint32_t load_elf_program(const char* prgm) {
|
||||||
|
int fd = open(prgm, 0);
|
||||||
|
if (fd == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ph_table_ptr = e_hdr->e_phoff;
|
||||||
|
elf_program_header_t* ph = kalloc(sizeof(elf_program_header_t));
|
||||||
|
uint32_t heap_start = 0;
|
||||||
|
|
||||||
|
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, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t data_ptr = ph->p_offset;
|
||||||
|
fseek(fd, data_ptr);
|
||||||
|
read(fd, (void*)vstart, ph->p_filesz);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ph_table_ptr += sizeof(elf_program_header_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t eip = e_hdr->e_entry;
|
||||||
|
kfree(ph);
|
||||||
|
kfree(e_hdr);
|
||||||
|
|
||||||
|
return eip;
|
||||||
|
}
|
||||||
@@ -34,4 +34,6 @@ typedef struct {
|
|||||||
uint32_t p_align;
|
uint32_t p_align;
|
||||||
} __attribute__((packed)) elf_program_header_t;
|
} __attribute__((packed)) elf_program_header_t;
|
||||||
|
|
||||||
|
uint32_t load_elf_program(const char* prgm);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -64,65 +64,14 @@ void load_root_program(const char* path) {
|
|||||||
load_pd(cr3);
|
load_pd(cr3);
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
|
|
||||||
int fd = open(path, 0);
|
uint32_t eip = load_elf_program(path);
|
||||||
if (fd == -1) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ph_table_ptr = e_hdr->e_phoff;
|
|
||||||
elf_program_header_t* ph = kalloc(sizeof(elf_program_header_t));
|
|
||||||
uint32_t heap_start = 0;
|
|
||||||
|
|
||||||
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, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t data_ptr = ph->p_offset;
|
|
||||||
fseek(fd, data_ptr);
|
|
||||||
read(fd, (void*)vstart, ph->p_filesz);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ph_table_ptr += sizeof(elf_program_header_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t stack_sz = PAGE_SIZE * 16;
|
uint32_t stack_sz = PAGE_SIZE * 16;
|
||||||
uint32_t stack_top = 0xBFFF0000;
|
uint32_t stack_top = 0xBFFF0000;
|
||||||
uint32_t stack_bottom = stack_top - stack_sz;
|
uint32_t stack_bottom = stack_top - stack_sz;
|
||||||
for (uint32_t vaddr = stack_bottom; vaddr < stack_top; vaddr += PAGE_SIZE) {
|
for (uint32_t vaddr = stack_bottom; vaddr < stack_top; vaddr += PAGE_SIZE) {
|
||||||
void* phys_frame = p_alloc_frame();
|
void* phys_frame = p_alloc_frame();
|
||||||
map_page(vaddr, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
map_page(vaddr, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* u_esp = (uint32_t*)stack_top;
|
uint32_t* u_esp = (uint32_t*)stack_top;
|
||||||
@@ -131,7 +80,7 @@ void load_root_program(const char* path) {
|
|||||||
*(--u_esp) = 0; // argc = 0
|
*(--u_esp) = 0; // argc = 0
|
||||||
|
|
||||||
process_t* process = kalloc(sizeof(process_t));
|
process_t* process = kalloc(sizeof(process_t));
|
||||||
init_task(process, e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp);
|
init_task(process, eip, (uint32_t)cr3, 1, (uint32_t)u_esp);
|
||||||
add_task(process);
|
add_task(process);
|
||||||
|
|
||||||
unlock_scheduler();
|
unlock_scheduler();
|
||||||
@@ -164,8 +113,8 @@ 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* vfs_root = vfs_create_root();
|
||||||
|
|
||||||
vfs_node_t* initrd_root = load_initrd();
|
vfs_node_t* initrd_root = load_initrd();
|
||||||
|
|
||||||
if (!initrd_root) {
|
if (!initrd_root) {
|
||||||
kprintf("failed to load initrd\n");
|
kprintf("failed to load initrd\n");
|
||||||
}
|
}
|
||||||
@@ -177,8 +126,8 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
init_scheduler();
|
init_scheduler();
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
kprintf("loading test program\n");
|
kprintf("loading terminal program\n");
|
||||||
load_root_program("/test.elf");
|
load_root_program("/vga_text_term.elf");
|
||||||
|
|
||||||
kprintf("kernel going to sleep...\n");
|
kprintf("kernel going to sleep...\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -267,4 +267,8 @@ void* clone_current_pd() {
|
|||||||
unmap_page(TEMP_TASKPD_VADDR);
|
unmap_page(TEMP_TASKPD_VADDR);
|
||||||
|
|
||||||
return (void*)task_pd_addr;
|
return (void*)task_pd_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_current_pd() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,7 @@ uint32_t total_free_memory();
|
|||||||
|
|
||||||
void* create_new_pd();
|
void* create_new_pd();
|
||||||
void* clone_current_pd();
|
void* clone_current_pd();
|
||||||
|
void clear_current_pd();
|
||||||
|
|
||||||
int is_cow(uint32_t vaddr);
|
int is_cow(uint32_t vaddr);
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,10 @@ void init_task (
|
|||||||
process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL;
|
process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL;
|
||||||
total_processes++;
|
total_processes++;
|
||||||
|
|
||||||
|
if (process->kstack_top != 0) {
|
||||||
|
kfree((void*)process->kstack_top);
|
||||||
|
}
|
||||||
|
|
||||||
void* kstack_bottom = kalloc(PAGE_SIZE);
|
void* kstack_bottom = kalloc(PAGE_SIZE);
|
||||||
uint32_t kstack_top = (uint32_t)kstack_bottom + PAGE_SIZE;
|
uint32_t kstack_top = (uint32_t)kstack_bottom + PAGE_SIZE;
|
||||||
process->kstack_top = kstack_top;
|
process->kstack_top = kstack_top;
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <drivers/pty/pty.h>
|
|
||||||
#include "lib/memory.h"
|
#include "lib/memory.h"
|
||||||
#include "lib/ringbuf.h"
|
#include "lib/ringbuf.h"
|
||||||
|
|
||||||
#include "memory/mm.h"
|
#include "memory/mm.h"
|
||||||
|
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#include <drivers/vga/vga.h>
|
#include <drivers/vga/vga.h>
|
||||||
|
#include <drivers/pty/pty.h>
|
||||||
|
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
@@ -53,11 +56,13 @@ static int32_t sys_read(int fd, void* buf, size_t count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int32_t sys_open(const char* filename, int flags) {
|
static int32_t sys_open(const char* filename, int flags) {
|
||||||
return -1;
|
return open(filename, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t sys_close(int fd) {
|
static int32_t sys_close(int fd) {
|
||||||
return -1;
|
process_t* task = current_task();
|
||||||
|
task->fd_table[fd] = NULL;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t sys_brk(uint32_t new_break) {
|
static int32_t sys_brk(uint32_t new_break) {
|
||||||
@@ -155,6 +160,42 @@ static int32_t sys_fork(registers_t* parent_regs) {
|
|||||||
return child->pid;
|
return child->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t sys_exec(registers_t* regs, const char* prgm) {
|
||||||
|
clear_current_pd();
|
||||||
|
|
||||||
|
uint32_t eip = load_elf_program(prgm);
|
||||||
|
|
||||||
|
uint32_t stack_sz = PAGE_SIZE * 16;
|
||||||
|
uint32_t stack_top = 0xBFFF0000;
|
||||||
|
uint32_t stack_bottom = stack_top - stack_sz;
|
||||||
|
for (uint32_t vaddr = stack_bottom; vaddr < stack_top; vaddr += PAGE_SIZE) {
|
||||||
|
void* phys_frame = p_alloc_frame();
|
||||||
|
map_page(vaddr, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t* u_esp = (uint32_t*)stack_top;
|
||||||
|
*(--u_esp) = 0; // envp = NULL
|
||||||
|
*(--u_esp) = 0; // argv = NULL
|
||||||
|
*(--u_esp) = 0; // argc = 0
|
||||||
|
|
||||||
|
regs->eax = 0;
|
||||||
|
regs->ecx = 0;
|
||||||
|
regs->edx = 0;
|
||||||
|
regs->ebp = 0;
|
||||||
|
regs->esi = 0;
|
||||||
|
regs->edi = 0;
|
||||||
|
regs->eip = eip;
|
||||||
|
regs->useresp = (uint32_t)u_esp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t sys_dup2(int src, int dst) {
|
||||||
|
process_t* task = current_task();
|
||||||
|
task->fd_table[dst] = task->fd_table[src];
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
void syscall(registers_t* regs) {
|
void syscall(registers_t* regs) {
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
switch(regs->eax) {
|
switch(regs->eax) {
|
||||||
@@ -166,6 +207,8 @@ void syscall(registers_t* regs) {
|
|||||||
case 12: ret = sys_brk(regs->ebx); break;
|
case 12: ret = sys_brk(regs->ebx); break;
|
||||||
case 20: ret = sys_pty((int*)regs->ebx); break;
|
case 20: ret = sys_pty((int*)regs->ebx); break;
|
||||||
case 21: ret = sys_fork(regs); break;
|
case 21: ret = sys_fork(regs); break;
|
||||||
|
case 22: ret = sys_exec(regs, (const char*)regs->ebx); break;
|
||||||
|
case 23: ret = sys_dup2(regs->ebx, regs->ecx); break;
|
||||||
default: ret = -1;
|
default: ret = -1;
|
||||||
}
|
}
|
||||||
regs->eax = ret;
|
regs->eax = ret;
|
||||||
|
|||||||
1
programs/compile_commands.json
Normal file
1
programs/compile_commands.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
Binary file not shown.
@@ -1,46 +1,13 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
const char* shell_prompt = "rocksh> ";
|
const char* shell_prompt = "rocksh> ";
|
||||||
|
|
||||||
static void process_cmd(const char* cmd) {
|
|
||||||
size_t cmd_len = strlen(cmd);
|
|
||||||
if (cmd_len < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(cmd, "exit") == 0) {
|
|
||||||
printf("bye!\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("command not recognized: %s\n", cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
char cmd[128];
|
printf(shell_prompt);
|
||||||
size_t p = 0;
|
|
||||||
|
|
||||||
printf("%s", shell_prompt);
|
|
||||||
|
|
||||||
while (1) {
|
return 3;
|
||||||
char c = getchar();
|
|
||||||
printf("%c", c);
|
|
||||||
if (c != '\n') {
|
|
||||||
cmd[p++] = c;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd[p] = 0;
|
|
||||||
process_cmd(cmd);
|
|
||||||
memset(cmd, 0, 128);
|
|
||||||
p = 0;
|
|
||||||
printf("%s", shell_prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
|
||||||
"-ffreestanding",
|
|
||||||
"-O2",
|
|
||||||
"-Wall",
|
|
||||||
"-Wextra",
|
|
||||||
"-I../../rocklibc/include",
|
|
||||||
"-c",
|
|
||||||
"-o",
|
|
||||||
"crt0.o",
|
|
||||||
"crt0.S"
|
|
||||||
],
|
|
||||||
"directory": "/home/slinky/source/RockOS/programs/test",
|
|
||||||
"file": "/home/slinky/source/RockOS/programs/test/crt0.S",
|
|
||||||
"output": "/home/slinky/source/RockOS/programs/test/crt0.o"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"arguments": [
|
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
|
||||||
"-ffreestanding",
|
|
||||||
"-O2",
|
|
||||||
"-Wall",
|
|
||||||
"-Wextra",
|
|
||||||
"-I../../rocklibc/include",
|
|
||||||
"-c",
|
|
||||||
"-o",
|
|
||||||
"main.o",
|
|
||||||
"main.c"
|
|
||||||
],
|
|
||||||
"directory": "/home/slinky/source/RockOS/programs/test",
|
|
||||||
"file": "/home/slinky/source/RockOS/programs/test/main.c",
|
|
||||||
"output": "/home/slinky/source/RockOS/programs/test/main.o"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
.global _start
|
|
||||||
.extern exit
|
|
||||||
.section .text
|
|
||||||
_start:
|
|
||||||
xor %ebp, %ebp
|
|
||||||
|
|
||||||
mov (%esp), %eax
|
|
||||||
lea 4(%esp), %ebx
|
|
||||||
lea 8(%esp,%eax,4), %ecx
|
|
||||||
|
|
||||||
and $-16, %esp
|
|
||||||
|
|
||||||
push %ecx
|
|
||||||
push %ebx
|
|
||||||
push %eax
|
|
||||||
|
|
||||||
call main
|
|
||||||
|
|
||||||
push %eax
|
|
||||||
call exit
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
. = 0x40000000;
|
|
||||||
|
|
||||||
.text ALIGN(4K) :
|
|
||||||
{
|
|
||||||
/* Force the crt0.o entry code to be placed FIRST in memory */
|
|
||||||
KEEP(*crt0.o(.text))
|
|
||||||
*(.text .text.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
.rodata ALIGN(4K) :
|
|
||||||
{
|
|
||||||
*(.rodata .rodata.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
.data ALIGN(4K) :
|
|
||||||
{
|
|
||||||
*(.data .data.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
.bss ALIGN(4K) :
|
|
||||||
{
|
|
||||||
_bss_start = .;
|
|
||||||
*(.bss .bss.*)
|
|
||||||
*(COMMON)
|
|
||||||
_bss_end = .;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#include "syscall.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
|
|
||||||
if (fork() == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
CC = i686-elf-gcc
|
|
||||||
LD = i686-elf-ld
|
|
||||||
|
|
||||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra -I../../rocklibc/include
|
|
||||||
LDFLAGS = -m elf_i386 -nostdlib
|
|
||||||
|
|
||||||
TARGET = test.elf
|
|
||||||
|
|
||||||
all: $(TARGET)
|
|
||||||
|
|
||||||
crt0.o: crt0.S
|
|
||||||
$(CC) $(CFLAGS) -c crt0.S -o crt0.o
|
|
||||||
|
|
||||||
main.o: main.c
|
|
||||||
$(CC) $(CFLAGS) -c main.c -o main.o
|
|
||||||
|
|
||||||
$(TARGET): crt0.o main.o ../lib/rlibc.a
|
|
||||||
$(LD) $(LDFLAGS) -T linker.ld crt0.o main.o ../lib/rlibc.a -o $(TARGET)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o $(TARGET)
|
|
||||||
|
|
||||||
.PHONY: all clean test
|
|
||||||
@@ -1,5 +1,44 @@
|
|||||||
#include <stdio.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void term();
|
||||||
|
|
||||||
|
int ptys;
|
||||||
|
int ptym;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
ptym = pty(&ptys);
|
||||||
|
|
||||||
|
if (fork() == 0) {
|
||||||
|
close(ptym);
|
||||||
|
dup2(ptys, 0);
|
||||||
|
dup2(0, 1);
|
||||||
|
dup2(0, 2);
|
||||||
|
|
||||||
|
exec("/rocksh.elf");
|
||||||
|
}
|
||||||
|
|
||||||
|
close(ptys);
|
||||||
|
dup2(ptym, 0);
|
||||||
|
dup2(0, 1);
|
||||||
|
dup2(0, 2);
|
||||||
|
|
||||||
|
term();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void term() {
|
||||||
|
int vga_fd = open("/dev/tvga");
|
||||||
|
if (vga_fd == -1) return;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
char c;
|
||||||
|
int rd = read(0, &c, 1);
|
||||||
|
if (rd > 0) {
|
||||||
|
write(vga_fd, &c, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,9 +7,14 @@
|
|||||||
#define SYS_EXIT 1
|
#define SYS_EXIT 1
|
||||||
#define SYS_READ 3
|
#define SYS_READ 3
|
||||||
#define SYS_WRITE 4
|
#define SYS_WRITE 4
|
||||||
|
#define SYS_OPEN 5
|
||||||
|
#define SYS_CLOSE 6
|
||||||
#define SYS_PTY 20
|
#define SYS_PTY 20
|
||||||
#define SYS_FORK 21
|
#define SYS_FORK 21
|
||||||
|
#define SYS_EXEC 22
|
||||||
|
#define SYS_DUP2 23
|
||||||
|
|
||||||
|
int open(const char* path);
|
||||||
int write(int fd, const void *buf, size_t count);
|
int write(int fd, const void *buf, size_t count);
|
||||||
int read(int fd, void *buf, size_t count);
|
int read(int fd, void *buf, size_t count);
|
||||||
int close(int fd);
|
int close(int fd);
|
||||||
@@ -22,6 +27,9 @@ void *sbrk(intptr_t increment);
|
|||||||
int brk(void *addr);
|
int brk(void *addr);
|
||||||
|
|
||||||
int pty(int* slave);
|
int pty(int* slave);
|
||||||
|
|
||||||
int fork();
|
int fork();
|
||||||
|
int exec(const char* path);
|
||||||
|
int dup2(int src, int dst);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -27,6 +27,10 @@ void exit(int status) {
|
|||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int open(const char* path) {
|
||||||
|
return syscall1(SYS_OPEN, (uint32_t)path);
|
||||||
|
}
|
||||||
|
|
||||||
int write(int fd, const void* buf, size_t cnt) {
|
int write(int fd, const void* buf, size_t cnt) {
|
||||||
return syscall3(SYS_WRITE, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt);
|
return syscall3(SYS_WRITE, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt);
|
||||||
}
|
}
|
||||||
@@ -35,10 +39,22 @@ int read(int fd, void* buf, size_t cnt) {
|
|||||||
return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt);
|
return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int close(int fd) {
|
||||||
|
return syscall1(SYS_CLOSE, fd);
|
||||||
|
}
|
||||||
|
|
||||||
int pty(int* slave) {
|
int pty(int* slave) {
|
||||||
return syscall1(SYS_PTY, (uint32_t)slave);
|
return syscall1(SYS_PTY, (uint32_t)slave);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fork() {
|
int fork() {
|
||||||
return syscall1(SYS_FORK, 0);
|
return syscall1(SYS_FORK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int exec(const char* path) {
|
||||||
|
return syscall1(SYS_EXEC, (uint32_t)path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dup2(int src, int dst) {
|
||||||
|
return syscall3(SYS_DUP2, src, dst, 0);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user