diff options
author | Alex Auvolat <alex@adnab.me> | 2016-07-30 20:37:21 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2016-07-30 20:37:21 +0200 |
commit | fa5327d4cc5e47656326b8c0c55d23cd71b04462 (patch) | |
tree | e0b9f5a9bf45bedbf8383b8839c98b04c5e44552 /src | |
parent | 6466208ec051e58b824cc3c839b6b086ae910fe6 (diff) | |
download | kogata-fa5327d4cc5e47656326b8c0c55d23cd71b04462.tar.gz kogata-fa5327d4cc5e47656326b8c0c55d23cd71b04462.zip |
Use elf symbol table instead of map file for kernel
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/bam.lua | 3 | ||||
-rw-r--r-- | src/kernel/core/kmain.c | 29 | ||||
-rw-r--r-- | src/kernel/core/sys.c | 34 | ||||
-rw-r--r-- | src/kernel/include/elf.h | 25 | ||||
-rw-r--r-- | src/kernel/include/multiboot.h | 2 | ||||
-rw-r--r-- | src/kernel/include/sys.h | 4 | ||||
-rw-r--r-- | src/lib/include/stdio.h | 4 | ||||
-rw-r--r-- | src/lib/libc/stdio.c | 69 |
8 files changed, 113 insertions, 57 deletions
diff --git a/src/kernel/bam.lua b/src/kernel/bam.lua index 4a82f49..2dc724e 100644 --- a/src/kernel/bam.lua +++ b/src/kernel/bam.lua @@ -3,8 +3,7 @@ local kernel_settings = TableDeepCopy(common_settings) kernel_settings.cc.includes:Add("src/common/include/kogata", "src/kernel/include") -kernel_settings.link.flags:Add("-T src/kernel/linker.ld", - "-Xlinker -Map=build/kernel.map") +kernel_settings.link.flags:Add("-T src/kernel/linker.ld") kernel_source = { Collect('src/kernel/core/*.s'), diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index d09a1b5..dd66805 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -69,6 +69,9 @@ void kmain(multiboot_info_t *mbd, int32_t mb_magic) { // to allocate memory ; they just increment it of the allocated quantity void* kernel_data_end = (void*)&k_end_addr; + elf_shdr_t *elf_sections = (elf_shdr_t*)(mbd->elf_sec.addr + K_HIGHHALF_ADDR); + ASSERT(sizeof(elf_shdr_t) == mbd->elf_sec.size); + dbglog_setup(); dbg_printf("Hello, kernel world!\n"); @@ -95,6 +98,14 @@ void kmain(multiboot_info_t *mbd, int32_t mb_magic) { kernel_data_end = mod_end_pa; } + for (unsigned i = 0; i < mbd->elf_sec.num; i++) { + elf_sections[i].sh_addr += K_HIGHHALF_ADDR; + size_t section_end = elf_sections[i].sh_addr + elf_sections[i].sh_size; + void* section_end_pa = (void*)((section_end & 0xFFFFF000) + 0x1000); + if (section_end_pa > kernel_data_end) + kernel_data_end = section_end_pa; + } + gdt_init(); dbg_printf("GDT set up.\n"); idt_init(); dbg_printf("IDT set up.\n"); @@ -125,17 +136,13 @@ void kmain(multiboot_info_t *mbd, int32_t mb_magic) { setup_syscall_table(); dbg_printf("System calls setup ok.\n"); - // If we have a kernel map, load it now - for (unsigned i = 0; i < mbd->mods_count; i++) { - char* modname = (char*)mods[i].string; - size_t len = mods[i].mod_end - mods[i].mod_start; - - if (strlen(modname) > 4 && strcmp(modname + strlen(modname) - 4, ".map") == 0) { - // Copy data to somewhere safe, as it will be modified - void* dup_data = malloc(len + 1); - memcpy(dup_data, (void*)mods[i].mod_start, len); - - load_kernel_symbol_map((char*)dup_data, len); + // Look for kernel symbol table section + for (unsigned i = 0; i < mbd->elf_sec.num; i++) { + dbg_printf("0x%p section type %d addr 0x%p - 0x%p\n", + &elf_sections[i], elf_sections[i].sh_type, + elf_sections[i].sh_addr, elf_sections[i].sh_addr + elf_sections[i].sh_size); + if (elf_sections[i].sh_type == SHT_SYMTAB) { + load_kernel_symbol_table(&elf_sections[i], &elf_sections[elf_sections[i].sh_link]); } } diff --git a/src/kernel/core/sys.c b/src/kernel/core/sys.c index 725843e..2908868 100644 --- a/src/kernel/core/sys.c +++ b/src/kernel/core/sys.c @@ -3,6 +3,8 @@ #include <thread.h> #include <string.h> +#include <elf.h> + #include <btree.h> @@ -44,31 +46,21 @@ void sys_panic_assert(const char* assertion, const char* file, int line) { btree_t *kernel_symbol_map = 0; -void load_kernel_symbol_map(char* text, size_t len) { +void load_kernel_symbol_table(elf_shdr_t *sym, elf_shdr_t *str) { kernel_symbol_map = create_btree(id_key_cmp_fun, 0); ASSERT (kernel_symbol_map != 0); - dbg_printf("Loading kernel symbol map...\n"); - - char* it = text; - while (it < text + len) { - char* eol = it; - while (eol < text + len && *eol != 0 && *eol != '\n') eol++; - if (eol >= text + len) break; - *eol = 0; - - if (it[16] == '0' && it[17] == 'x' && it[34] == ' ' && it[49] == ' ') { - uint32_t addr = 0; - for (unsigned i = 18; i < 34; i++) { - addr *= 16; - if (it[i] >= '0' && it[i] <= '9') addr += it[i] - '0'; - if (it[i] >= 'a' && it[i] <= 'f') addr += it[i] - 'a' + 10; - } - btree_add(kernel_symbol_map, (void*)addr, it + 50); - } + dbg_printf("Loading kernel symbol table...\n"); - it = eol + 1; - } + + ASSERT(sym->sh_entsize == sizeof(elf_sym_t)); + unsigned nsym = sym->sh_size / sym->sh_entsize; + + elf_sym_t *st = (elf_sym_t*)sym->sh_addr; + const char* strtab = (const char*)(str->sh_addr); + for (unsigned j = 0; j < nsym; j++) { + btree_add(kernel_symbol_map, (void*)st[j].st_value, (void*)(strtab + st[j].st_name)); + } } void kernel_stacktrace(uint32_t ebp, uint32_t eip) { diff --git a/src/kernel/include/elf.h b/src/kernel/include/elf.h index 6e0c7cb..79ec023 100644 --- a/src/kernel/include/elf.h +++ b/src/kernel/include/elf.h @@ -16,6 +16,9 @@ #define PT_PHDR 6 #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7fffffff + +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 /* elf_phdr_t :: p_flags : program header entries flags */ #define PF_X (1 << 0) @@ -52,6 +55,28 @@ typedef struct { uint32_t p_flags; uint32_t p_align; } elf_phdr_t; + +typedef struct elf_shdr { + uint32_t sh_name; + uint32_t sh_type; + uint32_t sh_flags; + uint32_t sh_addr; + uint32_t sh_offset; + uint32_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint32_t sh_addralign; + uint32_t sh_entsize; +} elf_shdr_t; + +typedef struct { + uint32_t st_name; + uint32_t st_value; + uint32_t st_size; + uint8_t st_info; + uint8_t st_other; + uint16_t st_shndx; +} elf_sym_t; bool is_elf(fs_handle_t *f); proc_entry_t elf_load(fs_handle_t *f, process_t *process); //Load an ELF to a process, return entry point diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index f84b626..b340a38 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -39,7 +39,7 @@ typedef struct { union { struct aout_symbol_table_t aout_sym; struct elf_section_header_table_t elf_sec; - } u; + }; unsigned long mmap_length; unsigned long mmap_addr; } multiboot_info_t; diff --git a/src/kernel/include/sys.h b/src/kernel/include/sys.h index 038135b..7d62d9e 100644 --- a/src/kernel/include/sys.h +++ b/src/kernel/include/sys.h @@ -3,6 +3,8 @@ #include <debug.h> // common header #include <config.h> +typedef struct elf_shdr elf_shdr_t; + static inline void outb(uint16_t port, uint8_t value) { asm volatile("outb %1, %0" : : "dN"(port), "a"(value)); } @@ -92,7 +94,7 @@ static inline void invlpg(void* addr) { #define ALIGN4_DOWN(x) (((size_t)x)&MASK4) -void load_kernel_symbol_map(char* text, size_t len); +void load_kernel_symbol_table(elf_shdr_t *sym, elf_shdr_t *str); void kernel_stacktrace(uint32_t ebp, uint32_t eip); /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/include/stdio.h b/src/lib/include/stdio.h index 5bb3b71..9048ecb 100644 --- a/src/lib/include/stdio.h +++ b/src/lib/include/stdio.h @@ -25,7 +25,9 @@ struct file_t { size_t out_buf_size, out_buf_used; bool out_buf_owned; - int ungetc_char; + char *in_buf; + size_t in_buf_size; + size_t in_buf_begin, in_buf_end; }; typedef struct file_t FILE; diff --git a/src/lib/libc/stdio.c b/src/lib/libc/stdio.c index f825c1b..0d707ef 100644 --- a/src/lib/libc/stdio.c +++ b/src/lib/libc/stdio.c @@ -14,20 +14,39 @@ FILE *stderr = 0; FILE libc_tty_stdio, libc_stdin, libc_stdout, libc_stderr; void initialize_out_buffer(FILE* f, int buf_mode) { - if (buf_mode == 0) { - f->buf_mode = 0; - f->out_buf = 0; - f->out_buf_size = f->out_buf_used = 0; - f->out_buf_owned = false; - } else { - f->buf_mode = buf_mode; + f->buf_mode = 0; + f->out_buf = 0; + f->out_buf_size = f->out_buf_used = 0; + f->out_buf_owned = false; + + if (buf_mode != 0) { f->out_buf = malloc(BUFSIZ); + if (f->out_buf == 0) { + f->file_mode &= ~FM_WRITE; + return; + } + f->buf_mode = buf_mode; f->out_buf_size = BUFSIZ; f->out_buf_used = 0; f->out_buf_owned = true; } } +void initialize_in_buffer(FILE* f) { + f->in_buf = 0; + f->in_buf_size = 0; + f->in_buf_begin = f->in_buf_end = 0; + + if (f->file_mode & FM_READ) { + f->in_buf = malloc(BUFSIZ); + if (f->in_buf == 0) { + f->file_mode &= ~FM_READ; + return; + } + f->in_buf_size = BUFSIZ; + } +} + void setup_libc_stdio() { if (sc_stat_open(STD_FD_TTY_STDIO, &libc_tty_stdio.st)) { libc_tty_stdio.fd = STD_FD_TTY_STDIO; @@ -35,10 +54,11 @@ void setup_libc_stdio() { libc_tty_stdio.pos = 0; initialize_out_buffer(&libc_tty_stdio, _IOLBF); + initialize_in_buffer(&libc_tty_stdio); + // For interactive input, enable blocking mode sc_fctl(libc_tty_stdio.fd, FC_SET_BLOCKING, 0); libc_tty_stdio.file_mode |= FM_BLOCKING; - libc_tty_stdio.ungetc_char = EOF; stdin = &libc_tty_stdio; stdout = &libc_tty_stdio; @@ -51,10 +71,10 @@ void setup_libc_stdio() { libc_stdin.pos = 0; initialize_out_buffer(&libc_stdin, 0); + initialize_in_buffer(&libc_stdin); - sc_fctl(libc_stdin.fd, FC_SET_BLOCKING, 0); - libc_stdin.file_mode |= FM_BLOCKING; - libc_stdin.ungetc_char = EOF; + int mode = sc_fctl(libc_stdin.fd, FC_GET_MODE, 0); + libc_stdin.file_mode |= (mode & FM_BLOCKING); stdin = &libc_stdin; } @@ -65,6 +85,7 @@ void setup_libc_stdio() { libc_stdout.pos = 0; initialize_out_buffer(&libc_stdout, _IOLBF); + initialize_in_buffer(&libc_stdout); stdout = &libc_stdout; } @@ -75,6 +96,7 @@ void setup_libc_stdio() { libc_stderr.pos = 0; initialize_out_buffer(&libc_stderr, _IONBF); + initialize_in_buffer(&libc_stderr); stderr = &libc_stderr; } @@ -117,7 +139,15 @@ FILE *freopen(const char *path, const char *mode, FILE *stream) { return 0; } int fclose(FILE* f) { - // TODO + if (fflush(f) != 0) return EOF; + + sc_close(f->fd); + if (f->out_buf != 0 && f->out_buf_owned) + free(f->out_buf); + if (f->in_buf != 0) + free(f->in_buf); + free(f); + return 0; } @@ -200,7 +230,7 @@ int setvbuf(FILE *stream, char *buf, int mode, size_t size) { if (stream == NULL || stream->fd == 0 || !(stream->file_mode & FM_WRITE)) return EOF; - if (fflush(stream) == EOF) return EOF; + if (fflush(stream) != 0) return EOF; if (stream->out_buf_owned) free(stream->out_buf); if (buf == NULL) { @@ -247,7 +277,7 @@ int buffered_putc(int c, FILE* stream) { stream->out_buf[stream->out_buf_used++] = c; if (stream->out_buf_used == stream->out_buf_size || (stream->buf_mode == _IOLBF && c == '\n')) { - fflush(stream); + if (fflush(stream) != 0) return EOF; } return c; } @@ -259,7 +289,7 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { if (stream == NULL || stream->fd == 0 || !(stream->file_mode & FM_WRITE)) return 0; - fflush(stream); + if (fflush(stream) != 0) return EOF; size_t ret = sc_write(stream->fd, stream->pos, size * nmemb, ptr); if (!(stream->st.type & (FT_CHARDEV | FT_CHANNEL | FT_DIR))) { @@ -274,7 +304,7 @@ int fputc(int c, FILE *stream) { buffered_putc(c, stream); if (stream->buf_mode == _IONBF) { - if (fflush(stream) == EOF) return EOF; + if (fflush(stream) != 0) return EOF; } return c; } @@ -288,7 +318,7 @@ int fputs(const char *s, FILE *stream) { i++; } if (stream->buf_mode == _IONBF) { - if (fflush(stream) == EOF) return EOF; + if (fflush(stream) != 0) return EOF; } return i; } @@ -324,7 +354,7 @@ int vfprintf(FILE *stream, const char *format, va_list ap) { int ret = vcprintf(vfprintf_putc_fun, stream, format, ap); if (stream->buf_mode == _IONBF) { - if (fflush(stream) == EOF) return -1; + if (fflush(stream) != 0) return -1; } return ret; @@ -347,8 +377,7 @@ int ferror(FILE *stream) { return 0; } int fileno(FILE *stream) { - // TODO - return 0; + return stream->fd; } |