diff --git a/bootasm.S b/bootasm.S index fc3ebf6..e29abcf 100644 --- a/bootasm.S +++ b/bootasm.S @@ -5,13 +5,13 @@ # memory at physical address 0x7c00 and starts executing in real mode # with %cs=0 %ip=7c00. -.set PROT_MODE_CSEG, 0x8 # kernel code segment selector -.set PROT_MODE_DSEG, 0x10 # kernel data segment selector -.set CR0_PE_ON, 0x1 # protected mode enable flag +.set CSEG32, 0x8 # kernel code segment selector +.set DSEG32, 0x10 # kernel data segment selector +.set CR0_PE, 0x1 # protected mode enable flag +.code16 # Assemble for 16-bit mode .globl start start: - .code16 # Assemble for 16-bit mode cli # Disable interrupts cld # String operations increment @@ -48,17 +48,17 @@ seta20.2: # effective memory map does not change during the switch. lgdt gdtdesc movl %cr0, %eax - orl $CR0_PE_ON, %eax + orl $CR0_PE, %eax movl %eax, %cr0 # Jump to next instruction, but in 32-bit code segment. # Switches processor into 32-bit mode. - ljmp $PROT_MODE_CSEG, $protcseg + ljmp $CSEG32, $start32 - .code32 # Assemble for 32-bit mode -protcseg: +.code32 # Assemble for 32-bit mode +start32: # Set up the protected-mode data segment registers - movw $PROT_MODE_DSEG, %ax # Our data segment selector + movw $DSEG32, %ax # Our data segment selector movw %ax, %ds # -> DS: Data Segment movw %ax, %es # -> ES: Extra Segment movw %ax, %fs # -> FS @@ -69,7 +69,13 @@ protcseg: movl $start, %esp call bootmain - # If bootmain returns (it shouldn't), loop. + # If bootmain returns (it shouldn't), trigger a Bochs + # breakpoint if running under Bochs, then loop. + movw $0x8a00, %ax # 0x8a00 -> port 0x8a00 + movw %ax, %dx + outw %ax, %dx + movw $0x8e00, %ax # 0x8e00 -> port 0x8a00 + outw %ax, %dx spin: jmp spin diff --git a/bootmain.c b/bootmain.c index 8ba4bd4..14f4ff3 100644 --- a/bootmain.c +++ b/bootmain.c @@ -11,7 +11,7 @@ #define SECTSIZE 512 -void readseg(uint, uint, uint); +void readseg(uchar*, uint, uint); void bootmain(void) @@ -19,32 +19,31 @@ bootmain(void) struct elfhdr *elf; struct proghdr *ph, *eph; void (*entry)(void); + uchar* va; elf = (struct elfhdr*)0x10000; // scratch space // Read 1st page off disk - readseg((uint)elf, SECTSIZE*8, 0); + readseg((uchar*)elf, 4096, 0); // Is this an ELF executable? if(elf->magic != ELF_MAGIC) - goto bad; + 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++) - readseg(ph->va & 0xFFFFFF, ph->memsz, ph->offset); + for(; ph < eph; ph++) { + va = (uchar*)(ph->va & 0xFFFFFF); + readseg(va, ph->filesz, ph->offset); + if(ph->memsz > ph->filesz) + stosb(va + ph->filesz, 0, ph->memsz - ph->filesz); + } // Call the entry point from the ELF header. // Does not return! entry = (void(*)(void))(elf->entry & 0xFFFFFF); entry(); - -bad: - outw(0x8A00, 0x8A00); - outw(0x8A00, 0x8E00); - for(;;) - ; } void @@ -76,14 +75,14 @@ readsect(void *dst, uint offset) // Read 'count' bytes at 'offset' from kernel into virtual address 'va'. // Might copy more than asked. void -readseg(uint va, uint count, uint offset) +readseg(uchar* va, uint count, uint offset) { - uint eva; + uchar* eva; eva = va + count; // Round down to sector boundary. - va &= ~(SECTSIZE - 1); + va -= offset % SECTSIZE; // Translate from bytes to sectors; kernel starts at sector 1. offset = (offset / SECTSIZE) + 1; @@ -92,5 +91,5 @@ readseg(uint va, uint count, uint offset) // We'd write more to memory than asked, but it doesn't matter -- // we load in increasing order. for(; va < eva; va += SECTSIZE, offset++) - readsect((uchar*)va, offset); + readsect(va, offset); } diff --git a/bootother.S b/bootother.S index 39b284d..cb3ff4c 100644 --- a/bootother.S +++ b/bootother.S @@ -61,7 +61,17 @@ protcseg: movl start-4, %esp movl start-8, %eax - jmp *%eax + call *%eax + + # If bootmain returns (it shouldn't), trigger a Bochs + # breakpoint if running under Bochs, then loop. + movw $0x8a00, %ax # 0x8a00 -> port 0x8a00 + movw %ax, %dx + outw %ax, %dx + movw $0x8e00, %ax # 0x8e00 -> port 0x8a00 + outw %ax, %dx +spin: + jmp spin # Bootstrap GDT .p2align 2 # force 4 byte alignment diff --git a/main.c b/main.c index c93d9bf..fbad920 100644 --- a/main.c +++ b/main.c @@ -12,11 +12,6 @@ static void mpmain(void) __attribute__((noreturn)); int main(void) { - extern char edata[], end[]; - - // clear BSS - memset(edata, 0, end - edata); - mp_init(); // collect info about this machine lapic_init(mp_bcpu()); cprintf("\ncpu%d: starting xv6\n\n", cpu());