1 /* This file is derived from source code used in MIT's 6.828
2 course. The original copyright notice is reproduced in full
6 * Copyright (C) 1997 Massachusetts Institute of Technology
8 * This software is being provided by the copyright holders under the
9 * following license. By obtaining, using and/or copying this software,
10 * you agree that you have read, understood, and will comply with the
11 * following terms and conditions:
13 * Permission to use, copy, modify, distribute, and sell this software
14 * and its documentation for any purpose and without fee or royalty is
15 * hereby granted, provided that the full text of this NOTICE appears on
16 * ALL copies of the software and documentation or portions thereof,
17 * including modifications, that you make.
19 * THIS SOFTWARE IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO
20 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE,
21 * BUT NOT LIMITATION, COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR
22 * WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
23 * THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY
24 * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT
25 * HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE OR
28 * The name and trademarks of copyright holders may NOT be used in
29 * advertising or publicity pertaining to the software without specific,
30 * written prior permission. Title to copyright in this software and any
31 * associated documentation will at all times remain with copyright
32 * holders. See the file AUTHORS which should have accompanied this software
33 * for a list of all copyright holders.
35 * This file may be derived from previously copyrighted software. This
36 * copyright applies only to those changes made by the copyright
37 * holders listed in the AUTHORS file. The rest of this file is covered by
38 * the copyright notices, if any, listed below.
44 ##############################################################################
47 # This code should be stored in the first sector of the hard disk. When the
48 # BIOS runs, it loads this code at physical address 0x7c00-0x7e00 (512 bytes).
49 # Then it jumps to the beginning of it, in real mode.
50 # This code switches into protected mode (32-bit mode) so that all of
51 # memory can accessed, loads the kernel into memory, and jumps to the
52 # first byte of the kernel, where start.S is linked.
53 ##############################################################################
55 /* Flags in control register 0 */
56 #define CR0_PE 0x00000001 /* Protection Enable. */
57 #define CR0_EM 0x00000004 /* (Floating-point) Emulation. */
58 #define CR0_PG 0x80000000 /* Paging. */
59 #define CR0_WP 0x00010000 /* Write-Protect enable in kernel mode. */
61 .globl start # Entry point
62 start: .code16 # This runs in real mode
63 cli # Disable interrupts
66 movw %ax,%es # Address
69 movw $start,%sp # stack (grows down)
72 #### Address line 20 is tied to low when the machine boots,
73 #### obviously this a bit of a drag, such as when trying to
74 #### address memory above 1MB. This code undoes this.
76 1: inb $0x64,%al # Get status
77 testb $0x2,%al # Busy?
79 movb $0xd1,%al # Command: Write
80 outb %al,$0x64 # output port
81 2: inb $0x64,%al # Get status
82 testb $0x2,%al # Busy?
84 movb $0xdf,%al # Enable
87 #### Get memory size, via interrupt 15h function 88h.
88 #### Returns CF clear if successful, with AX = (kB of physical memory) - 1024.
89 #### This only works for memory sizes <= 65 MB, which should be fine for our purposes.
93 jc panic # Carry flag set on error
94 2: addl $1024,%eax # Total kB
95 shrl $2,%eax # Total 4 kB pages
98 #### switch from real to protected mode
99 #### The segments in GDT allow all of physical memory to be accessed.
100 #### Furthermore, the segments have base addresses of 0, so that the
101 #### segment translation is a NOP, ie. virtual addresses are identical to
102 #### their physical addresses. With this setup, it appears to this code
103 #### that it is running directly on physical memory.
105 cli # Mandatory since we dont set up an IDT
106 lgdt gdtdesc # load GDT -- mandatory in protected mode
107 movl %cr0, %eax # turn on protected mode
110 ### CPU magic: jump to relocation, flush prefetch queue, and
111 ### reload %cs Has the effect of just jmp to the next
112 ### instruction, but simultaneous loads CS with
114 ljmp $SEL_KCSEG, $protcseg
116 #### We are in protected mode in a 32-bit segment (hence the .code32)
119 movw $SEL_KDSEG, %ax # set up data segment registers
126 #### Load kernel starting at physical address LOADER_KERN_BASE by
127 #### frobbing the IDE controller directly.
130 movl $LOADER_KERN_BASE, %edi
133 ### Poll status register while controller busy.
139 ### Read a single sector.
144 ### Sector number to write in low 28 bits.
145 ### LBA mode, device 0 in top 4 bits.
147 andl $0x0fffffff, %eax
148 orl $0xe0000000, %eax
150 ### Dump %eax to ports 0x1f3...0x1f6.
157 ### READ command to command register.
162 ### Poll status register while controller busy.
167 ### Poll status register until data ready.
179 cmpl $KERNEL_LOAD_PAGES*8 + 1, %ebx
182 ##### Create temporary page directory and page table, set page
183 ##### directory pointer, and turn on paging.
184 ##### FIXME? We could use a single 4 MB page instead of 1024 4 kB pages.
186 # Create page directory at 64 kB.
190 # Fill page directory with zeroes.
195 # Set PDEs for 0 and LOADER_PHYS_BASE to point to the
197 movl $0x11000 | PG_U | PG_W | PG_P, %eax
199 movl %eax, 0x10000 | (LOADER_PHYS_BASE >> 20)
201 # Initialize page table.
202 movl $PG_U | PG_W | PG_P, %eax
208 # Turn on paging and kernel write-protect.
210 orl $CR0_PG | CR0_WP, %eax
215 ##### Turn on EM bit in CR0, forcing most floating-point instructions
216 ##### to trap. We don't support floating-point or MMX.
222 ##### Jump to kernel entry point.
224 movl $LOADER_PHYS_BASE + 0x20000, %esp
225 movl $LOADER_PHYS_BASE + LOADER_KERN_BASE, %eax
232 .quad 0x0000000000000000 # null seg
233 .quad 0x00cf9a000000ffff # code seg
234 .quad 0x00cf92000000ffff # data seg
237 .word 0x17 # sizeof (gdt) - 1
238 .long gdt # address gdt
240 ##### To panic, we print panicmsg (with help from the BIOS) and spin.
241 panic: .code16 # We only panic in real mode.
252 .ascii "Loader panic!\r\n"
255 ##### Memory size in 4 kB pages.
256 .org LOADER_RAM_PAGES - LOADER_BASE
260 ##### Command-line arguments inserted by another utility.
261 ##### The loader doesn't use these, but we note their
262 ##### location here for easy reference.
263 .org LOADER_CMD_LINE - LOADER_BASE
267 ##### Boot-sector signature for BIOS inspection.
268 .org LOADER_BIOS_SIG - LOADER_BASE