]> Devi Nivas Git - cs3210-lab1.git/commitdiff
xv6: boot loader adjustments
authorrsc <rsc>
Sun, 8 Mar 2009 21:41:30 +0000 (21:41 +0000)
committerrsc <rsc>
Sun, 8 Mar 2009 21:41:30 +0000 (21:41 +0000)
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

bootasm.S
bootmain.c
bootother.S
main.c

index fc3ebf677b90366076e2d1e8c2dee78c50005bce..e29abcfbebd580d8ae1ed0c00bcdf8df1ab23d31 100644 (file)
--- 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
 
index 8ba4bd4c2c89ea44e3a124e2e7fea27f89b9558a..14f4ff3e3b9c44d429cfdf1faa27ae7401ef8020 100644 (file)
@@ -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);
 }
index 39b284d3e7fd2642a9e5227931889877b50762cc..cb3ff4c7a35ee171b8060aace006b3b1cc13db57 100644 (file)
@@ -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 c93d9bfeab41b8d6914fe4ff22d28d188c6eb7a9..fbad920c309cf3098b9e5e58cab08931351bc64a 100644 (file)
--- 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());