From: Joshua Wise Date: Wed, 10 Sep 2008 22:24:10 +0000 (-0400) Subject: Merge ELF loader. X-Git-Url: http://git.joshuawise.com/netwatch.git/commitdiff_plain/86c89e89a88d25e85956b258005b52e0f2686b89?hp=c4a165640f8cbf4844426c8cea87246db3953467 Merge ELF loader. --- diff --git a/elfload/loader.c b/elfload/loader.c index a231c85..c70571d 100644 --- a/elfload/loader.c +++ b/elfload/loader.c @@ -1,6 +1,6 @@ #include #include -#include "elf.h" +#include "../include/elf.h" #include #include #include diff --git a/grubload/Makefile b/grubload/Makefile index c850bb3..f0f9742 100644 --- a/grubload/Makefile +++ b/grubload/Makefile @@ -1,4 +1,4 @@ -OBJS=multiboot_c.o multiboot_asm.o console.o minilib.o realmode.o +OBJS=multiboot_c.o multiboot_asm.o console.o minilib.o realmode.o loader.o CC=gcc CFLAGS=-nostdlib -I../include -I. -fno-builtin -nostdinc diff --git a/grubload/loader.c b/grubload/loader.c new file mode 100644 index 0000000..4ecba2a --- /dev/null +++ b/grubload/loader.c @@ -0,0 +1,49 @@ +#include "minilib.h" +#include "../include/elf.h" + +static const unsigned char elf_ident[4] = { 0x7F, 'E', 'L', 'F' }; + +int load_elf (char * buf, int size) { + + Elf32_Ehdr * elf_hdr = (Elf32_Ehdr *) buf; + Elf32_Shdr * elf_sec_hdrs = (Elf32_Shdr *) (buf + elf_hdr->e_shoff); + + /* Sanity check on ELF file */ + if (memcmp(elf_hdr->e_ident, elf_ident, sizeof(elf_ident))) return -1; + if (elf_hdr->e_type != ET_EXEC) return -1; + if (elf_hdr->e_machine != EM_386) return -1; + if (elf_hdr->e_version != EV_CURRENT) return -1; + if (size < sizeof(Elf32_Ehdr)) return -1; + if (((char *)&elf_sec_hdrs[elf_hdr->e_shnum]) > (buf + size)) return -1; + + char * string_table = buf + elf_sec_hdrs[elf_hdr->e_shstrndx].sh_offset; + + if (string_table > (buf + size)) return -1; + + int i; + for (i = 0; i < elf_hdr->e_shnum; i++) { + + if (elf_sec_hdrs[i].sh_name == SHN_UNDEF) { + continue; + } + + char * section_name = string_table + elf_sec_hdrs[i].sh_name; + + if ((elf_sec_hdrs[i].sh_type != SHT_PROGBITS) || !(elf_sec_hdrs[i].sh_flags & SHF_ALLOC)) { + puts("Skipping "); + puts(section_name); + puts("\n"); + continue; + } + + puts("Loading "); + puts(section_name); + puts("\n"); + + memcpy(elf_sec_hdrs[i].sh_addr, + buf + elf_sec_hdrs[i].sh_offset, + elf_sec_hdrs[i].sh_size); + } + + return 0; +} diff --git a/grubload/loader.h b/grubload/loader.h new file mode 100644 index 0000000..e5d5c52 --- /dev/null +++ b/grubload/loader.h @@ -0,0 +1,2 @@ +int load_elf (char * buf, int size) ; + diff --git a/grubload/minilib.c b/grubload/minilib.c index f2ab662..b9813d7 100644 --- a/grubload/minilib.c +++ b/grubload/minilib.c @@ -20,6 +20,24 @@ void memmove(unsigned char *dest, unsigned char *src, int bytes) *(dest++) = *(src++); } +int memcmp (unsigned char *a2, unsigned char *a1, int bytes) { + while (bytes--) + { + if (*(a2++) != *(a1++)) + return 1; + } + return 0; +} + +int strcmp (unsigned char *a2, unsigned char *a1) { + while (1) { + if (*a2 != *a1) return 1; + if (*a2 == 0) return 0; + a1++; + a2++; + } +} + int strlen(char *c) { int l = 0; diff --git a/grubload/minilib.h b/grubload/minilib.h new file mode 100644 index 0000000..e0fc16b --- /dev/null +++ b/grubload/minilib.h @@ -0,0 +1,33 @@ +#ifndef __MINILIB_H +#define __MINILIB_H + +#define MINILIB 1 + +#ifndef __int8_t_defined +# define __int8_t_defined +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +# if __WORDSIZE == 64 +typedef long int int64_t; +# else +__extension__ +typedef long long int int64_t; +# endif +#endif + +/* Unsigned. */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +#ifndef __uint32_t_defined +typedef unsigned int uint32_t; +# define __uint32_t_defined +#endif +#if __WORDSIZE == 64 +typedef unsigned long int uint64_t; +#else +__extension__ +typedef unsigned long long int uint64_t; +#endif + +#endif diff --git a/grubload/multiboot_c.c b/grubload/multiboot_c.c index 25522e2..03e2143 100644 --- a/grubload/multiboot_c.c +++ b/grubload/multiboot_c.c @@ -38,7 +38,8 @@ void c_start(unsigned int magic, struct mb_info *wee) puts("Grubptr is: "); puthex(*grubptr); puts("\n"); - + + for (i = 0; i < wee->mod_cnt; i++) { puts("Module:\n"); @@ -47,7 +48,15 @@ void c_start(unsigned int magic, struct mb_info *wee) puts(" Name: "); puts(wee->mods[i].mod_string); puts("\n"); } + if ((wee->mod_cnt != 1) || (strcmp(wee->mods[0].mod_string, "aseg.elf"))) + { + puts("Expected 1 module called aseg.elf.\n"); + while(1) asm("hlt"); + } + + load_elf(wee->mods[0].mod_start, wee->mods[0].mod_end - wee->mods[0].mod_start); + puts("Now returning to real mode.\n"); memcpy(0x4000, _binary_realmode_bin_start, (int)&_binary_realmode_bin_size); - realmode(); + realmode(); // goodbye! } diff --git a/elfload/elf.h b/include/elf.h similarity index 99% rename from elfload/elf.h rename to include/elf.h index 7240b69..0d5abbd 100644 --- a/elfload/elf.h +++ b/include/elf.h @@ -21,7 +21,9 @@ #ifndef _ELF_H #define _ELF_H 1 +#ifndef MINILIB #include +#endif /* Standard ELF types. */