diff --git a/Makefile b/Makefile index 9c577e0..b87473f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include Makefile.common -all: k.iso +all: bin k.iso k.iso: install ./tools/create_iso.sh @@ -9,8 +9,16 @@ install: mkdir -p $(GRUBDIR) $(MAKE) -C $(SOURCEDIR) $@ +bin: + $(MAKE) -C $(LIB) + gcc -c test.c -Ilibk -Llibk -lk -m32 + ld -m elf_i386 -Ttext=0x6000000 --entry=main test.o -L./libk/ -lk + objcopy --input binary --output elf32-i386 --binary-architecture i386 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA a.out myfile.o + cp myfile.o $(SOURCEDIR)/myfile.o + clean: $(MAKE) -C $(SOURCEDIR) $@ + $(MAKE) -C $(LIB) $@ $(RM) kernel.iso $(RM) -r iso diff --git a/Makefile.common b/Makefile.common index 095aa11..92ed0b0 100644 --- a/Makefile.common +++ b/Makefile.common @@ -4,3 +4,4 @@ ASFLAGS = -m32 GRUBDIR = iso SOURCEDIR = src TARGET = kernel +LIB=libk diff --git a/libk/Makefile b/libk/Makefile new file mode 100644 index 0000000..15e0207 --- /dev/null +++ b/libk/Makefile @@ -0,0 +1,20 @@ +include ../Makefile.common + + +OBJS = \ + syscall.o \ + +DEPS = $(OBJS:.o=.d) + +CPPFLAGS += -MMD -Iinclude +CFLAGS += $(K_EXTRA_CFLAGS) -g -nostdlib +LDFLAGS += -Wl,-Tkernel.lds +LDLIBS = + +all: $(TARGET) + ar -rcs $(LIB).a *.o + +$(TARGET): $(OBJS) + +clean: + $(RM) $(OBJS) $(DEPS) $(TARGET) $(LIB).a \ No newline at end of file diff --git a/libk/syscall.c b/libk/syscall.c new file mode 100644 index 0000000..aca3fae --- /dev/null +++ b/libk/syscall.c @@ -0,0 +1,27 @@ +#include "syscall.h" + +int __syscall(int num, void *a0, void *a1, void *a2, void *a3, void *a4) +{ + int ret; + asm volatile(" \n \ + mov %1, %%eax; \n \ + mov %2, %%ebx; \n \ + mov %3, %%ecx; \n \ + mov %4, %%edx; \n \ + mov %5, %%edi; \n \ + mov %6, %%esi; \n \ + int $48; \n \ + mov %%eax, %0" : "=m" (ret), + "+m" (num), + "+m" (a0), + "+m" (a1), + "+m" (a2), + "+m" (a3), + "+m" (a4)); + return ret; +} + +int write(int fd, char *buf, int count) +{ + return __syscall(1, (void *) fd, (void *) buf, (void *) count, (void *) 0, (void *) 0); +} diff --git a/libk/syscall.h b/libk/syscall.h new file mode 100644 index 0000000..8c0bafc --- /dev/null +++ b/libk/syscall.h @@ -0,0 +1,7 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +int __syscall(int num, void *a0, void *a1, void *a2, void *a3, void *a4); +int write(int fd, char *buf, int count); + +#endif /* !SYSCALL_H */ \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index 9d4f0d3..b4062eb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,6 +14,8 @@ OBJS = \ userland.o \ launch_process.o \ paging.o \ + elf.o \ + myfile.o \ DEPS = $(OBJS:.o=.d) diff --git a/src/elf.c b/src/elf.c new file mode 100644 index 0000000..ff050fe --- /dev/null +++ b/src/elf.c @@ -0,0 +1,41 @@ +#include "elf.h" + +#include +#include "serial.h" +#include "debug.h" +#include "paging.h" + +int load_elf(char *elf_data_start, int uid) +{ + DEBUG_INFO("LOAD ELF: ", elf_data_start); + + struct elf_header *elf_header = (struct elf_header *) elf_data_start; + + DEBUG_INFO("ELF ENTRY POINT: %d", elf_header->entry_point); + DEBUG_INFO("PROGRAM HEADER ENTRY POINT: %d", elf_header->program_header_table_offset); + DEBUG_INFO("NUMBER PROGRAM HEADER ENTRY: %d", elf_header->number_of_program_header_table_entries); + + for (int i = 0; i < elf_header->number_of_program_header_table_entries; i++) + { + struct elf_header_table *elf_header_table = (struct elf_header_table *) (elf_data_start + elf_header->program_header_table_offset + sizeof(struct elf_header_table) * i); + u32 segment_type = elf_header_table->segment_type; + + DEBUG_INFO("ELF type : %d", segment_type == LOAD); + if (segment_type == LOAD && elf_header_table->p_vaddr >= 0x6000000) + { + for (u32 mem = (elf_header_table->p_vaddr >> 12); mem < ((elf_header_table->p_vaddr + elf_header_table->p_filesz) >> 12) + 1; mem += 1) + { + DEBUG_INFO("ELF ALLOCATE %d: ", mem << 12); + allocate_new_page(uid, mem << 12); + } + + memcpy(elf_header_table->p_vaddr, elf_data_start + elf_header_table->p_offset, elf_header_table->p_filesz); + + if (elf_header_table->p_filesz < elf_header_table->p_memsz) + { + for (int i = elf_header_table->p_filesz; i < elf_header_table->p_memsz; i++) + elf_header_table->p_vaddr[elf_data_start + elf_header_table->p_offset + i] = 0; + } + } + } +} diff --git a/src/elf.h b/src/elf.h new file mode 100644 index 0000000..680a912 --- /dev/null +++ b/src/elf.h @@ -0,0 +1,51 @@ +#ifndef ELF_H +#define ELF_H + +#include + +struct elf_header +{ + u32 magic_number; + u8 bus_size; + u8 endianess; + u8 elf_header_version; + u8 os_abi; + u32 unused[2]; + u16 type; + u16 isa; + u32 elf_version; + u32 entry_point; + u32 program_header_table_offset; + u32 section_header_table_offset; + u32 flags; + u16 header_size; + u16 program_header_table_entry_size; + u16 number_of_program_header_table_entries; + u16 size_of_program_header_table_entries; + u16 number_of_section_header_table_entries; + u16 index_section_header_table_with_section_names; +} __attribute__((packed)); + +struct elf_header_table +{ + u32 segment_type; + u32 p_offset; + u32 p_vaddr; + u32 undefined; + u32 p_filesz; + u32 p_memsz; + u32 flags; + u32 alignment; +} __attribute__((packed)); + +enum elf_segment_type { + NULL = 0, + LOAD = 1, + DYNAMIC = 2, + INTERP = 3, + NOTE = 4 +}; + +int load_elf(char *elf_data_start, int uid); + +#endif ELF_H diff --git a/src/gdt.c b/src/gdt.c index aa54e17..3864ce7 100644 --- a/src/gdt.c +++ b/src/gdt.c @@ -14,7 +14,9 @@ void *memcpy(void *dest, const void *src, size_t n) char *d = dest; for (size_t i = 0; i < n; i++) + { *d++ = *s++; + } return dest; } @@ -69,8 +71,6 @@ void init_gdt(void) kgdtr.limit = sizeof(gdt) - 1; kgdtr.base = (u32) gdt; - memcpy((char*) 0x30000, &userland, 1000); - gdt[0] = init_descriptor((struct segment_desc_param) { .Limit_1 = 0, .Base = 0, .Type = 0, .S = 0, .DPL = 0, .P = 0, .Limit_2 = 0, .AVL = 0, .L = 0, .D_B = 0, .G = 0 }); diff --git a/src/idt.c b/src/idt.c index 9bac021..6d57aa3 100644 --- a/src/idt.c +++ b/src/idt.c @@ -67,6 +67,9 @@ void init_idt(void) .Type = 0x06, .D = 1, .DPL = 0, .P = 1 }); } + idt[14] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_page_fault, .SegSelect = 0x08, + .Type = 0x06, .D = 1, .DPL = 0, .P = 1 }); + idt[32] = init_gate((struct interrupt_gate_param) { .Offset = (u32) _asm_irq_0, .SegSelect = 0x08, .Type = 0x06, .D = 1, .DPL = 0, .P = 1 }); diff --git a/src/int.S b/src/int.S index dfb5c46..ef6f802 100644 --- a/src/int.S +++ b/src/int.S @@ -1,5 +1,5 @@ -.extern isr_default_int, isr_clock_int, isr_kbd_int, syscall_handler -.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler +.extern isr_default_int, isr_clock_int, isr_kbd_int, syscall_handler, isr_page_fault +.global _asm_default_int, _asm_irq_0, _asm_irq_1, _asm_sycall_handler, _asm_page_fault _asm_default_int: pushal @@ -19,6 +19,24 @@ _asm_default_int: popal iret +_asm_page_fault: + pushal + push %ds + push %es + push %fs + push %gs + push %ebx + mov $0x10,%bx + mov %bx,%ds + pop %ebx + call isr_page_fault + pop %gs + pop %fs + pop %es + pop %ds + popal + iret + _asm_irq_0: pushal push %ds @@ -64,16 +82,24 @@ _asm_sycall_handler: push %ds push %es push %fs - push %gs + push %gs push %ebx mov $0x10,%bx mov %bx,%ds pop %ebx + push %esi + push %edi + push %edx + push %ecx push %ebx push %eax call syscall_handler pop %ebx pop %ebx + pop %ecx + pop %edx + pop %edi + pop %esi pop %gs pop %fs pop %es diff --git a/src/int.h b/src/int.h index cc85126..2805ade 100644 --- a/src/int.h +++ b/src/int.h @@ -2,6 +2,7 @@ #define INT_H void _asm_default_int(void); +void _asm_page_fault(void); void _asm_irq_0(void); void _asm_irq_1(void); int _asm_sycall_handler(int eax, int ebx); diff --git a/src/isr.c b/src/isr.c index 5740a90..e3ea96c 100644 --- a/src/isr.c +++ b/src/isr.c @@ -7,7 +7,12 @@ void isr_default_int(void) { - DEBUG_INFO("An INT has been raised, entering default interrupt handler."); + // DEBUG_INFO("An INT has been raised, entering default interrupt handler."); +} + +void isr_page_fault(void) +{ + DEBUG_INFO("A page fault exception occured"); } void isr_clock_int(void) @@ -23,16 +28,17 @@ void isr_kbd_int(void) DEBUG_INFO("Keyboard input: %d", x); } -void syscall_handler(int eax, int ebx) +int syscall_handler(int eax, void *ebx, void *ecx, void *edx, void *edi, void *esi) { - DEBUG_INFO("Syscall %d has been called from the userland with parameter %d", eax, ebx); + DEBUG_INFO("Syscall %d has been called from the userland with parameters: %d, %d, %d, %d, %d", eax, ebx, ecx, edx, edi, esi); switch (eax) { case 1: - char t = *((char *) ebx); - DEBUG_INFO("Syscall write : %d", (int) t); - return write(1, (u32) ebx); + int fd = (int) ebx; + char *buf = (char *) ecx; + int size = (int) edx; + return write(fd, buf, size); break; case 2: DEBUG_INFO("Syscall keyboard"); diff --git a/src/kernel.c b/src/kernel.c index 9460275..e31e104 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -7,12 +7,23 @@ #include "debug.h" #include "tss.h" #include "launch_process.h" +#include "elf.h" +#include "userland.h" + +extern char _binary_a_out_start[]; +extern char _binary_a_out_end[]; +extern char _binary_a_out_size[]; void main(void) { - DEBUG_INFO("Entering Main Function"); + DEBUG_INFO("Entering Main Function"); - launch_process(0x28, 0x30000, 0x20, 0x18, 0x20); + char *data_start = &_binary_a_out_start; + char *data_end = _binary_a_out_end; + size_t data_size = (size_t)_binary_a_out_size; + + create_process(0, data_start); + switch_to_process(0); for (;;) { @@ -23,7 +34,6 @@ void main(void) void kernel_main(void) { - init_serial(); DEBUG_INFO("Starting kernel"); @@ -31,7 +41,7 @@ void kernel_main(void) init_gdt(); init_idt(); pic_init(); - make_page(); + create_kernel_page(); asm volatile ("sti"); main(); diff --git a/src/kernel.lds b/src/kernel.lds index 2bb7afc..49f1a4a 100644 --- a/src/kernel.lds +++ b/src/kernel.lds @@ -3,21 +3,20 @@ OUTPUT_FORMAT("elf32-i386") SECTIONS { - .text : ALIGN(CONSTANT(MAXPAGESIZE)) { - _TEXT_START_ = .; - *(.multiboot) *(.text) - _TEXT_END_ = .; - } + .text : ALIGN(CONSTANT(MAXPAGESIZE)) { + _TEXT_START_ = .; + *(.multiboot) *(.text) + _TEXT_END_ = .; + } - .data : ALIGN(CONSTANT(MAXPAGESIZE)) { - _DATA_START_ = .; - *(.data) - _DATA_END_ = .; - } + .data : ALIGN(CONSTANT(MAXPAGESIZE)) { + _DATA_START_ = .; + *(.data) + } - .bss : ALIGN(CONSTANT(MAXPAGESIZE)) { - _BSS_START_ = .; - *(.bss) - _BSS_END_ = .; - } + .bss : ALIGN(CONSTANT(MAXPAGESIZE)) { + _BSS_START_ = .; + *(.bss) + _BSS_END_ = .; + } } diff --git a/src/launch_process.c b/src/launch_process.c index 7986305..18ca823 100644 --- a/src/launch_process.c +++ b/src/launch_process.c @@ -3,7 +3,7 @@ #include "tss.h" #include "debug.h" -void launch_process(int tss, int memory_start, int userland_stack, int userland_code, int userland_data) +void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data) { // Setting DPL and GDT bits userland_stack += 3; @@ -13,29 +13,22 @@ void launch_process(int tss, int memory_start, int userland_stack, int userland_ DEBUG_INFO("LAUCHING USER LAND PROCESS"); asm volatile (" \n \ - movw %0, %%ax \n \ + mov %0, %%ax \n \ ltr %%ax \n \ movw %%ss, %1 \n \ movl %%esp, %2 \n \ - cli \n \ - push %3 \n \ - push %4 \n \ - pushfl \n \ - popl %%eax \n \ - orl $0x200, %%eax \n \ - and $0xffffbfff, %%eax \n \ - push %%eax \n \ - push %5 \n \ - push $0x30000 \n \ - movl $0x20000, %6 \n \ - movw %7, %%ax \n \ + movw $0x23, %%ax \n \ movw %%ax, %%ds \n \ - iret" : "=m" (tss), + movw %%ax, %%es \n \ + movw %%ax, %%fs \n \ + movw %%ax, %%gs \n \ + mov %%esp, %%eax \n \ + push $0x23 \n \ + push $0x7FFFEFFF \n \ + pushfl \n \ + push $0x1B \n \ + push $0x6000000 \n \ + iret" : "+r" (tss), "=m" (user_land_tss.ss0), - "=m" (user_land_tss.esp0), - "=m" (userland_stack), - "=m" (memory_start), - "=m" (userland_code), - "=m" (user_land_tss.esp0), - "=m" (userland_data)); + "=m" (user_land_tss.esp0)); } diff --git a/src/launch_process.h b/src/launch_process.h index 5951834..7074392 100644 --- a/src/launch_process.h +++ b/src/launch_process.h @@ -1,6 +1,8 @@ #ifndef LAUNCH_PROCESS_H #define LAUNCH_PROCESS_H -void launch_process(int tss, int memory_start, int userland_stack, int userland_code, int userland_data); +#include + +void launch_process(u16 tss, int memory_start, int userland_stack, int userland_code, u16 userland_data); #endif /* !LAUNCH_PROCESS_H */ \ No newline at end of file diff --git a/src/paging.c b/src/paging.c index 0a4118e..f302fb2 100644 --- a/src/paging.c +++ b/src/paging.c @@ -2,9 +2,43 @@ #include "debug.h" #include "serial.h" +#include "userland.h" -struct page_directory_entry *page_dir = 0x2000; //__attribute__((aligned(4096))); -struct page_table_entry *page_table = 0x3000; //__attribute__((aligned(4096))); +struct page_directory_entry *page_dir; // = 0x3000000; //__attribute__((aligned(4096))); +struct page_table_entry *page_table; // = 0x3010000; //__attribute__((aligned(4096))); +u8 page_avl[131072] = {0}; +int page_avl_index = (USERLAND_BASE_ADDRESS >> 12) / 8; +int userland_page_dir_index = 0; + +#define KERNEL_PAGE_DIR 0x3000000 +#define KERNEL_PAGE_TABLE 0x3010000 +#define NB_KERNEL_PAGE_DIR 20 + +int find_page_avl(void) +{ + for (int i = page_avl_index; i < 131071; i++) { + for (int j = 0; j < 8; j++) { + if ((page_avl[i] & (1 << j)) == 0) { + page_avl_index = i; + return (i * 8 + j) << 12; + } + } + } + + // TODO : Add memory deallocation policies + return -1; +} + +void set_page(int address) +{ + page_avl[(address >> 12) / 8] |= (1 << ((address >> 12) % 8)); +} + +void clear_page(int address) +{ + page_avl[(address >> 12) / 8] |= (1 << ((address >> 12) % 8)); + page_avl[(address >> 12) / 8] ^= (1 << ((address >> 12) % 8)); +} struct page_directory_param { u8 P; @@ -73,21 +107,27 @@ struct page_table_entry create_page_table_entry(struct page_table_param param) return page_table; } -int make_page(void) +int create_kernel_page(void) { - for (int i = 0; i < 1024; i++) + page_dir = (struct page_directory_entry *) KERNEL_PAGE_DIR; + page_table = (struct page_table_entry *) KERNEL_PAGE_TABLE; + + for (int i = 0; i < NB_KERNEL_PAGE_DIR; i++) { - page_table[i] = create_page_table_entry((struct page_table_param) { - .P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0, - .A = 0, .D = 0, .PAT = 0, .G = 0, - .address = 1 * i}); + for (int j = 0; j < 1024; j++) + { + page_table[i * 1024 + j] = create_page_table_entry((struct page_table_param) { + .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, + .A = 0, .D = 0, .PAT = 0, .G = 0, + .address = j + i * 1024}); + } + DEBUG_INFO("PAGE_TABLE %d", &page_table[i * 1024]); + page_dir[i] = create_page_directory_entry((struct page_directory_param) { + .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, + .A = 0, .PS = 0, .address = &page_table[i * 1024]}); } - page_dir[0] = create_page_directory_entry((struct page_directory_param) { - .P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0, - .A = 0, .PS = 0, .address = page_table}); - - for (int i = 1; i < 1024; i++) + for (int i = NB_KERNEL_PAGE_DIR; i < 1024; i++) { page_dir[i] = create_page_directory_entry((struct page_directory_param) { .P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0, @@ -132,6 +172,7 @@ int make_page(void) DEBUG_INFO("address of Page Directory Array: %d", page_dir); DEBUG_INFO("address of the first Page Table array: %d", page_table); + // load page directory and enable paging (cr0 bit 31) asm volatile (" \ mov %0, %%eax \n \ mov %%eax, %%cr3 \n \ @@ -141,3 +182,72 @@ int make_page(void) return 0; } + +int create_new_userland_page(int uid) +{ + struct page_directory_entry *userland_page_dir = userland_data->userland_data[uid].page_directories; + struct page_table_entry *kernel_page_table = (struct page_table_entry *) KERNEL_PAGE_TABLE; + + for (int i = 0; i < NB_KERNEL_PAGE_DIR; i++) + { + DEBUG_INFO("PAGE_TABLE %d", &kernel_page_table[i * 1024]); + userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) { + .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, + .A = 0, .PS = 0, .address = &kernel_page_table[i * 1024]}); + } + + for (int i = 0; i < 1024; i++) + { + int avl_address = find_page_avl(); + set_page(avl_address); + userland_data->userland_data[uid].page_table[i] = create_page_table_entry((struct page_table_param) { + .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, + .A = 0, .D = 0, .PAT = 0, .G = 0, + .address = (avl_address >> 12)}); + } + + userland_page_dir[NB_KERNEL_PAGE_DIR] = create_page_directory_entry((struct page_directory_param) { + .P = 1, .R_W = 1, .U = 0, .PWT = 0, .PCD = 0, + .A = 0, .PS = 0, .address = userland_data->userland_data[uid].page_table}); + + for (int i = NB_KERNEL_PAGE_DIR + 1; i < 1024; i++) + { + userland_page_dir[i] = create_page_directory_entry((struct page_directory_param) { + .P = 0, .R_W = 0, .U = 0, .PWT = 0, .PCD = 0, + .A = 0, .PS = 0, .address = 0}); + } +} + +int allocate_new_page(int uid, int address) +{ + struct page_directory_entry *userland_page_dir = userland_data->userland_data[uid].page_directories; + + int dir_address = address >> 22; + int table_address = (address >> 12) ^ ((address >> 22) << 10); + + DEBUG_INFO("dir_address %d", dir_address); + DEBUG_INFO("table_address %d", table_address); + + // CPU does't use page table when decoding page table, so it need the physical address + int new_page_table_real = (int) userland_data->userland_data[uid].page_table[dir_address].address; + DEBUG_INFO("PAGE TABLE REAL ADDRESS %d", new_page_table_real << 12); + struct page_table_entry *new_page_table = USERLAND_BASE_ADDRESS + dir_address * 1024 * 4 + table_address * 4; + + if (userland_page_dir[dir_address].address != 0 && new_page_table->address != 0) + clear_page(new_page_table->address); + + if (userland_page_dir[dir_address].address == 0) + { + DEBUG_INFO("NEW DIR ENTRY"); + userland_page_dir[dir_address] = create_page_directory_entry((struct page_directory_param) { + .P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0, + .A = 0, .PS = 0, .address = new_page_table_real << 12}); + } + + int avl_address = find_page_avl(); + set_page(avl_address); + *new_page_table = create_page_table_entry((struct page_table_param) { + .P = 1, .R_W = 1, .U = 1, .PWT = 0, .PCD = 0, + .A = 0, .D = 0, .PAT = 0, .G = 0, + .address = (avl_address >> 12)}); +} diff --git a/src/paging.h b/src/paging.h index f5ca0db..ebb0857 100644 --- a/src/paging.h +++ b/src/paging.h @@ -16,7 +16,8 @@ struct page_table_entry { u32 address : 20; } __attribute__((packed)); -int make_page(void); +int create_kernel_page(void); +int allocate_new_page(int uid, int address); // extern struct page_directory_entry page_dir[1024]; // extern struct page_table_entry page_table[1024]; diff --git a/src/serial.c b/src/serial.c index ba59ba2..143a771 100644 --- a/src/serial.c +++ b/src/serial.c @@ -24,6 +24,14 @@ int init_serial() int write_serial_nb(int nb, int ln) { + if (nb < 0) + { + while ((inb(PORT + 5) & 0x20) == 0); + outb(PORT, '-'); + write_serial_nb(-nb, ln); + return 0; + } + if (nb < 10) { while ((inb(PORT + 5) & 0x20) == 0); diff --git a/src/syscall.c b/src/syscall.c index 670f283..78f1150 100644 --- a/src/syscall.c +++ b/src/syscall.c @@ -6,9 +6,9 @@ * Syscall handler for write, currently only serial write is supported. * Use the fd 1, to make a serial write. */ -int write(int fd, void *buf) +int write(int fd, void *buf, int size) { - if (fd != 1) + if (fd != 1 || size < 0) return -1; if (write_serial(buf)) diff --git a/src/syscall.h b/src/syscall.h index 36c9358..d69a768 100644 --- a/src/syscall.h +++ b/src/syscall.h @@ -1,7 +1,7 @@ #ifndef SYSCALL_H #define SYSCALL_H -int write(int fd, void *buf); +int write(int fd, void *buf, int size); int keyboard(void); #endif /* !SYSCALL_H */ \ No newline at end of file diff --git a/src/userland.c b/src/userland.c index 51821fb..e154f90 100644 --- a/src/userland.c +++ b/src/userland.c @@ -1,26 +1,45 @@ #include "userland.h" -void userland(void) +#include "debug.h" +#include "paging.h" +#include "launch_process.h" + +struct userlands_data *userland_data = 0x3020000; + +int create_process(int uid, char *data_start) { - int res = 0; - // asm ("mov $1, %0" : "=r" (res)); - // asm volatile ("movl $2, %eax; int $0x30"); - // asm("movl %%eax,%0" : "=r"(res)); - // asm volatile ("int $0x30"); - char *str = (void *) 0x30100; - str[0] = 'H'; - str[1] = 'e'; - str[2] = 'l'; - str[3] = 'l'; - str[4] = 'o'; - str[5] = '\0'; - asm volatile ("mov $1, %%eax; movl $0x30100, %%ebx; int $0x30; movl %%eax, %1" : "=m" (str), "=r" (res)); - // asm volatile ("mov $1, %%eax; movl %0, %%ebx; int $0x30" : "=m" (str)); - // asm ("mov $1, %eax; int $0x30"); - // asm ("movl %0, %eax; int $0x30" : "=m" (res)); - // asm ("movl %eax, %eax; int $0x30"); - // asm ("movl $28, %eax; movl $5, %ebx; int $0x30"); - // asm ("movl $43, %eax; movl $7, %ebx; int $0x30"); - while (1); - return; /* never go there */ -} \ No newline at end of file + create_new_userland_page(uid); + + DEBUG_INFO("CREATE PROCESS"); + void *process_page_dir_adress = userland_data->userland_data[uid].page_directories; + + // load cr3 + asm volatile (" \ + mov %0, %%eax \n \ + mov %%eax, %%cr3" : "+r" (process_page_dir_adress)); + + // Allocate stack + allocate_new_page(uid, 0x7FFFF000); + allocate_new_page(uid, 0x7FFFE000); + allocate_new_page(uid, 0x7FFFD000); + + // TODO : create data seg by process + // load elf + load_elf(data_start, uid); + + return 0; +} + +int switch_to_process(int uid) +{ + DEBUG_INFO("SWITCHING TO PROCESS"); + void *process_page_dir_adress = userland_data->userland_data[uid].page_directories; + + // load cr3 + asm volatile (" \ + mov %0, %%eax \n \ + mov %%eax, %%cr3" : "+r" (process_page_dir_adress)); + + // TODO : once data by process has been implemented, load the right one + launch_process(0x28, 0x6000000, 0x20, 0x18, 0x20); +} diff --git a/src/userland.h b/src/userland.h index 86da88f..c89a721 100644 --- a/src/userland.h +++ b/src/userland.h @@ -1,6 +1,26 @@ #ifndef USERLAND_H #define USERLAND_H -void userland(void); +#include +#include "paging.h" + +#define USERLAND_BASE_ADDRESS 0x5000000 + +struct userland_data +{ + struct page_directory_entry page_directories[1024]; + struct page_table_entry page_table[1024]; +}; + + +struct userlands_data { + struct userland_data userland_data[128]; + u32 page_dir[4]; +}; + +extern struct userlands_data *userland_data; + +int create_process(int uid, char *data_start); +int switch_to_process(int uid); #endif /* !USERLAND_H */