00001
00002
00003
00004
00005
00006
00007
00008 #include "types.h"
00009 #include "elf.h"
00010 #include "x86.h"
00011
00012 #define SECTSIZE 512
00013
00014 void readseg(uchar*, uint, uint);
00015
00016 void
00017 bootmain(void)
00018 {
00019 struct elfhdr *elf;
00020 struct proghdr *ph, *eph;
00021 void (*entry)(void);
00022 uchar* va;
00023
00024 elf = (struct elfhdr*)0x10000;
00025
00026
00027 readseg((uchar*)elf, 4096, 0);
00028
00029
00030 if(elf->magic != ELF_MAGIC)
00031 return;
00032
00033
00034 ph = (struct proghdr*)((uchar*)elf + elf->phoff);
00035 eph = ph + elf->phnum;
00036 for(; ph < eph; ph++) {
00037 va = (uchar*)(ph->va & 0xFFFFFF);
00038 readseg(va, ph->filesz, ph->offset);
00039 if(ph->memsz > ph->filesz)
00040 stosb(va + ph->filesz, 0, ph->memsz - ph->filesz);
00041 }
00042
00043
00044
00045 entry = (void(*)(void))(elf->entry & 0xFFFFFF);
00046 entry();
00047 }
00048
00049 void
00050 waitdisk(void)
00051 {
00052
00053 while((inb(0x1F7) & 0xC0) != 0x40)
00054 ;
00055 }
00056
00057
00058 void
00059 readsect(void *dst, uint offset)
00060 {
00061
00062 waitdisk();
00063 outb(0x1F2, 1);
00064 outb(0x1F3, offset);
00065 outb(0x1F4, offset >> 8);
00066 outb(0x1F5, offset >> 16);
00067 outb(0x1F6, (offset >> 24) | 0xE0);
00068 outb(0x1F7, 0x20);
00069
00070
00071 waitdisk();
00072 insl(0x1F0, dst, SECTSIZE/4);
00073 }
00074
00075
00076
00077 void
00078 readseg(uchar* va, uint count, uint offset)
00079 {
00080 uchar* eva;
00081
00082 eva = va + count;
00083
00084
00085 va -= offset % SECTSIZE;
00086
00087
00088 offset = (offset / SECTSIZE) + 1;
00089
00090
00091
00092
00093 for(; va < eva; va += SECTSIZE, offset++)
00094 readsect(va, offset);
00095 }