Start work on partition support.
[pintos-anon] / src / threads / loader.S
1 /* This file is derived from source code used in MIT's 6.828
2    course.  The original copyright notice is reproduced in full
3    below. */
4
5 /*
6  * Copyright (C) 1997 Massachusetts Institute of Technology 
7  *
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:
12  *
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.
18  *
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
26  * DOCUMENTATION.
27  *
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.
34  *
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.
39  */
40
41 #include "threads/loader.h"
42         
43         .intel_syntax noprefix
44         
45 #### Kernel loader.
46
47 #### This code should be stored in the first sector of the hard disk.
48 #### When the BIOS runs, it loads this code at physical address
49 #### 0x7c00-0x7e00 (512 bytes).  Then it jumps to the beginning of it,
50 #### in real mode.  This code switches into protected mode (32-bit
51 #### mode) so that all of memory can accessed, loads the kernel into
52 #### memory, and jumps to the first byte of the kernel, where start.S
53 #### is linked.
54         
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. */
60
61 # Code runs in real mode, which is a 16-bit segment.
62
63 .globl start
64 start:
65         .code16
66
67 # Set up segment registers.
68 # Stack grows downward starting from us.
69
70         sub ax, ax
71         mov ds, ax
72         mov ss, ax
73         mov sp, 0x7c00
74         
75 # Scan floppy disks.
76
77         sub dl, dl
78         sub ebx, ebx
79         mov eax, 0x7e00
80         mov es, ax
81 1:      call scan_partitions
82         inc dl
83         jnc 1b
84
85 # Scan hard disks.
86         mov dl, 0x80
87 1:      call scan_partitions
88         inc dl
89         jnc 1b
90
91         call panic
92         .asciz "No boot partition"
93
94 scan_partitions:
95         # EBX = sector number of partition table
96         # DL = drive number
97         # ES:0000 -> buffer for partition table
98         # Returns CF set if drive exists, CF clear otherwise.
99         call read_sector
100         jnc no_such_drive
101 2:      cmp word ptr [es:510], 0xaa55
102         jnz no_boot_partition
103         
104         mov si, 446
105 1:      mov al, [es:si+4]
106         cmp al, 0x20
107         jz found_boot_partition
108         cmp al, 0x05
109         jz found_extended_partition
110         cmp al, 0x0f
111         jz found_extended_partition
112         cmp al, 0x85
113         jz found_extended_partition
114         cmp al, 0xc5
115         jz found_extended_partition
116 next_parttbl_entry:     
117         add si, 16
118         cmp si, 510
119         jb 1b
120
121 no_boot_partition:      
122         clc
123         ret
124 no_such_drive:
125         stc
126         ret
127
128 found_extended_partition:
129         # DL = drive number.
130         # ES:SI -> partition table entry for extended partition.
131         # Recursively examine it.
132         pusha
133         mov ebx, es:[si+8]
134         mov ax, es
135         add ax, 0x20
136         mov es, ax
137         call scan_partitions
138         popa
139         jmp next_parttbl_entry
140
141 found_boot_partition:
142         mov ebx, [es:si+8]              # EBX = first sector
143         mov cx, [es:si+12]              # CX = number of sectors
144         mov ax, 0x1000                  # ES:0000 -> load address
145         mov es, ax
146 1:      call read_sector
147         add ax, 0x20
148         mov es, ax
149         loop 1b
150
151         ljmp 0x1000, 0
152
153         # ebx: sector number
154         # dl: drive number
155         # es:0000: destination buffer
156         # returns error flag in CF
157 read_sector:
158         pusha
159         or dl, dl                       # Floppy drives: DL < 0
160         js read_floppy_sector
161
162 read_harddrv_sector:
163         sub eax, eax
164         push eax                        # LBA sector number [32:63]
165         push ebx                        # LBA sector number [0:31]
166         mov ax, es
167         shl eax, 4
168         push eax                        # Buffer linear address
169         push 1                          # Transfer one sector
170         push 16                         # Packet size
171         mov ah, 0x42                    # Extended read
172         mov si, sp                      # DS:SI -> packet
173         int 0x13                        # Error code in CF
174 success:        
175         popa
176         ret                             # Error code in CF
177
178 read_floppy_sector:
179         #define HEADS 2
180         #define SECTORS 36
181
182         # In: BX = LBA sector number, DL = drive.
183         # Out: BL = drive, DX = cylinder, AL = head, AH = sector.
184         sub ax, ax
185         xchg dx, bx                     # DX = LBA sector number, BL = drive
186         mov cx, HEADS * SECTORS
187         div cx                          # AX = cyl, DX = hd + (sec-1) * SECTORS
188         xchg ax, dx                     # DX = cyl, AX = hd + (sec-1) * SECTORS
189         mov cl, SECTORS
190         div cl                          # AL = head, AH = sector - 1
191         inc ah
192
193         # Read sector.
194         mov ch, dl                      # CH = cylinder
195         mov cl, ah                      # CL = sector
196         mov dh, al                      # DH = head
197         mov dl, bl                      # DL = drive
198         mov ax, 0x0201                  # AH = function, AL = sectors to read
199         sub bx, bx                      # ES:BX -> buffer
200         pusha
201         int 0x13
202         popa
203         jnc success
204
205         # Reset floppy drive motor, try again.
206         sub ah, ah
207         int 0x13
208         popa
209         jmp read_sector
210         
211 #### The partition table goes here.
212         .org 446
213 part_tbl:       
214
215 #### Boot-sector signature for BIOS inspection.
216         .org 510
217         .word 0xaa55