]> Joshua Wise's Git repositories - netwatch.git/commitdiff
Merge ELF loader.
authorJoshua Wise <joshua@rebirth.joshuawise.com>
Wed, 10 Sep 2008 22:24:10 +0000 (18:24 -0400)
committerJoshua Wise <joshua@rebirth.joshuawise.com>
Wed, 10 Sep 2008 22:24:10 +0000 (18:24 -0400)
elfload/loader.c
grubload/Makefile
grubload/loader.c [new file with mode: 0644]
grubload/loader.h [new file with mode: 0644]
grubload/minilib.c
grubload/minilib.h [new file with mode: 0644]
grubload/multiboot_c.c
include/elf.h [moved from elfload/elf.h with 99% similarity]

index a231c85f3ac501900c28e5dd0368483e6ddeb3dc..c70571d9aa38866d89f880fcf1301e859657997f 100644 (file)
@@ -1,6 +1,6 @@
 #include <string.h>
 #include <stdio.h>
-#include "elf.h"
+#include "../include/elf.h"
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
index c850bb33434cc4512e48560bff4ce102e3432dd4..f0f9742d55564c4f8f0842cbfc60b4e62be82b38 100644 (file)
@@ -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 (file)
index 0000000..4ecba2a
--- /dev/null
@@ -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 (file)
index 0000000..e5d5c52
--- /dev/null
@@ -0,0 +1,2 @@
+int load_elf (char * buf, int size) ;
+
index f2ab6629d858238d8fd76b0634e1e06536110c5d..b9813d7992fae94635eafc6fdc02776de76084cc 100644 (file)
@@ -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 (file)
index 0000000..e0fc16b
--- /dev/null
@@ -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
index 25522e26c7cdffe8a14945a0066ad247f9454554..03e2143ba7d6970a8ab967f9ee33fd0f4024ac0b 100644 (file)
@@ -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!
 }
similarity index 99%
rename from elfload/elf.h
rename to include/elf.h
index 7240b699cfc5ce1d42d6a5ca191afd3b493aee76..0d5abbd0f72edd850c80994fc2ccc4ed76c28e91 100644 (file)
@@ -21,7 +21,9 @@
 #ifndef _ELF_H
 #define        _ELF_H 1
 
+#ifndef MINILIB
 #include <stdint.h>
+#endif
 
 /* Standard ELF types.  */
 
This page took 0.033136 seconds and 4 git commands to generate.