257 lines
16 KiB
Plaintext
257 lines
16 KiB
Plaintext
1
|
|
2 %include "bootdef.inc"
|
|
3 <1>
|
|
4 <1> %define VERSION "0.1.2" ;HOS version
|
|
5 <1>
|
|
6 <1> %define BOOT_FAT_SEG 0x07E0 ;right after boot sector
|
|
7 <1> %define BOOT_ROOT_SEG 0x0900 ;right after FAT
|
|
8 <1> %define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
|
|
9 <1> %define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
|
|
10 <1> %define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at
|
|
11 <1> %define BOOT_KERNEL_ADD 0x100000 ;final pmode kernel destination - physical
|
|
12 <1> %define BOOT_RD_ADD 0x200000 ;2mb for ram disk
|
|
13 <1>
|
|
14 <1> %define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here
|
|
15 <1>
|
|
16 <1> %define BOOT_HASRD 0x0000 ;1
|
|
17 <1> %define BOOT_VESA 0x0002 ;2 - 0 for console, otherwise VESA mode
|
|
18 <1> %define BOOT_VESA_OEM 0x0004 ;258 - null-terminated OEM identification string
|
|
19 <1> %define BOOT_VESA_VBE 0x0106 ;512 - copy of VESA VBEInfoBlock
|
|
20 <1> %define BOOT_VESA_INFO 0x0306 ;256 - copy of VESA ModeInfoBlock for selected mode
|
|
21 <1> %define BOOT_MEMENTRIES 0x040A ;4 - dword = number of memmap entries
|
|
22 <1> %define BOOT_MEMMAP 0x2000 ;? - memory map information
|
|
23 <1>
|
|
24 <1>
|
|
25 <1>
|
|
26 <1> %define BOOT_DRIVE 0x7C24 ;1 - boot drive
|
|
27 <1>
|
|
28 <1>
|
|
29
|
|
30 [bits 16]
|
|
31
|
|
32 org 0x7c00
|
|
33
|
|
34 00000000 EB3C jmp short start
|
|
35
|
|
36 ; --------------------------------------------------
|
|
37 ; data portion of the "DOS BOOT RECORD"
|
|
38 ; ----------------------------------------------------------------------
|
|
39 00000002 90 brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
|
|
40 00000003 4D53444F53352E30 brOEM DB 'MSDOS5.0' ; 0003h - OEM ID - Windows 95B
|
|
41 0000000B 0002 brBPS DW 512 ; 000Bh - Bytes per sector
|
|
42 0000000D 01 brSPC DB 1 ; 000Dh - Sector per cluster
|
|
43 0000000E 0100 brSc_b4_fat DW 1 ; 000Eh - Reserved sectors
|
|
44 00000010 02 brFATs DB 2 ; 0010h - FAT copies
|
|
45 00000011 E000 brRootEntries DW 0E0H ; 0011h - Root directory entries
|
|
46 00000013 400B brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB
|
|
47 00000015 F0 brMedia DB 240 ; 0015h - Media descriptor
|
|
48 00000016 0900 brSPF DW 9 ; 0016h - Sectors per FAT
|
|
49 00000018 1200 brSc_p_trk DW 18 ; 0018h - Sectors per head/track
|
|
50 0000001A 0200 brHPC DW 2 ; 001Ah - Heads per cylinder
|
|
51 0000001C 00000000 brSc_b4_prt DD 0 ; 001Ch - Hidden sectors
|
|
52 00000020 00000000 brSectors DD 0 ; 0020h - Total number of sectors
|
|
53 00000024 00 brDrive DB 0 ; 0024h - Physical drive no.
|
|
54 00000025 00 DB 0 ; 0025h - Reserved (FAT32)
|
|
55 00000026 29 DB 29H ; 0026h - Extended boot record sig (FAT32)
|
|
56 00000027 EA184440 brSerialNum DD 404418EAH ; 0027h - Volume serial number
|
|
57 0000002B 484F5320302E312E31- brLabel DB 'HOS 0.1.1 ' ; 002Bh - Volume label
|
|
58 00000034 2020
|
|
59 00000036 4641543132202020 brFSID DB 'FAT12 ' ; 0036h - File System ID
|
|
60 ;------------------------------------------------------------------------
|
|
61
|
|
62 start:
|
|
63 0000003E EA[4300]0000 jmp 0:jmphere ;ensure that cs=0 and ip=0x7c...
|
|
64 jmphere:
|
|
65 ;dl=drive number, save it!
|
|
66 00000043 31C0 xor ax, ax
|
|
67 00000045 8ED8 mov ds, ax
|
|
68 00000047 8816[2400] mov [brDrive], dl
|
|
69 0000004B FA cli
|
|
70 0000004C 8ED0 mov ss, ax
|
|
71 0000004E BCFE7B mov sp, 0x7Bfe ;right under boot sector
|
|
72 00000051 FB sti
|
|
73
|
|
74 00000052 B800B8 mov ax, 0xb800
|
|
75 00000055 8ED8 mov ds, ax
|
|
76 00000057 8EC0 mov es, ax
|
|
77
|
|
78 00000059 31FF xor di, di
|
|
79 0000005B B80007 mov ax, 0x0700
|
|
80 0000005E B9D007 mov cx, 2000
|
|
81 cls:
|
|
82 00000061 AB stosw
|
|
83 00000062 E2FD loop cls
|
|
84
|
|
85 enable_a20:
|
|
86 00000064 E464 in al, 0x64
|
|
87 00000066 A802 test al, 2
|
|
88 00000068 75FA jnz enable_a20
|
|
89 0000006A B0D1 mov al, 0xD1
|
|
90 0000006C E664 out 0x64, al
|
|
91 0000006E E464 ea20_2: in al, 0x64
|
|
92 00000070 83E002 and ax, byte 2
|
|
93 00000073 75F9 jnz ea20_2
|
|
94 00000075 B0DF mov al, 0xDF
|
|
95 00000077 E660 out 0x60, al
|
|
96
|
|
97 unreal:
|
|
98 00000079 31C0 xor ax, ax
|
|
99 0000007B 8EC0 mov es, ax
|
|
100 0000007D 8ED8 mov ds, ax
|
|
101
|
|
102 0000007F 0F0116[5E01] lgdt [gdtr] ;load gdt
|
|
103 00000084 FA cli
|
|
104 00000085 06 push es
|
|
105 00000086 1E push ds ;save segment values
|
|
106 00000087 0F20C3 mov ebx, cr0
|
|
107 0000008A FEC3 inc bl
|
|
108 0000008C 0F22C3 mov cr0, ebx ;pmode!
|
|
109 0000008F B80800 mov ax, KERNEL_DATA
|
|
110 00000092 8EC0 mov es, ax
|
|
111 00000094 8ED8 mov ds, ax ;load segment limits
|
|
112 00000096 FECB dec bl
|
|
113 00000098 0F22C3 mov cr0, ebx ;back to real mode!
|
|
114 0000009B 1F pop ds
|
|
115 0000009C 07 pop es ;segments back, with 4gb limits!
|
|
116 0000009D FB sti
|
|
117
|
|
118 ;now lets read in the FAT and root directory so we can search for the kernel file...
|
|
119 0000009E B80902 mov ax, 0x0209 ;FAT1
|
|
120 000000A1 B90200 mov cx, 0x0002
|
|
121 000000A4 30F6 xor dh, dh
|
|
122 000000A6 8A16[2400] mov dl, [brDrive]
|
|
123 000000AA BBE007 mov bx, BOOT_FAT_SEG
|
|
124 000000AD 8EC3 mov es, bx
|
|
125 000000AF 31DB xor bx, bx
|
|
126 000000B1 CD13 int 0x13
|
|
127
|
|
128 000000B3 B80E02 mov ax, 0x020E ;root directory
|
|
129 000000B6 B90200 mov cx, 0x0002 ;cyl/sect
|
|
130 000000B9 B601 mov dh, 0x01 ;head
|
|
131 000000BB 8A16[2400] mov dl, [brDrive] ;drive
|
|
132 000000BF BB0009 mov bx, BOOT_ROOT_SEG
|
|
133 000000C2 8EC3 mov es, bx
|
|
134 000000C4 31DB xor bx, bx
|
|
135 000000C6 CD13 int 0x13
|
|
136
|
|
137 ;k now read root directory
|
|
138 000000C8 BB0009 mov bx, BOOT_ROOT_SEG
|
|
139 000000CB 8EDB mov ds, bx
|
|
140 000000CD 31F6 xor si, si ;k now ds:si points to beginning of root directory
|
|
141 000000CF 8EC6 mov es, si
|
|
142 000000D1 B9E000 mov cx, 224 ;max root entries
|
|
143 loop_compare:
|
|
144 000000D4 BF[7401] mov di, stage2
|
|
145 000000D7 51 push cx
|
|
146 000000D8 56 push si ;save pointer to root dir entry
|
|
147 000000D9 B90B00 mov cx, 11
|
|
148 loop_name:
|
|
149 000000DC A6 cmpsb
|
|
150 000000DD E1FD loopz loop_name
|
|
151 000000DF 7505 jnz goon ;cx didn't get to zero, bad file
|
|
152 000000E1 5E pop si
|
|
153 000000E2 59 pop cx
|
|
154 000000E3 E90A00 jmp found_file ;good file, ds:si points to start of root directory entry
|
|
155 goon:
|
|
156 000000E6 5E pop si
|
|
157 000000E7 59 pop cx
|
|
158 000000E8 81C62000 add si, 32
|
|
159 000000EC E2E6 loop loop_compare
|
|
160
|
|
161 error:
|
|
162 000000EE EBFE jmp $ ;halt! no kernel file found!
|
|
163
|
|
164 found_file: ;ds:si points to root dir entry
|
|
165 000000F0 31C0 xor ax, ax
|
|
166 000000F2 8EE8 mov gs, ax
|
|
167 000000F4 B8000B mov ax, BOOT_STAGE2_SEG
|
|
168 000000F7 8EC0 mov es, ax
|
|
169
|
|
170 000000F9 3E8B441A mov ax, [ds:si+26]
|
|
171 000000FD BBE007 mov bx, BOOT_FAT_SEG
|
|
172 00000100 8EDB mov ds, bx ;ds points to beginning of FAT
|
|
173 00000102 31FF xor di, di
|
|
174
|
|
175 readstage2_loop:
|
|
176 00000104 3DF70F cmp ax, 0xff7
|
|
177 00000107 7F37 jg readstage2_done
|
|
178 00000109 47 inc di
|
|
179 0000010A 50 push ax
|
|
180 0000010B E83700 call getCHSfromCluster
|
|
181 0000010E B80102 mov ax, 0x0201
|
|
182 00000111 658A16247C mov dl, [gs:BOOT_DRIVE]
|
|
183 00000116 31DB xor bx, bx
|
|
184 00000118 CD13 int 0x13
|
|
185 0000011A 8CC3 mov bx, es
|
|
186 0000011C 81C32000 add bx, 0x0020
|
|
187 00000120 8EC3 mov es, bx
|
|
188 00000122 58 pop ax ;current logical cluster #
|
|
189
|
|
190 00000123 89C1 mov cx, ax ;cx=logical cluster
|
|
191 00000125 BA0300 mov dx, 3
|
|
192 00000128 F7E2 mul dx
|
|
193 0000012A D1E8 shr ax, 1 ;ax=logical cluster * 3 / 2
|
|
194 0000012C 89C6 mov si, ax
|
|
195 0000012E F6C101 test cl, 1 ;is bit0 set?
|
|
196 00000131 7507 jnz odd_cluster
|
|
197 even_cluster:
|
|
198 00000133 AD lodsw
|
|
199 00000134 25FF0F and ax, 0x0fff
|
|
200 00000137 E90400 jmp got_cluster
|
|
201 odd_cluster:
|
|
202 0000013A AD lodsw
|
|
203 0000013B C1E804 shr ax, 4
|
|
204 got_cluster:
|
|
205 0000013E EBC4 jmp readstage2_loop
|
|
206
|
|
207 readstage2_done:
|
|
208
|
|
209 00000140 EA00B00000 jmp 0:BOOT_STAGE2_ADD
|
|
210
|
|
211 ;------------------------------------------------------
|
|
212 getCHSfromCluster:
|
|
213 ;input: ax=lba of sector on floppy (0-2879)
|
|
214 00000145 051F00 add ax, 31 ;convert logical cluster# to lba#
|
|
215 00000148 31D2 xor dx, dx ;lba->chs
|
|
216 0000014A BB1200 mov bx, 18
|
|
217 0000014D F7F3 div bx
|
|
218 0000014F 42 inc dx
|
|
219 00000150 88D1 mov cl, dl ;sector# (1-18)
|
|
220 00000152 31D2 xor dx, dx
|
|
221 00000154 BB0200 mov bx, 2
|
|
222 00000157 F7F3 div bx
|
|
223 00000159 88C5 mov ch, al ;cylinder# (0-79)
|
|
224 0000015B 88D6 mov dh, dl ;head# (0-1)
|
|
225 0000015D C3 ret
|
|
226
|
|
227
|
|
228 ;-------------------------------------------------------
|
|
229 gdtr:
|
|
230 0000015E 0F00 dw gdt_end-gdt-1
|
|
231 00000160 [64010000] dd gdt
|
|
232 gdt:
|
|
233 00000164 00000000 dd 0
|
|
234 00000168 00000000 dd 0
|
|
235
|
|
236 KERNEL_DATA equ $-gdt
|
|
237 0000016C FF db 0xff ;segment 16 = 4gb data
|
|
238 0000016D FF db 0xff
|
|
239 0000016E 00 db 0x00
|
|
240 0000016F 00 db 0x00
|
|
241 00000170 00 db 0x00
|
|
242 00000171 92 db 0x92
|
|
243 00000172 CF db 0xcf ;cf
|
|
244 00000173 00 db 0x00
|
|
245
|
|
246 gdt_end:
|
|
247
|
|
248
|
|
249
|
|
250 00000174 535441474532202042- stage2: db "STAGE2 BIN"
|
|
251 0000017D 494E
|
|
252
|
|
253 0000017F 00<rept> times 510-($-$$) db 0
|
|
254
|
|
255 000001FE 55AA db 0x55, 0xaa
|
|
256
|