X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Floader.S;h=4e4fbb4c3e162ace5f0c0d6d1477a92d99e49bbd;hb=6c5c6fdfe80bad40c90c19b67f00226610d59a38;hp=c60e8dd6bd3347551b30f727617b113b88494388;hpb=44d0fa6a2b24a84e5eb0d54959ed91c1d4f15343;p=pintos-anon diff --git a/src/threads/loader.S b/src/threads/loader.S index c60e8dd..4e4fbb4 100644 --- a/src/threads/loader.S +++ b/src/threads/loader.S @@ -1,15 +1,23 @@ +#include "loader.h" #include "mmu.h" -################################################################################### -# ENTRY POINT -# This code should be stored in the first sector of the hard disk. When the -# BIOS runs, it loads this code at physical address 0x7c00 - 0x7e00 (512 bytes). -# Then jumps to the beginning of it, in real-mode (BIOS runs in real mode). -# +############################################################################## +# Kernel loader. +# +# This code should be stored in the first sector of the hard disk. When the +# BIOS runs, it loads this code at physical address 0x7c00-0x7e00 (512 bytes). +# Then it jumps to the beginning of it, in real mode. # This code switches into protected mode (32-bit mode) so that all of -# memory can accessed, then calls into C. -################################################################################### +# memory can accessed, loads the kernel into memory, and jumps to the +# first byte of the kernel, where start.S is linked. +############################################################################## +/* Flags in control register 0 */ +#define CR0_PE 0x00000001 /* Protection Enable. */ +#define CR0_EM 0x00000004 /* (Floating-point) Emulation. */ +#define CR0_PG 0x80000000 /* Paging. */ +#define CR0_WP 0x00010000 /* Write-Protect enable in kernel mode. */ + .globl start # Entry point start: .code16 # This runs in real mode cli # Disable interrupts @@ -40,12 +48,12 @@ start: .code16 # This runs in real mode #### Returns CF clear if successful, with AX = (kB of physical memory) - 1024. #### This only works for memory sizes <= 65 MB, which should be fine for our purposes. - movb $0x88,%ah - int $0x15 - jc panic # Carry flag set on error - addl $1024,%eax # Total kB - shrl $2,%eax # Total 4 kB pages - movl %eax, ram_pages + movb $0x88,%ah + int $0x15 + jc panic # Carry flag set on error +2: addl $1024,%eax # Total kB + shrl $2,%eax # Total 4 kB pages + movl %eax, ram_pages #### switch from real to protected mode #### The segments in GDT allow all of physical memory to be accessed. @@ -59,9 +67,10 @@ start: .code16 # This runs in real mode movl %cr0, %eax # turn on protected mode orl $CR0_PE, %eax # movl %eax, %cr0 # - ### CPU magic: jump to relocation, flush prefetch queue, and reload %cs - ### Has the effect of just jmp to the next instruction, but simultaneous - ### loads CS with $PROT_MODE_CSEG. + ### CPU magic: jump to relocation, flush prefetch queue, and + ### reload %cs Has the effect of just jmp to the next + ### instruction, but simultaneous loads CS with + ### $PROT_MODE_CSEG. ljmp $SEL_KCSEG, $protcseg #### We are in protected mode in a 32-bit segment (hence the .code32) @@ -74,10 +83,11 @@ protcseg: movw %ax, %gs movw %ax, %ss -#### Load kernel at 1 MB by frobbing the IDE controller directly. +#### Load kernel starting at physical address LOADER_KERN_BASE by +#### frobbing the IDE controller directly. movl $1, %ebx - movl $0x100000, %edi + movl $LOADER_KERN_BASE, %edi read_sector: ### Poll status register while controller busy. @@ -129,27 +139,35 @@ read_sector: cmpl $KERNEL_LOAD_PAGES*8 + 1, %ebx jnz read_sector -##### Create temporary PDE and PTE and set page directory pointer +##### Create temporary page directory and page table, set page +##### directory pointer, and turn on paging. ##### FIXME? We could use a single 4 MB page instead of 1024 4 kB pages. - movl $0x10000, %edi + # Create page directory at 64 kB. + movl $0x10000, %edi movl %edi, %cr3 + + # Fill page directory with zeroes. subl %eax, %eax movl $0x400, %ecx rep stosl + + # Set PDEs for 0 and LOADER_PHYS_BASE to point to the + # page table. movl $0x11000 | PG_U | PG_W | PG_P, %eax movl %eax, 0x10000 - movl %eax, 0x10c00 + movl %eax, 0x10000 | (LOADER_PHYS_BASE >> 20) + + # Initialize page table. movl $PG_U | PG_W | PG_P, %eax movl $0x400, %ecx 1: stosl addl $0x1000, %eax loop 1b -##### Enable paging. - + # Turn on paging and kernel write-protect. movl %cr0, %eax - orl $CR0_PG, %eax + orl $CR0_PG | CR0_WP, %eax movl %eax, %cr0 jmp 1f 1: @@ -163,8 +181,8 @@ read_sector: ##### Jump to kernel entry point. - movl $0xc0007c00, %esp - movl $0xc0100000, %eax + movl $LOADER_PHYS_BASE + LOADER_BASE, %esp + movl $LOADER_PHYS_BASE + LOADER_KERN_BASE, %eax jmp *%eax ##### GDT @@ -178,14 +196,33 @@ gdtdesc: .word 0x17 # sizeof (gdt) - 1 .long gdt # address gdt -##### Arrive here on error -panic: jmp panic +##### To panic, we print panicmsg (with help from the BIOS) and spin. +panic: .code16 # We only panic in real mode. + movw $panicmsg, %si + movb $0xe, %ah + xorb %bh, %bh +1: lodsb + test %al, %al +2: jz 2b # Spin. + int $0x10 + jmp 1b + +panicmsg: + .ascii "Loader panic!\r\n" + .byte 0 ##### Memory size in 4 kB pages. - .org 0x200 - 8 + .org LOADER_RAM_PAGES - LOADER_BASE ram_pages: .long 0 +##### Command-line arguments inserted by another utility. +##### The loader doesn't use these, but we note their +##### location here for easy reference. + .org LOADER_CMD_LINE - LOADER_BASE +cmd_line: + .fill 0x80, 1, 0 + ##### Boot-sector signature for BIOS inspection. - .org 0x200 - 2 + .org LOADER_BIOS_SIG - LOADER_BASE .word 0xaa55