source: trunk/minix/boot/masterboot.s@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.4 KB
RevLine 
[9]1! masterboot 2.0 - Master boot block code Author: Kees J. Bot
2!
3! This code may be placed in the first sector (the boot sector) of a floppy,
4! hard disk or hard disk primary partition. There it will perform the
5! following actions at boot time:
6!
7! - If the booted device is a hard disk and one of the partitions is active
8! then the active partition is booted.
9!
10! - Otherwise the next floppy or hard disk device is booted, trying them one
11! by one.
12!
13! To make things a little clearer, the boot path might be:
14! /dev/fd0 - Floppy disk containing data, tries fd1 then d0
15! [/dev/fd1] - Drive empty
16! /dev/c0d0 - Master boot block, selects active partition 2
17! /dev/c0d0p2 - Submaster, selects active subpartition 0
18! /dev/c0d0p2s0 - Minix bootblock, reads Boot Monitor /boot
19! Minix - Started by /boot from a kernel image in /minix
20
21 LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
22 BUFFER = 0x0600 ! First free memory
23 PART_TABLE = 446 ! Location of partition table within this code
24 PENTRYSIZE = 16 ! Size of one partition table entry
25 MAGIC = 510 ! Location of the AA55 magic number
26
27 ! <ibm/partition>.h:
28 bootind = 0
29 sysind = 4
30 lowsec = 8
31
32
33.text
34
35! Find active (sub)partition, load its first sector, run it.
36
37master:
38 xor ax, ax
39 mov ds, ax
40 mov es, ax
41 cli
42 mov ss, ax ! ds = es = ss = Vector segment
43 mov sp, #LOADOFF
44 sti
45
46! Copy this code to safety, then jump to it.
47 mov si, sp ! si = start of this code
48 push si ! Also where we'll return to eventually
49 mov di, #BUFFER ! Buffer area
50 mov cx, #512/2 ! One sector
51 cld
52 rep movs
53 jmpf BUFFER+migrate, 0 ! To safety
54migrate:
55
56! Find the active partition
57findactive:
58 testb dl, dl
59 jns nextdisk ! No bootable partitions on floppies
60 mov si, #BUFFER+PART_TABLE
61find: cmpb sysind(si), #0 ! Partition type, nonzero when in use
62 jz nextpart
63 testb bootind(si), #0x80 ! Active partition flag in bit 7
64 jz nextpart ! It's not active
65loadpart:
66 call load ! Load partition bootstrap
67 jc error1 ! Not supposed to fail
68bootstrap:
69 ret ! Jump to the master bootstrap
70nextpart:
71 add si, #PENTRYSIZE
72 cmp si, #BUFFER+PART_TABLE+4*PENTRYSIZE
73 jb find
74! No active partition, tell 'em
75 call print
76 .ascii "No active partition\0"
77 jmp reboot
78
79! There are no active partitions on this drive, try the next drive.
80nextdisk:
81 incb dl ! Increment dl for the next drive
82 testb dl, dl
83 js nexthd ! Hard disk if negative
84 int 0x11 ! Get equipment configuration
85 shl ax, #1 ! Highest floppy drive # in bits 6-7
86 shl ax, #1 ! Now in bits 0-1 of ah
87 andb ah, #0x03 ! Extract bits
88 cmpb dl, ah ! Must be dl <= ah for drive to exist
89 ja nextdisk ! Otherwise try disk 0 eventually
90 call load0 ! Read the next floppy bootstrap
91 jc nextdisk ! It failed, next disk please
92 ret ! Jump to the next master bootstrap
93nexthd: call load0 ! Read the hard disk bootstrap
94error1: jc error ! No disk?
95 ret
96
97
98! Load sector 0 from the current device. It's either a floppy bootstrap or
99! a hard disk master bootstrap.
100load0:
101 mov si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
102 !jmp load
103
104! Load sector lowsec(si) from the current device. The obvious head, sector,
105! and cylinder numbers are ignored in favour of the more trustworthy absolute
106! start of partition.
107load:
108 mov di, #3 ! Three retries for floppy spinup
109retry: push dx ! Save drive code
110 push es
111 push di ! Next call destroys es and di
112 movb ah, #0x08 ! Code for drive parameters
113 int 0x13
114 pop di
115 pop es
116 andb cl, #0x3F ! cl = max sector number (1-origin)
117 incb dh ! dh = 1 + max head number (0-origin)
118 movb al, cl ! al = cl = sectors per track
119 mulb dh ! dh = heads, ax = heads * sectors
120 mov bx, ax ! bx = sectors per cylinder = heads * sectors
121 mov ax, lowsec+0(si)
122 mov dx, lowsec+2(si)! dx:ax = sector within drive
123 cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
124 jae bigdisk
125 div bx ! ax = cylinder, dx = sector within cylinder
126 xchg ax, dx ! ax = sector within cylinder, dx = cylinder
127 movb ch, dl ! ch = low 8 bits of cylinder
128 divb cl ! al = head, ah = sector (0-origin)
129 xorb dl, dl ! About to shift bits 8-9 of cylinder into dl
130 shr dx, #1
131 shr dx, #1 ! dl[6..7] = high cylinder
132 orb dl, ah ! dl[0..5] = sector (0-origin)
133 movb cl, dl ! cl[0..5] = sector, cl[6..7] = high cyl
134 incb cl ! cl[0..5] = sector (1-origin)
135 pop dx ! Restore drive code in dl
136 movb dh, al ! dh = al = head
137 mov bx, #LOADOFF ! es:bx = where sector is loaded
138 mov ax, #0x0201 ! Code for read, just one sector
139 int 0x13 ! Call the BIOS for a read
140 jmp rdeval ! Evaluate read result
141bigdisk:
142 mov bx, dx ! bx:ax = dx:ax = sector to read
143 pop dx ! Restore drive code in dl
144 push si ! Save si
145 mov si, #BUFFER+ext_rw ! si = extended read/write parameter packet
146 mov 8(si), ax ! Starting block number = bx:ax
147 mov 10(si), bx
148 movb ah, #0x42 ! Extended read
149 int 0x13
150 pop si ! Restore si to point to partition entry
151 !jmp rdeval
152rdeval:
153 jnc rdok ! Read succeeded
154 cmpb ah, #0x80 ! Disk timed out? (Floppy drive empty)
155 je rdbad
156 dec di
157 jl rdbad ! Retry count expired
158 xorb ah, ah
159 int 0x13 ! Reset
160 jnc retry ! Try again
161rdbad: stc ! Set carry flag
162 ret
163rdok: cmp LOADOFF+MAGIC, #0xAA55
164 jne nosig ! Error if signature wrong
165 ret ! Return with carry still clear
166nosig: call print
167 .ascii "Not bootable\0"
168 jmp reboot
169
170! A read error occurred, complain and hang
171error:
172 mov si, #LOADOFF+errno+1
173prnum: movb al, ah ! Error number in ah
174 andb al, #0x0F ! Low 4 bits
175 cmpb al, #10 ! A-F?
176 jb digit ! 0-9!
177 addb al, #7 ! 'A' - ':'
178digit: addb (si), al ! Modify '0' in string
179 dec si
180 movb cl, #4 ! Next 4 bits
181 shrb ah, cl
182 jnz prnum ! Again if digit > 0
183 call print
184 .ascii "Read error "
185errno: .ascii "00\0"
186 !jmp reboot
187
188reboot:
189 call print
190 .ascii ". Hit any key to reboot.\0"
191 xorb ah, ah ! Wait for keypress
192 int 0x16
193 call print
194 .ascii "\r\n\0"
195 int 0x19
196
197! Print a message.
198print: pop si ! si = String following 'call print'
199prnext: lodsb ! al = *si++ is char to be printed
200 testb al, al ! Null marks end
201 jz prdone
202 movb ah, #0x0E ! Print character in teletype mode
203 mov bx, #0x0001 ! Page 0, foreground color
204 int 0x10
205 jmp prnext
206prdone: jmp (si) ! Continue after the string
207
208.data
209
210! Extended read/write commands require a parameter packet.
211ext_rw:
212 .data1 0x10 ! Length of extended r/w packet
213 .data1 0 ! Reserved
214 .data2 1 ! Blocks to transfer (just one)
215 .data2 LOADOFF ! Buffer address offset
216 .data2 0 ! Buffer address segment
217 .data4 0 ! Starting block number low 32 bits (tbfi)
218zero: .data4 0 ! Starting block number high 32 bits
Note: See TracBrowser for help on using the repository browser.