Skip to content

Commit

Permalink
xv6: boot loader adjustments
Browse files Browse the repository at this point in the history
do Bochs breakpoint and spin in bootasm.S.
not needed in bootmain too.
fix readseg bug (rounding of va).
zero segments when memsz > filesz.
no need to clear BSS in kernel main.
make bootother.S like bootasm.S
  • Loading branch information
rsc committed Mar 8, 2009
1 parent 8220135 commit b7f653d
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 31 deletions.
26 changes: 16 additions & 10 deletions bootasm.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down
29 changes: 14 additions & 15 deletions bootmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,39 @@

#define SECTSIZE 512

void readseg(uint, uint, uint);
void readseg(uchar*, uint, uint);

void
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
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
12 changes: 11 additions & 1 deletion bootother.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 0 additions & 5 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit b7f653d

Please sign in to comment.