| // Boot loader. | |
| // | |
| // Part of the boot block, along with bootasm.S, which calls bootmain(). | |
| // bootasm.S has put the processor into protected 32-bit mode. | |
| // bootmain() loads an ELF kernel image from the disk starting at | |
| // sector 1 and then jumps to the kernel entry routine. | |
| void readseg(uchar*, uint, uint); | |
| void | |
| bootmain(void) | |
| { | |
| struct elfhdr *elf; | |
| struct proghdr *ph, *eph; | |
| void (*entry)(void); | |
| uchar* pa; | |
| elf = (struct elfhdr*)0x10000; // scratch space | |
| // Read 1st page off disk | |
| readseg((uchar*)elf, 4096, 0); | |
| // Is this an ELF executable? | |
| if(elf->magic != ELF_MAGIC) | |
| return; // let bootasm.S handle error | |
| // Load each program segment (ignores ph flags). | |
| ph = (struct proghdr*)((uchar*)elf + elf->phoff); | |
| eph = ph + elf->phnum; | |
| for(; ph < eph; ph++){ | |
| pa = (uchar*)ph->paddr; | |
| readseg(pa, ph->filesz, ph->off); | |
| if(ph->memsz > ph->filesz) | |
| stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz); | |
| } | |
| // Call the entry point from the ELF header. | |
| // Does not return! | |
| entry = (void(*)(void))(elf->entry); | |
| entry(); | |
| } | |
| void | |
| waitdisk(void) | |
| { | |
| // Wait for disk ready. | |
| while((inb(0x1F7) & 0xC0) != 0x40) | |
| ; | |
| } | |
| // Read a single sector at offset into dst. | |
| void | |
| readsect(void *dst, uint offset) | |
| { | |
| // Issue command. | |
| waitdisk(); | |
| outb(0x1F2, 1); // count = 1 | |
| outb(0x1F3, offset); | |
| outb(0x1F4, offset >> 8); | |
| outb(0x1F5, offset >> 16); | |
| outb(0x1F6, (offset >> 24) | 0xE0); | |
| outb(0x1F7, 0x20); // cmd 0x20 - read sectors | |
| // Read data. | |
| waitdisk(); | |
| insl(0x1F0, dst, SECTSIZE/4); | |
| } | |
| // Read 'count' bytes at 'offset' from kernel into physical address 'pa'. | |
| // Might copy more than asked. | |
| void | |
| readseg(uchar* pa, uint count, uint offset) | |
| { | |
| uchar* epa; | |
| epa = pa + count; | |
| // Round down to sector boundary. | |
| pa -= offset % SECTSIZE; | |
| // Translate from bytes to sectors; kernel starts at sector 1. | |
| offset = (offset / SECTSIZE) + 1; | |
| // If this is too slow, we could read lots of sectors at a time. | |
| // We'd write more to memory than asked, but it doesn't matter -- | |
| // we load in increasing order. | |
| for(; pa < epa; pa += SECTSIZE, offset++) | |
| readsect(pa, offset); | |
| } | |
Xet Storage Details
- Size:
- 2.25 kB
- Xet hash:
- c6f3d4d95420934f76b0624881f12ff83699c6f0b423f90a397920c2220bf0f9
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.