X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Floader.S;h=2d76763cffc3dcdc2aa339404bfb674360e22ae1;hb=8abbb333aea445641d967befd3ca477502ea770b;hp=811d2b60be1f2c89706d51ae4dd6ef48dea99792;hpb=7d4e3dda080a47db88616f1c0d975f2091be47f1;p=pintos-anon diff --git a/src/threads/loader.S b/src/threads/loader.S index 811d2b6..2d76763 100644 --- a/src/threads/loader.S +++ b/src/threads/loader.S @@ -40,8 +40,6 @@ #include "threads/loader.h" - .intel_syntax noprefix - #### Kernel loader. #### This code should be stored in the first sector of the hard disk. @@ -70,18 +68,19 @@ start: cli cld -# Set up data segments and stack. +# Set up data segments. - sub ax, ax - mov es, ax - mov ds, ax + subw %ax, %ax + movw %ax, %es + movw %ax, %ds +# Set up stack segment. # Stack grows downward starting from us. -# We don't ever use the stack so this is strictly speaking -# unnecessary. +# We don't ever use the stack, but we call into the BIOS, +# which might. - mov ss, ax - mov sp, 0x7c00 + movw %ax, %ss + movw $0x7c00, %sp #### Enable A20. Address line 20 is tied to low when the machine #### boots, which prevents addressing memory about 1 MB. This code @@ -89,25 +88,25 @@ start: # Poll status register while busy. -1: in al, 0x64 - test al, 0x2 +1: inb $0x64, %al + testb $0x2, %al jnz 1b # Send command for writing output port. - mov al, 0xd1 - outb 0x64, al + movb $0xd1, %al + outb %al, $0x64 # Poll status register while busy. -1: in al, 0x64 - test al, 0x2 +1: inb $0x64, %al + testb $0x2, %al jnz 1b # Enable A20 line. - mov al, 0xdf - out 0x60, al + movb $0xdf, %al + outb %al, $0x60 #### Get memory size, via interrupt 15h function 88h. Returns CF #### clear if successful, with AX = (kB of physical memory) - 1024. @@ -115,65 +114,67 @@ start: #### for our purposes. We cap memory at 64 MB because that's all we #### prepare page tables for, below. - mov ah, 0x88 - int 0x15 + movb $0x88, %ah + int $0x15 jc panic - add eax, 1024 # Total kB memory - cmp eax, 0x10000 # Cap at 64 MB + cli # BIOS might have enabled interrupts + addl $1024, %eax # Total kB memory + cmp $0x10000, %eax # Cap at 64 MB jbe 1f - mov eax, 0x10000 -1: shr eax, 2 # Total 4 kB pages - mov ram_pages, eax + mov $0x10000, %eax +1: shrl $2, %eax # Total 4 kB pages + movl %eax, ram_pgs #### Create temporary page directory and page table and set page #### directory base register. # Create page directory at 64 kB and fill with zeroes. - mov ax, 0x1000 - mov es, ax - sub eax, eax - sub edi, edi - mov ecx, 0x400 - rep stosd + mov $0x1000, %ax + mov %ax, %es + subl %eax, %eax + subl %edi, %edi + movl $0x400, %ecx + rep stosl # Add PDEs to point to PTEs for the first 64 MB of RAM. # Also add identical PDEs starting at LOADER_PHYS_BASE. -# See [IA32-v3] section 3.7.6 for a description of the bits in eax. - - mov eax, 0x11007 - mov ecx, 0x11 - sub edi, edi -1: mov es:[di], eax - mov es:LOADER_PHYS_BASE / 1024 / 1024[di], eax - add di, 4 - add eax, 0x1000 +# See [IA32-v3a] section 3.7.6 "Page-Directory and Page-Table Entries" +# for a description of the bits in %eax. + + + movl $0x11007, %eax + movl $0x11, %ecx + subl %edi, %edi +1: movl %eax, %es:(%di) + movl %eax, %es:LOADER_PHYS_BASE >> 20(%di) + addw $4, %di + addl $0x1000, %eax loop 1b # Set up one-to-map linear to physical map for the first 64 MB of RAM. -# See [IA32-v3] section 3.7.6 for a description of the bits in eax. - - mov ax, 0x1100 - mov es, ax - mov eax, 0x7 - mov ecx, 0x4000 - sub edi, edi -1: mov es:[di], eax - add di, 4 - add eax, 0x1000 +# See [IA32-v3a] section 3.7.6 "Page-Directory and Page-Table Entries" +# for a description of the bits in %eax. + + movw $0x1100, %ax + movw %ax, %es + movl $0x7, %eax + movl $0x4000, %ecx + subl %edi, %edi +1: movl %eax, %es:(%di) + addw $4, %di + addl $0x1000, %eax loop 1b # Set page directory base register. - mov eax, 0x10000 - mov cr3, eax + movl $0x10000, %eax + movl %eax, %cr3 #### Switch to protected mode. -# First we turn off interrupts because we don't set up an IDT. - - cli +# Note that interrupts are still off. -# Then we point the GDTR to our GDT. Protected mode requires a GDT. +# Point the GDTR to our GDT. Protected mode requires a GDT. # We need a data32 prefix to ensure that all 32 bits of the GDT # descriptor are loaded (default is to load only 24 bits). @@ -187,18 +188,18 @@ start: # EM (Emulation): forces floating-point instructions to trap. # We don't support floating point. - mov eax, cr0 - or eax, CR0_PE + CR0_PG + CR0_WP + CR0_EM - mov cr0, eax + movl %cr0, %eax + orl $CR0_PE | CR0_PG | CR0_WP | CR0_EM, %eax + movl %eax, %cr0 # We're now in protected mode in a 16-bit segment. The CPU still has -# the real-mode code segment cached in cs's segment descriptor. We -# need to reload cs, and the easiest way is to use a far jump. +# the real-mode code segment cached in %cs's segment descriptor. We +# need to reload %cs, and the easiest way is to use a far jump. # Because we're not in a 32-bit segment the data32 prefix is needed to # jump to a 32-bit offset. - data32 ljmp SEL_KCSEG, 1f + LOADER_PHYS_BASE - + data32 ljmp $SEL_KCSEG, $1f + LOADER_PHYS_BASE + # We're now in protected mode in a 32-bit segment. .code32 @@ -206,83 +207,83 @@ start: # Reload all the other segment registers and the stack pointer to # point into our new GDT. -1: mov ax, SEL_KDSEG - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - mov esp, LOADER_PHYS_BASE + 0x30000 +1: movw $SEL_KDSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + movl $LOADER_PHYS_BASE + 0x30000, %esp #### Load kernel starting at physical address LOADER_KERN_BASE by #### frobbing the IDE controller directly. - mov ebx, 1 - mov edi, LOADER_KERN_BASE + LOADER_PHYS_BASE + movl $1, %ebx + movl $LOADER_KERN_BASE + LOADER_PHYS_BASE, %edi read_sector: # Poll status register while controller busy. - mov edx, 0x1f7 -1: in al, dx - test al, 0x80 + movl $0x1f7, %edx +1: inb %dx, %al + testb $0x80, %al jnz 1b # Read a single sector. - mov edx, 0x1f2 - mov al, 1 - out dx, al + movl $0x1f2, %edx + movb $1, %al + outb %al, %dx # Sector number to write in low 28 bits. # LBA mode, device 0 in top 4 bits. - mov eax, ebx - and eax, 0x0fffffff - or eax, 0xe0000000 + movl %ebx, %eax + andl $0x0fffffff, %eax + orl $0xe0000000, %eax -# Dump eax to ports 0x1f3...0x1f6. +# Dump %eax to ports 0x1f3...0x1f6. - mov ecx, 4 -1: inc dx - out dx, al - shr eax, 8 + movl $4, %ecx +1: incw %dx + outb %al, %dx + shrl $8, %eax loop 1b # READ command to command register. - inc dx - mov al, 0x20 - out dx, al + incw %dx + movb $0x20, %al + outb %al, %dx # Poll status register while controller busy. -1: in al, dx - test al, 0x80 +1: inb %dx, %al + testb $0x80, %al jnz 1b # Poll status register until data ready. -1: in al, dx - test al, 0x08 +1: inb %dx, %al + testb $0x08, %al jz 1b # Transfer sector. - mov ecx, 256 - mov edx, 0x1f0 + movl $256, %ecx + movl $0x1f0, %edx rep insw # Next sector. - inc ebx - cmp ebx, KERNEL_LOAD_PAGES*8 + 1 + incl %ebx + cmpl $KERNEL_LOAD_PAGES*8 + 1, %ebx jnz read_sector #### Jump to kernel entry point. - mov eax, LOADER_PHYS_BASE + LOADER_KERN_BASE - call eax + movl $LOADER_PHYS_BASE + LOADER_KERN_BASE, %eax + call *%eax jmp panic #### GDT @@ -297,34 +298,39 @@ gdtdesc: .long gdt + LOADER_PHYS_BASE # address gdt #### Fatal error. -#### Print panicmsg (with help from the BIOS) and spin. +#### Print panic_message (with help from the BIOS) and spin. panic: .code16 # We only panic in real mode. - mov si, offset panicmsg - mov ah, 0xe - sub bh, bh + movw $panic_message, %si + movb $0xe, %ah + subb %bh, %bh 1: lodsb - test al, al + test %al, %al 2: jz 2b # Spin. - int 0x10 + int $0x10 jmp 1b -panicmsg: - .ascii "Loader panic!\r\n" +panic_message: + .ascii "Panic!" .byte 0 -#### Memory size in 4 kB pages. - .org LOADER_RAM_PAGES - LOADER_BASE -ram_pages: +#### Physical memory size in 4 kB pages. +#### This is initialized by the loader and read by the kernel. + .org LOADER_RAM_PGS - LOADER_BASE +ram_pgs: .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: +#### Command-line arguments and their count. +#### This is written by the `pintos' utility and read by the kernel. +#### The loader itself does not do anything with the command line. + .org LOADER_ARG_CNT - LOADER_BASE +arg_cnt: + .long 0 + .org LOADER_ARGS - LOADER_BASE +args: .fill 0x80, 1, 0 -#### Boot-sector signature for BIOS inspection. - .org LOADER_BIOS_SIG - LOADER_BASE +#### Boot-sector signature. +#### The BIOS checks that this is set properly. + .org LOADER_SIG - LOADER_BASE .word 0xaa55