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
bootmain.c
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 }
 All Data Structures