]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/pbs.s
9boot: add e820 scan to bootloader
[plan9front.git] / sys / src / boot / pc / pbs.s
1 #include "x16.h"
2 #include "mem.h"
3
4 #define RELOC 0x7c00
5
6 TEXT _magic(SB), $0
7         BYTE $0xEB; BYTE $0x58;         /* jmp .+ 0x58  (_start0x5A) */
8         BYTE $0x90                      /* nop */
9 TEXT _version(SB), $0
10         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
11         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
12 TEXT _sectsize(SB), $0
13         BYTE $0x00; BYTE $0x00
14 TEXT _clustsize(SB), $0
15         BYTE $0x00
16 TEXT _nresrv(SB), $0
17         BYTE $0x00; BYTE $0x00
18 TEXT _nfats(SB), $0
19         BYTE $0x00
20 TEXT _rootsize(SB), $0
21         BYTE $0x00; BYTE $0x00
22 TEXT _volsize(SB), $0
23         BYTE $0x00; BYTE $0x00
24 TEXT _mediadesc(SB), $0
25         BYTE $0x00
26 TEXT _fatsize(SB), $0
27         BYTE $0x00; BYTE $0x00
28 TEXT _trksize(SB), $0
29         BYTE $0x00; BYTE $0x00
30 TEXT _nheads(SB), $0
31         BYTE $0x00; BYTE $0x00
32 TEXT _nhiddenlo(SB), $0
33         BYTE $0x00; BYTE $0x00
34 TEXT _nhiddenhi(SB), $0
35         BYTE $0x00; BYTE $0x00;
36 TEXT _bigvolsize(SB), $0
37         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
38 /* FAT32 structure, starting @0x24 */
39 TEXT _fatsz32(SB), $0
40         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
41 TEXT _extflags(SB), $0
42         BYTE $0x00; BYTE $0x00
43 TEXT _fsver(SB), $0
44         BYTE $0x00; BYTE $0x00
45 TEXT _rootclust(SB), $0
46         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
47 TEXT _fsinfo(SB), $0
48         BYTE $0x00; BYTE $0x00
49 TEXT _bkboot(SB), $0
50         BYTE $0x00; BYTE $0x00
51 TEXT _reserved0(SB), $0
52         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
53         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
54         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
55 TEXT _driveno(SB), $0
56         BYTE $0x00
57 TEXT _reserved1(SB), $0
58         BYTE $0x00
59 TEXT _bootsig(SB), $0
60         BYTE $0x00
61 TEXT _volid(SB), $0
62         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
63 TEXT _label(SB), $0
64         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
65         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
66         BYTE $0x00; BYTE $0x00; BYTE $0x00
67 TEXT _type(SB), $0
68         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
69         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
70
71 _start0x5A:
72         CLI
73         CLR(rAX)
74         MTSR(rAX, rSS)                  /* 0000 -> rSS */
75         MTSR(rAX, rDS)                  /* 0000 -> rDS, source segment */
76         MTSR(rAX, rES)
77
78         LWI(0x100, rCX)
79         LWI(RELOC, rSI)
80         MW(rSI, rSP)
81         LWI(_magic(SB), rDI)
82         CLD
83         REP; MOVSL                      /* MOV DS:[(E)SI] -> ES:[(E)DI] */
84
85         PUSHA
86         MW(rSP, rBP)
87
88         PUSHR(rCX)
89         PUSHI(start16(SB))
90         BYTE $0xCB                      /* FAR RET */
91
92 TEXT halt(SB), $0
93 _halt:
94         JMP _halt
95
96 TEXT start16(SB), $0
97         STI
98         LWI(hello(SB), rSI)
99         CALL16(print16(SB))
100         LWI(crnl(SB), rSI)
101         CALL16(print16(SB))
102         LW(_volid(SB), rAX)             /* Xrootlo */
103         LW(_volid+2(SB), rBX)           /* Xroothi */
104         PUSHR(rBP)
105         LW(_sectsize(SB), rCX)
106         SUB(rCX, rSP)
107         MW(rSP, rBP)
108         MW(rSP, rSI)
109
110 _nextsect:
111         PUSHR(rAX)
112         CALL16(readsect16(SB))
113         OR(rAX, rAX)
114         JNE _halt
115
116         LW(_sectsize(SB), rCX)
117         SHRI(5, rCX)
118
119 _nextdir:
120         PUSHR(rCX)
121         PUSHR(rSI)                      /* save for later if it matches */
122         LWI(bootname(SB), rDI)
123         LW(bootnamelen(SB), rCX)
124         CLD
125         REP
126         CMPSB
127         POPR(rSI)
128         POPR(rCX)
129         JEQ _found
130         ADDI(0x20, rSI) 
131         LOOP _nextdir
132         POPR(rAX)
133         ADDI(1, rAX)
134         ADC(rCX, rBX)
135         JMP _nextsect
136
137 _found:
138         PUSHR(rDX)
139
140         CLR(rBX)
141
142         LW(_rootsize(SB), rAX)          /* calculate and save Xrootsz */
143         LWI(0x20, rCX)
144         MUL(rCX)
145         LW(_sectsize(SB), rCX)
146         PUSHR(rCX)
147         DEC(rCX)
148         ADD(rCX, rAX)
149         ADC(rBX, rDX)
150         POPR(rCX)                       /* _sectsize(SB) */
151         DIV(rCX)
152         PUSHR(rAX)                      /* Xrootsz */
153
154         LXW(0x1a, xSI, rAX)             /* starting sector address */
155         DEC(rAX)                        /* that's just the way it is */
156         DEC(rAX)
157         LB(_clustsize(SB), rCL)
158         CLRB(rCH)
159         MUL(rCX)
160         LW(_volid(SB), rCX)             /* Xrootlo */
161         ADD(rCX, rAX)
162         LW(_volid+2(SB), rCX)           /* Xroothi */
163         ADC(rCX, rDX)
164         POPR(rCX)                       /* Xrootsz */
165         ADD(rCX, rAX)
166         ADC(rBX, rDX)
167
168         PUSHR(rAX)                      /* calculate how many sectors to read */
169         PUSHR(rDX)
170         LXW(0x1c, xSI, rAX)
171         LXW(0x1e, xSI, rDX)
172         LW(_sectsize(SB), rCX)
173         PUSHR(rCX)
174         DEC(rCX)
175         ADD(rCX, rAX)
176         ADC(rBX, rDX)
177         POPR(rCX)                       /* _sectsize(SB) */
178         DIV(rCX)
179         MW(rAX, rCX)
180         POPR(rBX)
181         POPR(rAX)
182         POPR(rDX)
183
184         LWI(RELOC, rSI)
185         PUSHR(rSI)
186
187 _loadnext:
188         PUSHR(rCX)
189         PUSHR(rAX)
190         CALL16(readsect16(SB))
191         OR(rAX, rAX)
192         JNE _loaderror
193         POPR(rAX)
194         CLR(rCX)
195         ADDI(1, rAX)
196         ADC(rCX, rBX)
197         LW(_sectsize(SB), rCX)
198         ADD(rCX, rSI)
199         POPR(rCX)
200         LOOP _loadnext
201         CLI
202         RET
203
204 _loaderror:
205         LWI(ioerror(SB), rSI)
206         CALL16(print16(SB))
207         CALL16(halt(SB))
208
209 TEXT print16(SB), $0
210         PUSHA
211         CLR(rBX)
212 _printnext:
213         LODSB
214         ORB(rAL, rAL)
215         JEQ _printret
216         LBI(0x0E, rAH)
217         BIOSCALL(0x10)
218         JMP _printnext
219 _printret:
220         POPA
221         RET
222
223 /*
224  * in:
225  *      DL drive
226  *      AX:BX lba32,
227  *      0000:SI buffer
228  */
229 TEXT readsect16(SB), $0
230         PUSHA
231         CLR(rCX)
232
233         PUSHR(rCX)              /* qword lba */
234         PUSHR(rCX)
235         PUSHR(rBX)
236         PUSHR(rAX)
237
238         PUSHR(rCX)              /* dword buffer */
239         PUSHR(rSI)
240
241         INC(rCX)
242         PUSHR(rCX)              /* word # of sectors */
243
244         PUSHI(0x0010)           /* byte reserved, byte packet size */
245
246         MW(rSP, rSI)
247         LWI(0x4200, rAX)
248         BIOSCALL(0x13)
249         JCC _readok
250         ADDI(0x10, rSP)
251         POPA
252         CLR(rAX)
253         DEC(rAX)
254         RET
255 _readok:
256         ADDI(0x10, rSP)
257         POPA
258         CLR(rAX)
259         RET
260
261 TEXT bootnamelen(SB), $0
262         WORD $8
263 TEXT bootname(SB), $0
264         BYTE $'9'; BYTE $'B'; BYTE $'O'; BYTE $'O';
265         BYTE $'T'; BYTE $'F'; BYTE $'A'; BYTE $'T';
266         BYTE $0
267
268 TEXT ioerror(SB), $0
269         BYTE $'i'; BYTE $'/'; BYTE $'o'; BYTE $'-';
270         BYTE $'e'; BYTE $'r'; BYTE $'r'; BYTE $0
271
272 TEXT hello(SB), $0
273         BYTE $'p'; BYTE $'b'; BYTE $'s'; BYTE $0
274
275 TEXT crnl(SB), $0
276         BYTE $'\r'; BYTE $'\n'; BYTE $0