more userlaand stuff
This commit is contained in:
12
kernel/idt.c
12
kernel/idt.c
@@ -4,6 +4,7 @@
|
||||
#define IDT_MAX_DESCRIPTORS 256
|
||||
|
||||
#define ATTR_KERN_32 0x8E // active(1), ring 0 (00), interrupt gate(0), 32 bit (1110)
|
||||
#define ATTR_USER_32 0xEE // active, ring 3, 32bit
|
||||
|
||||
#define SEGMENT_KERN 0x08
|
||||
|
||||
@@ -31,11 +32,11 @@ void* isr_stub_table[256] = {
|
||||
idt_entry idt[IDT_MAX_DESCRIPTORS];
|
||||
idt_ptr idtr;
|
||||
|
||||
void set_idtr(uint8_t vector, void* isr, uint8_t attributes) {
|
||||
void set_idtr(uint8_t vector, void* isr, uint16_t sel, uint8_t attributes) {
|
||||
idt_entry* desc = &idt[vector];
|
||||
|
||||
desc->isr_low = (uint32_t)isr & 0xFFFF;
|
||||
desc->kernel_cs = SEGMENT_KERN;
|
||||
desc->selector = SEGMENT_KERN;
|
||||
desc->reserved = 0;
|
||||
desc->attributes = attributes;
|
||||
desc->isr_high = ((uint32_t)isr >> 16) & 0xFFFF;
|
||||
@@ -47,11 +48,14 @@ void init_idt() {
|
||||
|
||||
for (int i = 0; i < IDT_MAX_DESCRIPTORS; i++) {
|
||||
if (isr_stub_table[i] != 0) {
|
||||
set_idtr(i, isr_stub_table[i], ATTR_KERN_32);
|
||||
set_idtr(i, isr_stub_table[i], SEGMENT_KERN, ATTR_KERN_32);
|
||||
} else {
|
||||
set_idtr(i, 0, 0);
|
||||
set_idtr(i, 0, SEGMENT_KERN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern void syscall_handler();
|
||||
set_idtr(0x80, syscall_handler, SEGMENT_KERN, ATTR_USER_32);
|
||||
|
||||
load_idt();
|
||||
}
|
||||
10
kernel/idt.h
10
kernel/idt.h
@@ -4,11 +4,11 @@
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct __attribute__((packed)){
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs; // The GDT segment selector the CPU will load into CS
|
||||
uint8_t reserved; // Set to 0
|
||||
uint8_t attributes;// Type and attributes flags
|
||||
uint16_t isr_high; // The higher 16 bits of the ISR's address
|
||||
uint16_t isr_low;
|
||||
uint16_t selector;
|
||||
uint8_t reserved;
|
||||
uint8_t attributes;
|
||||
uint16_t isr_high;
|
||||
} idt_entry;
|
||||
|
||||
typedef struct __attribute__((packed)){
|
||||
|
||||
@@ -88,7 +88,7 @@ void load_origin_program(multiboot_info* mbi) {
|
||||
kprintf("program loaded into memory @ [virt] 0x%x\n", elf->e_entry);
|
||||
|
||||
extern void liftoff(uint32_t entry, uint32_t stack_top);
|
||||
kprintf("launching origin process");
|
||||
kprintf("launching origin process\n");
|
||||
uint32_t stack_top = 0xBFFFF000 + 4095;
|
||||
liftoff(elf->e_entry, stack_top);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ static uint8_t memory_bitmap[BITMAP_SIZE];
|
||||
|
||||
static void mark_free(uint32_t addr) {
|
||||
uint32_t page_index = addr / PAGE_SIZE;
|
||||
uint32_t byte_index = page_index / 8;
|
||||
uint32_t byte_index = page_index / 8;
|
||||
uint32_t bit_index = page_index % 8;
|
||||
memory_bitmap[byte_index] &= ~(1 << bit_index);
|
||||
}
|
||||
|
||||
27
kernel/syscall.c
Normal file
27
kernel/syscall.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/print.h"
|
||||
|
||||
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 sys_vga_text_write(char* buf);
|
||||
|
||||
int32_t syscall(registers_t* regs) {
|
||||
switch(regs->eax) {
|
||||
case 1: {
|
||||
return sys_vga_text_write((char*)regs->ebx);
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t sys_vga_text_write(char* buf) {
|
||||
kprintf(buf);
|
||||
return 0;
|
||||
}
|
||||
36
kernel/syscall_stubs.S
Normal file
36
kernel/syscall_stubs.S
Normal file
@@ -0,0 +1,36 @@
|
||||
.code32
|
||||
.global syscall_handler
|
||||
.extern syscall
|
||||
syscall_handler:
|
||||
cli
|
||||
|
||||
push $0
|
||||
push $0x80
|
||||
|
||||
pusha
|
||||
|
||||
push %ds
|
||||
push %es
|
||||
push %fs
|
||||
push %gs
|
||||
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
|
||||
push %esp
|
||||
call syscall
|
||||
add $4, %esp
|
||||
|
||||
mov 28(%esp), %eax
|
||||
|
||||
pop %gs
|
||||
pop %fs
|
||||
pop %es
|
||||
pop %ds
|
||||
|
||||
popa
|
||||
add $8, %esp
|
||||
iret
|
||||
0
libc/arch/i686/crt0.S
Normal file
0
libc/arch/i686/crt0.S
Normal file
17
libc/include/rock.h
Normal file
17
libc/include/rock.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef LIBC_ROCK_H
|
||||
#define LIBC_ROCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline int32_t syscall(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) {
|
||||
int32_t ret;
|
||||
__asm__ __volatile__ (
|
||||
"int $0x80"
|
||||
: "=a" (ret)
|
||||
: "0" (num), "b" (arg1), "c" (arg2), "d" (arg3)
|
||||
: "memory"
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
11
libc/include/string.h
Normal file
11
libc/include/string.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef LIBC_STRING_H
|
||||
#define LIBC_STRING_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void* memcpy(void* dst, const void* src, size_t n);
|
||||
void* memset(void* dst, int c, size_t n);
|
||||
void* memmove(void* dst, const void* src, size_t n);
|
||||
int memcmp(const void* s1, const void* s2, size_t n);
|
||||
|
||||
#endif
|
||||
0
libc/makefile
Normal file
0
libc/makefile
Normal file
@@ -1,8 +1,16 @@
|
||||
.code32
|
||||
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
mov $1, %eax
|
||||
add $1, %eax
|
||||
mov $(message), %ebx
|
||||
mov $0, %ecx
|
||||
mov $0, %edx
|
||||
int $0x80
|
||||
loop:
|
||||
jmp loop
|
||||
jmp loop
|
||||
|
||||
.section .data
|
||||
message:
|
||||
.asciz "Hello, Userland!\n";
|
||||
Reference in New Issue
Block a user