Xv6 with picoc & Linkage editor
v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
|
00001 // Boot loader. 00002 // 00003 // Part of the boot sector, along with bootasm.S, which calls bootmain(). 00004 // bootasm.S has put the processor into protected 32-bit mode. 00005 // bootmain() loads an ELF kernel image from the disk starting at 00006 // sector 1 and then jumps to the kernel entry routine. 00007 00008 #include "types.h" 00009 #include "elf.h" 00010 #include "x86.h" 00011 #include "memlayout.h" 00012 00013 #define SECTSIZE 512 00014 00015 void readseg(uchar*, uint, uint); 00016 00017 void 00018 bootmain(void) 00019 { 00020 struct elfhdr *elf; 00021 struct proghdr *ph, *eph; 00022 void (*entry)(void); 00023 uchar* pa; 00024 00025 elf = (struct elfhdr*)0x10000; // scratch space 00026 00027 // Read 1st page off disk 00028 readseg((uchar*)elf, 4096, 0); 00029 00030 // Is this an ELF executable? 00031 if(elf->magic != ELF_MAGIC) 00032 return; // let bootasm.S handle error 00033 00034 // Load each program segment (ignores ph flags). 00035 ph = (struct proghdr*)((uchar*)elf + elf->phoff); 00036 eph = ph + elf->phnum; 00037 for(; ph < eph; ph++){ 00038 pa = (uchar*)ph->paddr; 00039 readseg(pa, ph->filesz, ph->off); 00040 if(ph->memsz > ph->filesz) 00041 stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz); 00042 } 00043 00044 // Call the entry point from the ELF header. 00045 // Does not return! 00046 entry = (void(*)(void))(elf->entry); 00047 entry(); 00048 } 00049 00050 void 00051 waitdisk(void) 00052 { 00053 // Wait for disk ready. 00054 while((inb(0x1F7) & 0xC0) != 0x40) 00055 ; 00056 } 00057 00058 // Read a single sector at offset into dst. 00059 void 00060 readsect(void *dst, uint offset) 00061 { 00062 // Issue command. 00063 waitdisk(); 00064 outb(0x1F2, 1); // count = 1 00065 outb(0x1F3, offset); 00066 outb(0x1F4, offset >> 8); 00067 outb(0x1F5, offset >> 16); 00068 outb(0x1F6, (offset >> 24) | 0xE0); 00069 outb(0x1F7, 0x20); // cmd 0x20 - read sectors 00070 00071 // Read data. 00072 waitdisk(); 00073 insl(0x1F0, dst, SECTSIZE/4); 00074 } 00075 00076 // Read 'count' bytes at 'offset' from kernel into physical address 'pa'. 00077 // Might copy more than asked. 00078 void 00079 readseg(uchar* pa, uint count, uint offset) 00080 { 00081 uchar* epa; 00082 00083 epa = pa + count; 00084 00085 // Round down to sector boundary. 00086 pa -= offset % SECTSIZE; 00087 00088 // Translate from bytes to sectors; kernel starts at sector 1. 00089 offset = (offset / SECTSIZE) + 1; 00090 00091 // If this is too slow, we could read lots of sectors at a time. 00092 // We'd write more to memory than asked, but it doesn't matter -- 00093 // we load in increasing order. 00094 for(; pa < epa; pa += SECTSIZE, offset++) 00095 readsect(pa, offset); 00096 }