3 // Part of the boot sector, along with bootasm.S, which calls bootmain().
4 // bootasm.S has put the processor into protected 32-bit mode.
5 // bootmain() loads an ELF kernel image from the disk starting at
6 // sector 1 and then jumps to the kernel entry routine.
14 void readseg(uchar
*, uint
, uint
);
20 struct proghdr
*ph
, *eph
;
24 elf
= (struct elfhdr
*)0x10000; // scratch space
26 // Read 1st page off disk
27 readseg((uchar
*)elf
, 4096, 0);
29 // Is this an ELF executable?
30 if(elf
->magic
!= ELF_MAGIC
)
31 return; // let bootasm.S handle error
33 // Load each program segment (ignores ph flags).
34 ph
= (struct proghdr
*)((uchar
*)elf
+ elf
->phoff
);
35 eph
= ph
+ elf
->phnum
;
36 for(; ph
< eph
; ph
++){
38 readseg(va
, ph
->filesz
, ph
->offset
);
39 if(ph
->memsz
> ph
->filesz
)
40 stosb(va
+ ph
->filesz
, 0, ph
->memsz
- ph
->filesz
);
43 // Call the entry point from the ELF header.
45 entry
= (void(*)(void))(elf
->entry
);
52 // Wait for disk ready.
53 while((inb(0x1F7) & 0xC0) != 0x40)
57 // Read a single sector at offset into dst.
59 readsect(void *dst
, uint offset
)
63 outb(0x1F2, 1); // count = 1
65 outb(0x1F4, offset
>> 8);
66 outb(0x1F5, offset
>> 16);
67 outb(0x1F6, (offset
>> 24) | 0xE0);
68 outb(0x1F7, 0x20); // cmd 0x20 - read sectors
72 insl(0x1F0, dst
, SECTSIZE
/4);
75 // Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
76 // Might copy more than asked.
78 readseg(uchar
* va
, uint count
, uint offset
)
84 // Round down to sector boundary.
85 va
-= offset
% SECTSIZE
;
87 // Translate from bytes to sectors; kernel starts at sector 1.
88 offset
= (offset
/ SECTSIZE
) + 1;
90 // If this is too slow, we could read lots of sectors at a time.
91 // We'd write more to memory than asked, but it doesn't matter --
92 // we load in increasing order.
93 for(; va
< eva
; va
+= SECTSIZE
, offset
++)