more userspace stuff
This commit is contained in:
21
deploy_programs.sh
Executable file
21
deploy_programs.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd rocklibc
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
cd programs
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
|
||||||
|
cd initrd
|
||||||
|
./make_img.sh
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
make -B
|
||||||
|
|
||||||
@@ -29,14 +29,19 @@ liftoff:
|
|||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
|
|
||||||
push $0x23
|
pushl $0x23 # User Data Segment (SS)
|
||||||
push %ebx
|
pushl %ebx # User Stack Pointer (ESP)
|
||||||
push $0x202
|
pushl $0x202 # EFLAGS (Interrupts enabled, bit 1 standard)
|
||||||
push $0x1B
|
pushl $0x1B # User Code Segment (CS)
|
||||||
push %ecx
|
pushl %ecx # User Entry Point (EIP)
|
||||||
|
|
||||||
xor %eax, %eax
|
xor %eax, %eax
|
||||||
|
xor %ebx, %ebx
|
||||||
|
xor %ecx, %ecx
|
||||||
xor %edx, %edx
|
xor %edx, %edx
|
||||||
|
xor %esi, %esi
|
||||||
|
xor %edi, %edi
|
||||||
|
xor %ebp, %ebp
|
||||||
|
|
||||||
iret
|
iret
|
||||||
|
|
||||||
@@ -121,5 +126,3 @@ outsw:
|
|||||||
fetch_cr3:
|
fetch_cr3:
|
||||||
mov %cr3, %eax
|
mov %cr3, %eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global set_cr3
|
|
||||||
|
|||||||
@@ -7,4 +7,6 @@ void enable_interrupts();
|
|||||||
void disable_interrupts();
|
void disable_interrupts();
|
||||||
uint32_t fetch_cr3();
|
uint32_t fetch_cr3();
|
||||||
|
|
||||||
|
void liftoff(uint32_t entry_point, uint32_t user_stack) __attribute__((noreturn));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -33,9 +33,9 @@ init_pic:
|
|||||||
outb %al, $PIC2_DATA
|
outb %al, $PIC2_DATA
|
||||||
|
|
||||||
# mask
|
# mask
|
||||||
mov $0xF8, %al
|
mov $0xFF, %al
|
||||||
outb %al, $PIC1_DATA
|
outb %al, $PIC1_DATA
|
||||||
mov $0x3F, %al
|
mov $0xFF, %al
|
||||||
outb %al, $PIC2_DATA
|
outb %al, $PIC2_DATA
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ typedef struct __attribute__((packed)) {
|
|||||||
} tss_entry_t;
|
} tss_entry_t;
|
||||||
|
|
||||||
void init_gdt();
|
void init_gdt();
|
||||||
|
void tss_flush();
|
||||||
|
|
||||||
extern tss_entry_t tss;
|
extern tss_entry_t tss;
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void common_interrupt_handler(registers *args) {
|
|||||||
case 13:
|
case 13:
|
||||||
case 15:
|
case 15:
|
||||||
case 16:
|
case 16:
|
||||||
kprintf("CPU Error: %s", err_messages[args->int_no]);
|
kprintf("CPU Error: %s, %d\n", err_messages[args->int_no], args->error_code);
|
||||||
break;
|
break;
|
||||||
case 14:{
|
case 14:{
|
||||||
uint32_t faulting_address;
|
uint32_t faulting_address;
|
||||||
@@ -119,6 +119,9 @@ void common_interrupt_handler(registers *args) {
|
|||||||
kprintf("Faulted Virtual Address: 0x%x\n", faulting_address);
|
kprintf("Faulted Virtual Address: 0x%x\n", faulting_address);
|
||||||
kprintf("Error Code: 0x%x\n", args->error_code);
|
kprintf("Error Code: 0x%x\n", args->error_code);
|
||||||
kprintf("Instruction Pointer: 0x%x\n", args->eip);
|
kprintf("Instruction Pointer: 0x%x\n", args->eip);
|
||||||
|
kprintf("Stack Pointer: 0x%x\n", args->useresp);
|
||||||
|
kprintf("EAX: 0x%x\n", args->eax);
|
||||||
|
kprintf("EFLAGS: 0x%x\n", args->eflags);
|
||||||
kprintf("Caused by: %s, %s, running in %s mode\n",
|
kprintf("Caused by: %s, %s, running in %s mode\n",
|
||||||
(args->error_code & 0x01) ? "Protection Violation" : "Page Not Present",
|
(args->error_code & 0x01) ? "Protection Violation" : "Page Not Present",
|
||||||
(args->error_code & 0x02) ? "Write" : "Read",
|
(args->error_code & 0x02) ? "Write" : "Read",
|
||||||
@@ -127,15 +130,18 @@ void common_interrupt_handler(registers *args) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 33: {
|
case 33: {
|
||||||
|
kprintf("ps2 keyboard interrupt\n");
|
||||||
uint8_t data = ps2_read_data();
|
uint8_t data = ps2_read_data();
|
||||||
send_eoi_master();
|
send_eoi_master();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 46: { // IDE PRIMARY
|
case 46: { // IDE PRIMARY
|
||||||
|
kprintf("IDE PRIMARY interrupt\n");
|
||||||
send_eoi_slave();
|
send_eoi_slave();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 47: { // IDE SLAVE
|
case 47: { // IDE SLAVE
|
||||||
|
kprintf("IDE SLAVE interrupt\n");
|
||||||
send_eoi_slave();
|
send_eoi_slave();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "scheduler.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "scheduler.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
#include "gdt.h"
|
||||||
|
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
@@ -26,6 +27,9 @@
|
|||||||
extern char __kernel_start;
|
extern char __kernel_start;
|
||||||
extern char __kernel_end;
|
extern char __kernel_end;
|
||||||
|
|
||||||
|
extern uint32_t page_directory[1024];
|
||||||
|
void* kernel_cr3 = page_directory;
|
||||||
|
|
||||||
void parse_multiboot_modules(uint32_t mbi_vaddr) {
|
void parse_multiboot_modules(uint32_t mbi_vaddr) {
|
||||||
// find where grub put the boot module containing initrd
|
// find where grub put the boot module containing initrd
|
||||||
multiboot_info* mbi = (multiboot_info*)mbi_vaddr;
|
multiboot_info* mbi = (multiboot_info*)mbi_vaddr;
|
||||||
@@ -52,7 +56,8 @@ vfs_node_t* load_initrd() {
|
|||||||
return cpio_read_fs(initrd_module->mod_start);
|
return cpio_read_fs(initrd_module->mod_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_program(const char* path) {
|
void load_root_program(const char* path) {
|
||||||
|
uint32_t kernel_cr3 = fetch_cr3();
|
||||||
void* cr3 = create_task_pd();
|
void* cr3 = create_task_pd();
|
||||||
load_pd(cr3);
|
load_pd(cr3);
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
@@ -93,12 +98,12 @@ void load_program(const char* path) {
|
|||||||
|
|
||||||
for (uint32_t v = page_start; v < page_end; v += PAGE_SIZE) {
|
for (uint32_t v = page_start; v < page_end; v += PAGE_SIZE) {
|
||||||
void* phys_frame = p_alloc_frame();
|
void* phys_frame = p_alloc_frame();
|
||||||
map_page(v, (uint32_t)phys_frame, 0x07);
|
map_page(v, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t data_ptr = ph->p_offset;
|
uint32_t data_ptr = ph->p_offset;
|
||||||
fseek(fd, data_ptr);
|
fseek(fd, data_ptr);
|
||||||
read(fd, (void*)vstart, ph->p_memsz);
|
read(fd, (void*)vstart, ph->p_filesz);
|
||||||
|
|
||||||
// 0 out bss
|
// 0 out bss
|
||||||
if (ph->p_memsz > ph->p_filesz) {
|
if (ph->p_memsz > ph->p_filesz) {
|
||||||
@@ -110,15 +115,24 @@ void load_program(const char* path) {
|
|||||||
ph_table_ptr += sizeof(elf_program_header_t);
|
ph_table_ptr += sizeof(elf_program_header_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t esp = 0xBFFF0000;
|
uint32_t stack_sz = PAGE_SIZE * 16;
|
||||||
void* pesp = p_alloc_frame();
|
uint32_t stack_top = 0xBFFF0000;
|
||||||
map_page(esp - PAGE_SIZE, (uint32_t)pesp, 0x07);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
create_task(e_hdr->e_entry, fetch_cr3(), 1);
|
uint32_t* u_esp = (uint32_t*)stack_top;
|
||||||
}
|
*(--u_esp) = 0; // envp = NULL
|
||||||
|
*(--u_esp) = 0; // argv = NULL
|
||||||
|
*(--u_esp) = 0; // argc = 0
|
||||||
|
|
||||||
void start_origin() {
|
create_task(e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp);
|
||||||
load_program("/origin.elf");
|
load_pd((void*)kernel_cr3);
|
||||||
|
flush_tlb();
|
||||||
|
|
||||||
|
kprintf("task created for origin program %s\n", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmain(uint32_t magic, multiboot_info* mbi) {
|
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||||
@@ -150,13 +164,14 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
if (!initrd_root) {
|
if (!initrd_root) {
|
||||||
kprintf("failed to load initrd\n");
|
kprintf("failed to load initrd\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
mount(vfs_root, initrd_root);
|
mount(vfs_root, initrd_root);
|
||||||
kprintf("initrd read, mounted @ /\n");
|
kprintf("initrd read, mounted @ /\n");
|
||||||
|
|
||||||
disable_interrupts();
|
|
||||||
init_scheduler();
|
init_scheduler();
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
kprintf("loading user program\n");
|
kprintf("loading origin program\n");
|
||||||
start_origin();
|
load_root_program("/origin.elf");
|
||||||
|
yield();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,3 +135,7 @@ void* kalloc(size_t sz) {
|
|||||||
|
|
||||||
return kalloc(sz);
|
return kalloc(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kfree(void* ptr) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -14,6 +14,6 @@ char* strcpy(char* dest, const char* src);
|
|||||||
|
|
||||||
void kgrow(size_t pages);
|
void kgrow(size_t pages);
|
||||||
void* kalloc(size_t sz);
|
void* kalloc(size_t sz);
|
||||||
|
void kfree(void* ptr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -18,6 +18,9 @@ extern uint32_t page_directory[1024];
|
|||||||
|
|
||||||
#define TEMP_MAPPING_VADDR 0xDFFF0000
|
#define TEMP_MAPPING_VADDR 0xDFFF0000
|
||||||
|
|
||||||
|
#define USR_PAGE 0x07
|
||||||
|
#define SUP_PAGE 0x03
|
||||||
|
|
||||||
static uint32_t max_address = 0;
|
static uint32_t max_address = 0;
|
||||||
static uint32_t total_available_memory = 0;
|
static uint32_t total_available_memory = 0;
|
||||||
static uint8_t memory_bitmap[BITMAP_SIZE];
|
static uint8_t memory_bitmap[BITMAP_SIZE];
|
||||||
|
|||||||
@@ -10,15 +10,21 @@ typedef enum {
|
|||||||
STATE_DEAD
|
STATE_DEAD
|
||||||
} process_state_t;
|
} process_state_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROCESS_FLAG_NONE = 0,
|
||||||
|
PROCESS_FLAG_KERNEL = 1 << 0,
|
||||||
|
PROCESS_FLAG_USER = 1 << 1
|
||||||
|
} process_flags_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t pid;
|
uint32_t pid;
|
||||||
uint32_t esp;
|
uint32_t esp;
|
||||||
uint32_t esp0;
|
uint32_t kstack_top;
|
||||||
uint32_t cr3;
|
uint32_t cr3;
|
||||||
process_state_t state;
|
process_state_t state;
|
||||||
uint32_t sleep;
|
uint32_t sleep;
|
||||||
void* next;
|
|
||||||
uint32_t heap_end;
|
uint32_t heap_end;
|
||||||
|
uint32_t flags;
|
||||||
} __attribute__((packed)) process_t;
|
} __attribute__((packed)) process_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -18,8 +18,6 @@ yield: # void yield()
|
|||||||
movl %ebx, 4(%esp) # Move Return EIP over CS
|
movl %ebx, 4(%esp) # Move Return EIP over CS
|
||||||
addl $4, %esp # Adjust stack pointer up.
|
addl $4, %esp # Adjust stack pointer up.
|
||||||
|
|
||||||
# the stack now looks like a hardware interrupt just happened, even though we never called one.
|
|
||||||
|
|
||||||
pushal
|
pushal
|
||||||
|
|
||||||
pushl %esp
|
pushl %esp
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <lib/tasks.h>
|
#include <lib/tasks.h>
|
||||||
|
#include <lib/print.h>
|
||||||
#include <lib/memory.h>
|
#include <lib/memory.h>
|
||||||
|
|
||||||
#include <memory/mm.h>
|
#include <memory/mm.h>
|
||||||
@@ -69,7 +70,9 @@ uint32_t switch_context(uint32_t current_esp) {
|
|||||||
|
|
||||||
current_process = next_process;
|
current_process = next_process;
|
||||||
|
|
||||||
tss.esp0 = process_table[current_process].esp0;
|
if (process_table[current_process].flags & PROCESS_FLAG_USER ) {
|
||||||
|
tss.esp0 = process_table[current_process].kstack_top;
|
||||||
|
}
|
||||||
|
|
||||||
if (fetch_cr3() != process_table[current_process].cr3) {
|
if (fetch_cr3() != process_table[current_process].cr3) {
|
||||||
load_pd((void*)process_table[current_process].cr3);
|
load_pd((void*)process_table[current_process].cr3);
|
||||||
@@ -88,14 +91,15 @@ void init_scheduler() {
|
|||||||
process->cr3 = fetch_cr3();
|
process->cr3 = fetch_cr3();
|
||||||
process->state = STATE_READY;
|
process->state = STATE_READY;
|
||||||
process->sleep = 0;
|
process->sleep = 0;
|
||||||
|
process->flags = PROCESS_FLAG_KERNEL;
|
||||||
total_processes++;
|
total_processes++;
|
||||||
|
|
||||||
create_task((uint32_t)idle_task, fetch_cr3(), 0);
|
create_task((uint32_t)idle_task, fetch_cr3(), 0, 0);
|
||||||
|
|
||||||
current_process = 0;
|
current_process = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_task(uint32_t entry_point, uint32_t cr3, int user) {
|
int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp) {
|
||||||
if (total_processes >= 16) {
|
if (total_processes >= 16) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -103,12 +107,14 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user) {
|
|||||||
lock_scheduler();
|
lock_scheduler();
|
||||||
|
|
||||||
// default to a new task, but if we find a dead one, re use it
|
// default to a new task, but if we find a dead one, re use it
|
||||||
|
int reuse = 0;
|
||||||
process_t* process = &process_table[total_processes];
|
process_t* process = &process_table[total_processes];
|
||||||
uint32_t pid = total_processes;
|
uint32_t pid = total_processes;
|
||||||
for (uint32_t i = 0; i < total_processes; i++) {
|
for (uint32_t i = 0; i < total_processes; i++) {
|
||||||
if (process_table[i].state == STATE_DEAD) {
|
if (process_table[i].state == STATE_DEAD) {
|
||||||
process = &process_table[i];
|
process = &process_table[i];
|
||||||
pid = i;
|
pid = i;
|
||||||
|
reuse = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,22 +122,26 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user) {
|
|||||||
process->cr3 = cr3;
|
process->cr3 = cr3;
|
||||||
process->state = STATE_READY;
|
process->state = STATE_READY;
|
||||||
process->sleep = 0;
|
process->sleep = 0;
|
||||||
|
process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL;
|
||||||
|
|
||||||
void* stack_bottom = kalloc(4096);
|
void* kstack_bottom = kalloc(PAGE_SIZE);
|
||||||
uint32_t* esp = (uint32_t*)((uint32_t)stack_bottom + 4096);
|
uint32_t kstack_top = (uint32_t)kstack_bottom + PAGE_SIZE;
|
||||||
process->esp0 = (uint32_t)esp;
|
process->kstack_top = kstack_top;
|
||||||
|
|
||||||
|
uint32_t* esp = (uint32_t*)kstack_top;
|
||||||
if (user) {
|
if (user) {
|
||||||
*(--esp) = 0x23; // User Data Segment (SS) with RPL 3 (0x20 | 3)
|
*(--esp) = 0x23; // User Data Segment (SS) with RPL 3 (0x20 | 3)
|
||||||
*(--esp) = 0xBFFFF000; // User Stack Pointer (ESP) - location mapped in user space
|
*(--esp) = u_esp; // User Stack Pointer (ESP) - location mapped in user space
|
||||||
*(--esp) = 0x0202; // EFLAGS (Interrupts enabled)
|
*(--esp) = 0x0202; // EFLAGS (Interrupts enabled)
|
||||||
*(--esp) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3)
|
*(--esp) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3)
|
||||||
*(--esp) = entry_point; // EIP
|
*(--esp) = entry_point; // EIP
|
||||||
|
*(--esp) = 0x23;
|
||||||
} else {
|
} else {
|
||||||
// IRET values for Ring 0
|
// IRET values for Ring 0
|
||||||
*(--esp) = 0x0202; // EFLAGS
|
*(--esp) = 0x0202; // EFLAGS
|
||||||
*(--esp) = 0x08; // Kernel Code Segment (CS)
|
*(--esp) = 0x08; // Kernel Code Segment (CS)
|
||||||
*(--esp) = entry_point; // EIP
|
*(--esp) = entry_point; // EIP
|
||||||
|
*(--esp) = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(--esp) = 0; // EAX
|
*(--esp) = 0; // EAX
|
||||||
@@ -144,7 +154,9 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user) {
|
|||||||
*(--esp) = 0; // EDI
|
*(--esp) = 0; // EDI
|
||||||
|
|
||||||
process->esp = (uint32_t)esp;
|
process->esp = (uint32_t)esp;
|
||||||
total_processes++;
|
if (!reuse) {
|
||||||
|
total_processes++;
|
||||||
|
}
|
||||||
unlock_scheduler();
|
unlock_scheduler();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
void init_scheduler();
|
void init_scheduler();
|
||||||
|
|
||||||
int create_task(uint32_t entry_point, uint32_t cr3, int user);
|
int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp);
|
||||||
process_t* current_task();
|
process_t* current_task();
|
||||||
|
|
||||||
void sleep(uint32_t ms);
|
void sleep(uint32_t ms);
|
||||||
|
|||||||
@@ -4,33 +4,33 @@
|
|||||||
syscall_handler:
|
syscall_handler:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
push $0
|
pushfl
|
||||||
push $0x80
|
pushl %cs
|
||||||
|
|
||||||
pusha
|
movl 8(%esp), %eax
|
||||||
|
pushl %eax
|
||||||
|
movl 4(%esp), %ebx # Get CS
|
||||||
|
movl %ebx, 8(%esp) # Move CS over Old EIP
|
||||||
|
movl 0(%esp), %ebx # Get Return EIP
|
||||||
|
movl %ebx, 4(%esp) # Move Return EIP over CS
|
||||||
|
addl $4, %esp # Adjust stack pointer
|
||||||
|
|
||||||
push %ds
|
movw %ds, %ax
|
||||||
push %es
|
pushl %eax
|
||||||
push %fs
|
|
||||||
push %gs
|
|
||||||
|
|
||||||
mov $0x10, %ax
|
pushal
|
||||||
mov %ax, %ds
|
|
||||||
mov %ax, %es
|
|
||||||
mov %ax, %fs
|
|
||||||
mov %ax, %gs
|
|
||||||
|
|
||||||
push %esp
|
pushl %esp
|
||||||
call syscall
|
call switch_context
|
||||||
add $4, %esp
|
movl %eax, %esp
|
||||||
|
|
||||||
mov 28(%esp), %eax
|
popal
|
||||||
|
|
||||||
pop %gs
|
popl %eax
|
||||||
pop %fs
|
movw %ax, %ds
|
||||||
pop %es
|
movw %ax, %es
|
||||||
pop %ds
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
popa
|
sti
|
||||||
add $8, %esp
|
|
||||||
iret
|
iret
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <drivers/vga/vga.h>
|
#include <drivers/vga/vga.h>
|
||||||
|
|
||||||
|
#include <lib/print.h>
|
||||||
|
|
||||||
typedef struct registers {
|
typedef struct registers {
|
||||||
uint32_t gs, fs, es, ds; // Pushed manually
|
uint32_t gs, fs, es, ds; // Pushed manually
|
||||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
|
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
|
||||||
@@ -16,7 +18,7 @@ typedef struct registers {
|
|||||||
|
|
||||||
|
|
||||||
static int32_t sys_exit(int status) {
|
static int32_t sys_exit(int status) {
|
||||||
exit();
|
asm volatile("hlt");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
.global _start
|
.global _start
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
_start:
|
_start:
|
||||||
xor ebp, ebp
|
xor %ebp, %ebp
|
||||||
push ebp
|
push %ebp
|
||||||
mov ebp, esp
|
mov %esp, %ebp
|
||||||
|
|
||||||
mov eax, [esp + 4]
|
mov (%esp), %eax
|
||||||
lea ebx, [esp + 8]
|
lea 4(%esp), %ebx
|
||||||
lea ecx, [esp + 12]
|
lea 8(%esp, %eax, 4), %ecx
|
||||||
|
|
||||||
push ecx
|
push %ecx
|
||||||
push ebx
|
push %ebx
|
||||||
push eax
|
push %eax
|
||||||
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
push eax
|
push %eax
|
||||||
call exit
|
call exit
|
||||||
|
1: jmp 1b
|
||||||
1: hlt
|
|
||||||
jmp 1b
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
# 0 "crt0.S"
|
|
||||||
# 0 "<built-in>"
|
|
||||||
# 0 "<command-line>"
|
|
||||||
# 1 "crt0.S"
|
|
||||||
.global _start
|
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
.section .text
|
|
||||||
_start:
|
|
||||||
xor ebp, ebp
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
mov eax, [esp + 4]
|
|
||||||
lea ebx, [esp + 8]
|
|
||||||
lea ecx, [esp + 12]
|
|
||||||
|
|
||||||
push ecx
|
|
||||||
push ebx
|
|
||||||
push eax
|
|
||||||
|
|
||||||
call main
|
|
||||||
|
|
||||||
push eax
|
|
||||||
call exit
|
|
||||||
|
|
||||||
1: hlt
|
|
||||||
jmp 1b
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
printf("Hello, World from RockOS!\n");
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("RockOS booting...\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,8 @@ TARGET = origin.elf
|
|||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
crt0.o: crt0.s
|
crt0.o: crt0.S
|
||||||
$(CC) $(CFLAGS) -c crt0.s -o crt0.o
|
$(CC) $(CFLAGS) -c crt0.S -o crt0.o
|
||||||
|
|
||||||
main.o: main.c
|
main.o: main.c
|
||||||
$(CC) $(CFLAGS) -c main.c -o main.o
|
$(CC) $(CFLAGS) -c main.c -o main.o
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef int _PDCLIB_fd_t;
|
typedef int _PDCLIB_fd_t;
|
||||||
|
|
||||||
@@ -14,13 +15,8 @@ static inline int32_t inline_syscall(uint32_t num, uint32_t arg1, uint32_t arg2,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
inline_syscall(1, (uint32_t)status, 0, 0);
|
|
||||||
while(1) { asm volatile("hlt"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void _PDCLIB_exit(int status) {
|
void _PDCLIB_exit(int status) {
|
||||||
_exit(status);
|
inline_syscall(1, (uint32_t)status, 0, 0);;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _PDCLIB_read(_PDCLIB_fd_t fd, void *buf, size_t count) {
|
int _PDCLIB_read(_PDCLIB_fd_t fd, void *buf, size_t count) {
|
||||||
@@ -112,3 +108,7 @@ void * sbrk(intptr_t increment) {
|
|||||||
|
|
||||||
return (void *)-1;
|
return (void *)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exit(int status) {
|
||||||
|
_PDCLIB_exit(status);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user