diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rwxr-xr-x | run | 1 | ||||
-rw-r--r-- | src/kernel/fs/elf.c | 86 | ||||
-rw-r--r-- | src/kernel/fs/elf.h | 28 | ||||
-rw-r--r-- | src/kernel/fs/ext2.c | 2 | ||||
-rw-r--r-- | src/kernel/fs/load.c | 1 | ||||
-rw-r--r-- | src/kernel/fs/load.h | 3 | ||||
-rw-r--r-- | src/kernel/kernel.c | 3 | ||||
-rwxr-xr-x | src/resources/conv.sh | 2 | ||||
-rw-r--r-- | src/resources/font.c | 2 | ||||
-rw-r--r-- | src/userspace/linker.ld | 2 |
11 files changed, 75 insertions, 63 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cf3ba4..14436e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,11 +55,7 @@ add_custom_command( add_executable(user ${user_sources}) target_include_directories(user PUBLIC "src/userspace/") set_target_properties(user PROPERTIES OUTPUT_NAME "${CMAKE_CURRENT_SOURCE_DIR}/build/user.o") -add_custom_command( - TARGET user POST_BUILD - COMMAND cross/opt/bin/i686-elf-objcopy -O binary build/user.o build/user.bin - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) - +target_link_libraries(kernel PRIVATE "-T ${CMAKE_CURRENT_SOURCE_DIR}/src/userspace/linker.ld") + # Dependencies add_dependencies(kernel resources user) @@ -112,6 +112,7 @@ make_build() { mkdir -p ./mnt/usr/ mkdir -p ./mnt/bin/ cp ./build/font.bin ./mnt/bin/font + cp ./build/user.o ./mnt/bin/user echo "Hello world, ext2!" | tee -a ./mnt/etc/test /usr/local/bin/genext2fs -B 4096 -d mnt -U -N 4096 -b 65536 ./build/disk.img rm -r mnt/ diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index f6d7fb8..dd1e764 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -4,63 +4,59 @@ #include <kernel/memory/alloc.h> #include <kernel/lib/lib.h> #include <kernel/memory/paging.h> +#include <kernel/fs/ext2.h> -#define USER_OFFSET 0x40000000 -#define USER_STACK 0xF0000000 -#define PT_LOAD 0x1 - -int is_elf(char *elf_data) +int is_elf(elf_header_t *header) { - elf_header_t *header = (elf_header_t *)elf_data; - if (header->ident[0] == 0x7f && header->ident[1] == 'E' && header->ident[2] == 'L' && - header->ident[3] == 'F') { - log("Buffer is valid ELF file!"); + if (header->ident[0] == ELF_MAG && header->ident[1] == 'E' && header->ident[2] == 'L' && + header->ident[3] == 'F' && header->ident[4] == ELF_32 && + header->ident[5] == ELF_LITTLE && header->ident[6] == ELF_CURRENT && + header->machine == ELF_386 && (header->type == ET_REL || header->type == ET_EXEC)) { return 1; } return 0; } -uint32_t load_elf(char *elf_data) +void elf_load(char *path) { - uint32_t v_begin, v_end; - elf_header_t *hdr; - elf_program_header_t *p_entry; - elf_section_header_t *s_entry; - - hdr = (elf_header_t *)elf_data; - p_entry = (elf_program_header_t *)(elf_data + hdr->phoff); - - s_entry = (elf_section_header_t *)(elf_data + hdr->shoff); - - if (is_elf(elf_data) == 0) - return 0; - - for (int pe = 0; pe < hdr->phnum; pe++, p_entry++) { - if (p_entry->type == PT_LOAD) { - v_begin = p_entry->vaddr; - v_end = p_entry->vaddr + p_entry->memsz; - if (v_begin < USER_OFFSET) { - warn("load_elf(): can't load executable below %x", USER_OFFSET); - return 0; - } + uint8_t *file = read_file(path); + if (!file) { + warn("File or directory not found: %s", file); + return; + } - if (v_end > USER_STACK) { - warn("load_elf(): can't load executable above %x", USER_STACK); - return 0; - } + elf_header_t *header = (elf_header_t *)file; + elf_program_header_t *program_header = (void *)header + header->phoff; - log("ELF: entry flags: %x (%d)", p_entry->flags, p_entry->flags); + if (!is_elf(header)) { + warn("File not valid: %s", path); + return; + } else { + debug("File is valid: %s", path); + } - memcpy((uint8_t *)v_begin, (uint8_t *)(elf_data + p_entry->offset), - p_entry->filesz); - if (p_entry->memsz > p_entry->filesz) { - char *p = (char *)p_entry->vaddr; - for (int i = p_entry->filesz; i < (int)(p_entry->memsz); i++) { - p[i] = 0; - } + uint32_t seg_begin, seg_end; + for (int i = 0; i < header->phnum; i++) { + if (program_header->type == 1) { + seg_begin = program_header->vaddr; + seg_end = seg_begin + program_header->memsz; + + for (uint32_t z = 0; z < seg_end - seg_begin; z += 4096) + paging_map((uint32_t)seg_begin + z, (uint32_t)seg_begin + z, + PT_PRESENT | PT_RW | PT_USED | PT_ALL_PRIV); + + memcpy((void *)seg_begin, file + program_header->offset, + program_header->filesz); + memset((void *)(seg_begin + program_header->filesz), 0, + program_header->memsz - program_header->filesz); + + // Code segment + if (program_header->flags == PF_X + PF_R + PF_W || + program_header->flags == PF_X + PF_R) { + debug("Found code segment"); + // current_process->regs.eip = header->entry + seg_begin; } } + program_header++; } - - return hdr->entry; }
\ No newline at end of file diff --git a/src/kernel/fs/elf.h b/src/kernel/fs/elf.h index 7e599b8..fa6dbb0 100644 --- a/src/kernel/fs/elf.h +++ b/src/kernel/fs/elf.h @@ -3,6 +3,30 @@ #include <stdint.h> +#define ELF_MAG 0x7F // 0 +#define ELF_32 (1) // 4: 32-bit Architecture +#define ELF_LITTLE (1) // 5: Little Endian +#define ELF_CURRENT (1) // 6: ELF Current Version +#define ELF_386 (3) // header->machine x86 machine type + +#define ET_NONE 0 // Unkown type +#define ET_REL 1 // Relocatable file +#define ET_EXEC 2 // Executable file + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 + typedef struct { uint32_t sig; } elf_priv_data; @@ -48,7 +72,7 @@ typedef struct { uint32_t align; } elf_program_header_t; -int is_elf(char *data); -uint32_t load_elf(char *elf_data); +int is_elf(elf_header_t *header); +void elf_load(char *path); #endif
\ No newline at end of file diff --git a/src/kernel/fs/ext2.c b/src/kernel/fs/ext2.c index afab33d..5fb0158 100644 --- a/src/kernel/fs/ext2.c +++ b/src/kernel/fs/ext2.c @@ -241,7 +241,7 @@ uint8_t *read_file(char *path) ext2_open_inode(inode, &file); if (inode != 0) { size_t size = file.inode.size; - debug("%dKiB", size >> 10); + debug("Reading %s: %dKiB", path, size >> 10); uint8_t *buf = kmalloc(size); ext2_read(&file, buf, size); kfree(file.buf); diff --git a/src/kernel/fs/load.c b/src/kernel/fs/load.c index 59bb905..f3e46ed 100644 --- a/src/kernel/fs/load.c +++ b/src/kernel/fs/load.c @@ -6,7 +6,6 @@ void load_binaries() { - // userspace = (uint32_t)read_file("/bin/user.bin"); font = (struct font *)read_file("/bin/font"); log("Successfully loaded binaries"); diff --git a/src/kernel/fs/load.h b/src/kernel/fs/load.h index d4833ce..d03b0ec 100644 --- a/src/kernel/fs/load.h +++ b/src/kernel/fs/load.h @@ -3,8 +3,6 @@ #include <stdint.h> -uint32_t userspace; - struct font *font; struct font { @@ -12,7 +10,6 @@ struct font { uint16_t font_24[758][24]; uint8_t font_16[758][16]; uint16_t cursor[19]; - uint32_t magic; }; void load_binaries(); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index c5137bd..441f188 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -62,9 +62,10 @@ void kernel_main(uint32_t magic, uint32_t multiboot_address) load_binaries(); set_optimal_resolution(); - printf("Awesome!"); + elf_load("/bin/user"); + // tasking_install(); #ifdef INSTALL_MELVIX diff --git a/src/resources/conv.sh b/src/resources/conv.sh index 8b38016..36a17d0 100755 --- a/src/resources/conv.sh +++ b/src/resources/conv.sh @@ -4,7 +4,7 @@ printf "// Generated using the Spleen font and the bdf2c converter (modified using the conv.sh script)\n// Spleen font: (c) 2018-2019, Frederic Cambus, License: MIT\n // bdf2c: (c) 2009-2010 Lutz Sammer, License: AGPLv3\n\n" >font.c -printf "#include <stdint.h>\n\nuint32_t magic=0xf0f0f0f0;\n\nuint16_t cursor[19]={0b100000000000,0b110000000000,0b111000000000,0b111100000000,0b111110000000,0b111111000000,0b111111100000,0b111111110000,0b111111111000,0b111111111100,0b111111111110,0b111111111111,0b111111111111,0b111111110000,0b111101111000,0b111001111000,0b110000111100,0b000000111100,0b000000011000};\n" >>font.c +printf "#include <stdint.h>\n\nuint16_t cursor[19]={0b100000000000,0b110000000000,0b111000000000,0b111100000000,0b111110000000,0b111111000000,0b111111100000,0b111111110000,0b111111111000,0b111111111100,0b111111111110,0b111111111111,0b111111111111,0b111111110000,0b111101111000,0b111001111000,0b110000111100,0b000000111100,0b000000011000};\n" >>font.c generate() { font_url="https://raw.githubusercontent.com/fcambus/spleen/master/spleen-$1x$2.bdf" diff --git a/src/resources/font.c b/src/resources/font.c index 4269b35..de5dda1 100644 --- a/src/resources/font.c +++ b/src/resources/font.c @@ -4,8 +4,6 @@ #include <stdint.h> -uint32_t magic = 0xf0f0f0f0; - uint16_t cursor[19] = { 0b100000000000, 0b110000000000, 0b111000000000, 0b111100000000, 0b111110000000, 0b111111000000, 0b111111100000, 0b111111110000, 0b111111111000, 0b111111111100, 0b111111111110, 0b111111111111, diff --git a/src/userspace/linker.ld b/src/userspace/linker.ld index 152e0bf..d793912 100644 --- a/src/userspace/linker.ld +++ b/src/userspace/linker.ld @@ -1,7 +1,7 @@ ENTRY(_start) SECTIONS { - .text 0x40000000 : { + .text : { *(.text) . = ALIGN(4096); } |