cli
cld
-# Set up data segments and stack.
+# Set up data segments.
sub ax, ax
mov es, ax
mov ds, ax
+# Set up stack segment.
# Stack grows downward starting from us.
# We don't ever use the stack so this is strictly speaking
# unnecessary.
mov al, 0xdf
out 0x60, al
-#### Get memory size, via interrupt 15h function 88h. Returns CF
+#### Get memory size, via interrupt 15h function 88h, which 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. We cap memory at 64 MB because that's all we
mov ah, 0x88
int 0x15
jc panic
+ cli # BIOS might have enabled interrupts
add eax, 1024 # Total kB memory
cmp eax, 0x10000 # Cap at 64 MB
jbe 1f
mov eax, 0x10000
1: shr eax, 2 # Total 4 kB pages
- mov ram_pages, eax
+ mov ram_pgs, eax
#### Create temporary page directory and page table and set page
#### directory base register.
# Also add identical PDEs starting at LOADER_PHYS_BASE.
# See [IA32-v3] section 3.7.6 for a description of the bits in eax.
+# A bug in some versions of GAS prevents us from using the straightforward
+# mov es:[di + LOADER_PHYS_BASE / 1024 / 1024], eax
+# so we calculate the displacement in bx instead.
+
mov eax, 0x11007
mov ecx, 0x11
- sub edi, edi
+ sub di, di
+ mov ebx, LOADER_PHYS_BASE
+ shr ebx, 20
1: mov es:[di], eax
- mov es:LOADER_PHYS_BASE / 1024 / 1024[di], eax
+ mov es:[bx + di], eax
add di, 4
add eax, 0x1000
loop 1b
mov ax, 0x1100
mov es, ax
mov eax, 0x7
- mov ecx, 0x4000
- sub edi, edi
+ mov cx, 0x4000
+ sub di, di
1: mov es:[di], eax
add di, 4
add eax, 0x1000
#### Switch to protected mode.
-# First we turn off interrupts because we don't set up an IDT.
-
- cli
-
# Then we 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).
#### Print panicmsg (with help from the BIOS) and spin.
panic: .code16 # We only panic in real mode.
- mov si, offset panicmsg
+ mov si, offset panic_message
mov ah, 0xe
sub bh, bh
1: lodsb
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