From 62837e9c44e4b6aca2e68a7983b18567cb3e0776 Mon Sep 17 00:00:00 2001 From: "brice.boisson" Date: Mon, 25 Sep 2023 11:38:14 +0900 Subject: [PATCH] Add: launch elf process in paging --- src/elf.c | 12 +++++++-- src/elf.h | 2 +- src/gdt.c | 2 ++ src/isr.c | 2 +- src/kernel.c | 40 ++------------------------- src/launch_process.c | 35 ++++++++++-------------- src/launch_process.h | 4 ++- src/myfile.o | Bin 13840 -> 13840 bytes src/paging.c | 58 +++++++-------------------------------- src/userland.c | 63 ++++++++++++++++++++++++++----------------- src/userland.h | 3 ++- 11 files changed, 83 insertions(+), 138 deletions(-) diff --git a/src/elf.c b/src/elf.c index ec342d9..ff050fe 100644 --- a/src/elf.c +++ b/src/elf.c @@ -3,8 +3,9 @@ #include #include "serial.h" #include "debug.h" +#include "paging.h" -int load_elf(char *elf_data_start) +int load_elf(char *elf_data_start, int uid) { DEBUG_INFO("LOAD ELF: ", elf_data_start); @@ -19,8 +20,15 @@ int load_elf(char *elf_data_start) 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; - if (segment_type == LOAD && elf_header_table->p_vaddr < 0x100000) + 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) diff --git a/src/elf.h b/src/elf.h index 7d05f5b..680a912 100644 --- a/src/elf.h +++ b/src/elf.h @@ -46,6 +46,6 @@ enum elf_segment_type { NOTE = 4 }; -int load_elf(char *elf_data_start); +int load_elf(char *elf_data_start, int uid); #endif ELF_H diff --git a/src/gdt.c b/src/gdt.c index 1a72ff3..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; } diff --git a/src/isr.c b/src/isr.c index 3c14e8f..213950d 100644 --- a/src/isr.c +++ b/src/isr.c @@ -7,7 +7,7 @@ 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) diff --git a/src/kernel.c b/src/kernel.c index 139551c..e31e104 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -22,44 +22,8 @@ void main(void) char *data_end = _binary_a_out_end; size_t data_size = (size_t)_binary_a_out_size; - - create_new_userland_page(0); - - DEBUG_INFO("PAGE DIR: %d", userland_data->userland_data[0].page_directories); - struct page_table_entry *ttt = userland_data->userland_data[0].page_directories[20].address << 12; - DEBUG_INFO("PAGE DIR: %d", ttt->address); - - asm volatile (" \ - mov $0x3020000, %eax \n \ - mov %eax, %cr3"); - - // DEBUG_INFO("BIN %b", 0x13000000); - allocate_new_page(0, 0x32400000); - - // asm volatile (" \ - // xor $0x80000000, %eax \n \ - // mov %eax, %cr0"); - - // u32 *data2 = 50466816; - // DEBUG_INFO("BIN %b", *data2); - - // u32 *data = 83886080; - // DEBUG_INFO("BIN %b", *data); - - // struct page_directory_entry *var = 0x3020000; - // DEBUG_INFO("address %d", var[76].address); - - // u32 *var = 0x13000000; - u32 *var = 0x32403400; - *var = 10; - DEBUG_INFO("%d", *var); - // asm volatile (" \ - // mov %0, %%eax \n \ - // mov %%eax, %%cr3" : "=m" (userland_data->userland_data[0].page_directories)); - - // load_elf(data_start); - - // launch_process(0x28, 0x30000, 0x20, 0x18, 0x20); + create_process(0, data_start); + switch_to_process(0); for (;;) { diff --git a/src/launch_process.c b/src/launch_process.c index 7986305..2735335 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 $0x7FFFFFFF \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/myfile.o b/src/myfile.o index 644e412cf7a8aea7ff647625195124830e208224..7cab4588283ec1115d243bfe938b4b0d0bde422a 100644 GIT binary patch delta 301 zcmbP`Ga+Y!9}@%H!~mtV|Evrj{ZoWfv_x)0AW@jhRZ8} z*=#^Qn+K2y!pQo+=rb??F&hX^yfKRn!rENHSY=Spz-9nc%?L3M$btYChL8WbfJ~4M zkO(8tJOv;v32_C35EB!F8IW&a0Ff5}>URS2fq)IDhCzsdiNPI6Bg^}t@fk`|i%T{a n8nH660}TOsRd(`4L*dC2jQM~8GI@cq8i+aprZ#^tR$u}E+ms}J delta 301 zcmbP`Ga+Y!9}_df!~mrnHX{h~fT|fG<^fp{z{2qHKNpY* z(ggyHK=TxUv?SOS3=Bd{Obli~zJUQmUI3`y3CIVzP!dQAF)%T>18HP=KQul=NosM) n=0YP@Ms|?Xf!>;Y(NK8u1Yuserland_data[uid].page_directories; @@ -269,25 +230,24 @@ int allocate_new_page(int uid, int 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; - struct page_table_entry *new_page_table = USERLAND_BASE_ADDRESS + dir_address * 1024 * 4; + 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}); } - for (struct page_table_entry *i = new_page_table; i < new_page_table + 1024; i++) - { - int avl_address = find_page_avl(); - set_page(avl_address); - *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 = (avl_address >> 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/userland.c b/src/userland.c index 9662161..edf2ed8 100644 --- a/src/userland.c +++ b/src/userland.c @@ -1,28 +1,43 @@ #include "userland.h" +#include "debug.h" +#include "paging.h" +#include "launch_process.h" + struct userlands_data *userland_data = 0x3020000; -// void userland(void) -// { -// 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 +int create_process(int uid, char *data_start) +{ + 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); + + // 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 97b22fb..c89a721 100644 --- a/src/userland.h +++ b/src/userland.h @@ -20,6 +20,7 @@ struct userlands_data { extern struct userlands_data *userland_data; -void userland(void); +int create_process(int uid, char *data_start); +int switch_to_process(int uid); #endif /* !USERLAND_H */