aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2016-07-30 20:37:21 +0200
committerAlex Auvolat <alex@adnab.me>2016-07-30 20:37:21 +0200
commitfa5327d4cc5e47656326b8c0c55d23cd71b04462 (patch)
treee0b9f5a9bf45bedbf8383b8839c98b04c5e44552 /src
parent6466208ec051e58b824cc3c839b6b086ae910fe6 (diff)
downloadkogata-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.lua3
-rw-r--r--src/kernel/core/kmain.c29
-rw-r--r--src/kernel/core/sys.c34
-rw-r--r--src/kernel/include/elf.h25
-rw-r--r--src/kernel/include/multiboot.h2
-rw-r--r--src/kernel/include/sys.h4
-rw-r--r--src/lib/include/stdio.h4
-rw-r--r--src/lib/libc/stdio.c69
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;
}