Slightly more flexible packman.
[minix3.git] / boot / jumpboot.s
blob6e758821e49f73657eb1eeedab32ccade19a9700
1 ! jumpboot 1.0 - Jump to another bootstrap Author: Kees J. Bot
2 ! 14 Apr 1999
4 ! This code may be placed into any free boot sector, like the first sector
5 ! of an extended partition, a file system partition other than the root,
6 ! or even the master bootstrap. It will load and run another bootstrap whose
7 ! disk, partition, and slice number (not necessarily all three) are patched
8 ! into this code by installboot. If the ALT key is held down when this code
9 ! is booted then you can type the disk, partition, and slice numbers manually.
10 ! The manual interface is default if no numbers are patched in by installboot.
13 o32 = 0x66 ! This assembler doesn't know 386 extensions
14 LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
15 BUFFER = 0x0600 ! First free memory
16 PART_TABLE = 446 ! Location of partition table within master
17 PENTRYSIZE = 16 ! Size of one partition table entry
18 MAGIC = 510 ! Location of the AA55 magic number
20 ! <ibm/partition.h>:
21 MINIX_PART = 0x81
22 sysind = 4
23 lowsec = 8
26 .text
28 ! Find and load another bootstrap and jump to it.
29 jumpboot:
30 xor ax, ax
31 mov ds, ax
32 mov es, ax
33 cli
34 mov ss, ax ! ds = es = ss = Vector segment
35 mov sp, #LOADOFF
36 sti
38 ! Move this code to safety, then jump to it.
39 mov si, sp ! si = start of this code
40 mov di, #BUFFER ! di = Buffer area
41 mov cx, #512/2 ! One sector
42 cld
43 rep movs
44 jmpf BUFFER+migrate, 0 ! To safety
45 migrate:
47 mov bp, #BUFFER+guide ! Patched guiding characters
48 altkey:
49 movb ah, #0x02 ! Keyboard shift status
50 int 0x16
51 testb al, #0x08 ! Bit 3 = ALT key
52 jz noalt ! ALT key pressed?
53 again:
54 mov bp, #zero ! Ignore patched stuff
55 noalt:
57 ! Follow guide characters to find the boot partition.
58 call print
59 .ascii "d?\b\0" ! Initial greeting
61 ! Disk number?
62 disk:
63 movb dl, #0x80 - 0x30 ! Prepare to add an ASCII digit
64 call getch ! Get number to tell which disk
65 addb dl, al ! dl = 0x80 + (al - '0')
66 jns n0nboot ! Result should be >= 0x80
67 mov si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
68 cmpb (bp), #0x23 ! Next guide character is '#'?
69 jne notlogical
70 lea si, 1-lowsec(bp) ! Logical sector offset follows '#'
71 notlogical:
72 call load ! Load chosen sector of chosen disk
73 cmpb (bp), #0x23
74 je boot ! Run bootstrap if a logical is chosen
76 call print ! Intro to partition number
77 .ascii "p?\b\0"
79 part:
80 call getch ! Get character to tell partition
81 call gettable ! Get partition table
82 call sort ! Sort partition table
83 call choose_load ! Compute chosen entry and load
85 cmpb sysind(si), #MINIX_PART ! Minix subpartition table possible?
86 jne waitboot
88 call print ! Intro to slice number
89 .ascii "s?\b\0"
91 slice:
92 call getch ! Get character to tell slice
93 call gettable ! Get partition table
94 call choose_load ! Compute chosen entry and load
96 waitboot:
97 call print ! Intro to nothing
98 .ascii " ?\b\0"
99 call getch ! Supposed to type RETURN now
100 n0nboot:jmp nonboot ! Sorry, can't go further
102 ! Get a character, either the patched-in, or one from the keyboard.
103 getch:
104 movb al, (bp) ! Get patched-in character
105 testb al, al
106 jz getkey
107 inc bp
108 jmp gotkey
109 getkey: xorb ah, ah ! Wait for keypress
110 int 0x16
111 gotkey: testb dl, dl ! Ignore CR if disk number not yet set
112 jns putch
113 cmpb al, #0x0D ! Carriage return?
114 je boot
115 !jmp putch
117 ! Print a character
118 putch: movb ah, #0x0E ! Print character in teletype mode
119 mov bx, #0x0001 ! Page 0, foreground color
120 int 0x10
123 ! Print a message.
124 print: mov cx, si ! Save si
125 pop si ! si = String following 'call print'
126 prnext: lodsb ! al = *si++ is char to be printed
127 testb al, al ! Null marks end
128 jz prdone
129 call putch
130 jmp prnext
131 prdone: xchg si, cx ! Restore si
132 jmp (cx) ! Continue after the string
134 ! Return typed (or in patched data) means to run the bootstrap now in core!
135 boot:
136 call print ! Make line on screen look proper
137 .ascii "\b \r\n\0"
138 jmp LOADOFF-BUFFER ! Jump to LOADOFF
140 ! Compute address of chosen partition entry from choice al into si, then
141 ! continue to load the boot sector of that partition.
142 choose_load:
143 subb al, #0x30 ! al -= '0'
144 cmpb al, #4 ! Only four partitions
145 ja n0nboot
146 movb ah, #PENTRYSIZE
147 mulb ah ! al *= PENTRYSIZE
148 add ax, #BUFFER+PART_TABLE
149 mov si, ax ! si = &part_table[al - '0']
150 movb al, sysind(si) ! System indicator
151 testb al, al ! Unused partition?
152 jz n0nboot
153 !jmp load ! Continue to load boot sector
155 ! Load boot sector of the current partition.
156 load:
157 push dx ! Save drive code
158 push es ! Next call sets es
159 movb ah, #0x08 ! Code for drive parameters
160 int 0x13
161 pop es
162 andb cl, #0x3F ! cl = max sector number (1-origin)
163 incb dh ! dh = 1 + max head number (0-origin)
164 movb al, cl ! al = cl = sectors per track
165 mulb dh ! dh = heads, ax = heads * sectors
166 mov bx, ax ! bx = sectors per cylinder = heads * sectors
167 mov ax, lowsec+0(si)
168 mov dx, lowsec+2(si) ! dx:ax = sector within drive
169 cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
170 jae bigdisk
171 div bx ! ax = cylinder, dx = sector within cylinder
172 xchg ax, dx ! ax = sector within cylinder, dx = cylinder
173 movb ch, dl ! ch = low 8 bits of cylinder
174 divb cl ! al = head, ah = sector (0-origin)
175 xorb dl, dl ! About to shift bits 8-9 of cylinder into dl
176 shr dx, #1
177 shr dx, #1 ! dl[6..7] = high cylinder
178 orb dl, ah ! dl[0..5] = sector (0-origin)
179 movb cl, dl ! cl[0..5] = sector, cl[6..7] = high cyl
180 incb cl ! cl[0..5] = sector (1-origin)
181 pop dx ! Restore drive code in dl
182 movb dh, al ! dh = al = head
183 mov bx, #LOADOFF ! es:bx = where sector is loaded
184 mov ax, #0x0201 ! ah = Code for read / al = one sector
185 int 0x13
186 jmp rdeval ! Evaluate read result
187 bigdisk:
188 mov bx, dx ! bx:ax = dx:ax = sector to read
189 pop dx ! Restore drive code in dl
190 push si ! Save si
191 mov si, #BUFFER+ext_rw ! si = extended read/write parameter packet
192 mov 8(si), ax ! Starting block number = bx:ax
193 mov 10(si), bx
194 movb ah, #0x42 ! Extended read
195 int 0x13
196 pop si ! Restore si to point to partition entry
197 !jmp rdeval
198 rdeval:
199 jnc rdok
200 rderr:
201 call print
202 .ascii "\r\nRead error\r\n\0"
203 jmp again
204 rdok:
205 cmp LOADOFF+MAGIC, #0xAA55
206 je sigok ! Signature ok?
207 nonboot:
208 call print
209 .ascii "\r\nNot bootable\r\n\0"
210 jmp again
211 sigok:
214 ! Get the partition table into my space.
215 gettable:
216 mov si, #LOADOFF+PART_TABLE
217 mov di, #BUFFER+PART_TABLE
218 mov cx, #4*PENTRYSIZE/2
219 rep movs
222 ! Sort the partition table.
223 sort:
224 mov cx, #4 ! Four times is enough to sort
225 bubble: mov si, #BUFFER+PART_TABLE ! First table entry
226 bubble1:lea di, PENTRYSIZE(si) ! Next entry
227 cmpb sysind(si), ch ! Partition type, nonzero when in use
228 jz exchg ! Unused entries sort to the end
229 inuse: mov bx, lowsec+0(di)
230 sub bx, lowsec+0(si) ! Compute di->lowsec - si->lowsec
231 mov bx, lowsec+2(di)
232 sbb bx, lowsec+2(si)
233 jae order ! In order if si->lowsec <= di->lowsec
234 exchg: movb bl, (si)
235 xchgb bl, PENTRYSIZE(si) ! Exchange entries byte by byte
236 movb (si), bl
237 inc si
238 cmp si, di
239 jb exchg
240 order: mov si, di
241 cmp si, #BUFFER+PART_TABLE+3*PENTRYSIZE
242 jb bubble1
243 loop bubble
246 .data
248 ! Extended read/write commands require a parameter packet.
249 ext_rw:
250 .data1 0x10 ! Length of extended r/w packet
251 .data1 0 ! Reserved
252 .data2 1 ! Blocks to transfer (just one)
253 .data2 LOADOFF ! Buffer address offset
254 .data2 0 ! Buffer address segment
255 .data4 0 ! Starting block number low 32 bits (tbfi)
256 zero: .data4 0 ! Starting block number high 32 bits
258 .align 2
259 guide:
260 ! Guide characters and possibly a logical partition number patched here by
261 ! installboot, up to 6 bytes maximum.