source: trunk/AIR-BOOT/SOURCE/SPECIAL/LINUX.ASM@ 8

Last change on this file since 8 was 8, checked in by kiewitz, 23 years ago

Added AiR-BOOT Images and support for other languages.
Note: This comment was created after rebuilding the repo. [2011-07]

File size: 17.7 KB
Line 
1
2; Disclaimer:
3;=============
4; The sourcecode is released via www.netlabs.org CVS *ONLY*.
5; You MUST NOT upload it to other servers nor republish it in any way.
6; The sourcecode is still COPYRIGHTED and NOT YET RELEASED UNDER GPL.
7; It's (c) Copyright 1998-2002 by Martin Kiewitz.
8; You may recompile the source and do *PRIVATE* modifications, but please keep
9; in mind that modifying this code needs at least *some* assembly skill. If
10; you mess up your system, because you needed to hack your way through, don't
11; blame me. Releasing a customized version of AiR-BOOT, selling it in any form
12; or reusing parts of this source is *PROHIBITED*. Ask me, if you have some
13; idea about new functionality *before* developing the code, otherwise I will
14; definitely reject it. Also please accept, that I have some basic design
15; rules on AiR-BOOT and I will maintain them at all costs, so this won't get
16; another GRUB.
17
18;---------------------------------------------------------------------------
19; AiR-BOOT / LINUX SUPPORT
20;---------------------------------------------------------------------------
21
22; Here is the startup-code for Linux-Kernels. I'm sure this won't work on
23; all of them, but on the latest.
24
25; Note: This code will ONLY WORK on computers with INT 13h Extension.
26; I did not want to code silly cylinder stuff here and if you don't
27; have INT 13h Extensions, you will not need this. LINUXIMG won't work
28; without them.
29;
30; And another note: *Fuck* Linux usenet-users. Really. I mean *fuck them*.
31; I asked in an OS/2 newsgroup for testers -> Got 8 volunteers within some
32; days. I asked in 2 Linux newsgroups. What did happen? Some idiots discussed
33; the whole shiat with me, knew nothing about INT13h CHS/LBA mode, BIOS,
34; boot-managers in general, assembly coding and other stuff and wanted to tell
35; me that 95k GRUB is well-coded and its good to have it placed all over your
36; harddrive and that file-support and all those lousy features would waste
37; sooo much space. ROFLMAO.
38;
39; I could implement some more file-systems into AiR-BOOT, but instead I did
40; some nice menus, setup, text, cyrillic support, demo-coder effects, easy
41; handling, help, auto-detection and plenty of other stuff INTO AROUND 25k.
42;
43; Oh, why is this code here? Because of 2 friends of mine. Otherwise I wouldnt
44; have done it as well as fat16.asm.
45
46Linux_TranslateBase db '/dev/hd'
47Linux_KernelDirectory db 'KERNELS '
48
49; Translates partition-number to Linux-device name (e.g. /dev/hda3)
50; In: DL - partition number, ES:DI - destination 9-byte buffer
51; Out: (buffer filled)
52; Destroyed: None
53LINUX_TranslateToDEV Proc Near Uses eax ebx cx dx ds si
54 ; Damn Linux. Our logic is as follows: first get the drive letter.
55 ; that's easy. Now search our partition-table for new
56 ; extended partitions and fix them up. Stupid logic.
57 push cs
58 pop ds ; CS == DS
59 mov si, offset Linux_TranslateBase
60 mov cx, 7
61 rep movsb ; First write base-name (/dev/hd)...
62 ; First get our partition-table
63 call PART_GetPartitionPointer ; Partition (DL) -> CS:SI
64 mov dl, ds:[si+LocIPT_Drive]
65 mov al, dl
66 sub al, 1Fh ; Generate letter from drive (80h -> 61h)
67 stosb ; write letter
68
69 ; Now get the linux local partition number
70 ; 1. Search for partition, where TranslateDrive (DL) got used first
71 mov cx, si ; CX - Searched partition offset
72 mov si, offset PartitionTable ; begin here
73 LTTD_SearchDriveLoop:
74 cmp ds:[si+LocIPT_Drive], dl
75 je LTTD_SearchDrive_Found
76 add si, LocIPT_LenOfIPT
77 jmp LTTD_SearchDriveLoop
78 LTTD_SearchDrive_Found:
79 ; Now count all partitions to hit. After root partition set counter to
80 ; 4 and count further.
81 xor dh, dh ; Linux Partition Counter (Base 0)
82 LTTD_SearchPart_Loop:
83 inc dh ; Increase Linux Local Partition Number
84 mov ax, wptr ds:[si+LocIPT_AbsolutePartTable+2]
85 shr eax, 16
86 mov ax, wptr ds:[si+LocIPT_AbsolutePartTable+0] ; -> EAX
87 cmp dh, 4 ; over root partition yet ?
88 ja LTTD_ContinueLoop ; yes, continue loop
89 cmp eax, 0 ; not in root partition anymore?
90 je LTTD_ContinueLoop
91 mov dh, 5 ; nope, so adjust counter
92 LTTD_ContinueLoop:
93 cmp si, cx
94 je LTTD_SearchPart_Found
95 add si, LocIPT_LenOfIPT ; Next Partition
96 jmp LTTD_SearchPart_Loop
97
98 LTTD_SearchPart_Found:
99 or eax, eax
100 jnz LTTD_SearchPart_NotRootPartition
101 ; Bullshit, it's in the MBR, so we have to look for the
102 ; partition number directly (because EXTEND, EXT2: EXT2 would be
103 ; partition 1, in fact it would be partition 2)
104 ; All we do here is to load the MBR to memory (suck) and look in it
105 ; manually. Pervertly this could be crazy, when user
106 ; is in setup and changing 'Linux Root'.
107 mov ax, wptr ds:[si+LocIPT_AbsoluteBegin+2]
108 shr eax, 16
109 mov ax, wptr ds:[si+LocIPT_AbsoluteBegin+0] ; -> EAX
110 push eax
111 xor ax, ax
112 xor bx, bx
113 mov cx, 1
114 xor dh, dh
115 mov si, offset TmpSector
116 call DriveIO_LoadSector ; Load fucking MBR
117 pop eax
118 xor dh, dh ; Reset again to zero
119 add si, 446
120 LTTD_SearchRoot_Loop:
121 cmp bptr ds:[si+4], 0
122 je LTTD_SearchRoot_NoPart ; if partition...
123 inc dh ; add one
124 LTTD_SearchRoot_NoPart:
125 mov bx, wptr ds:[si+10]
126 shr ebx, 16
127 mov bx, wptr ds:[si+08] ; -> EBX (Start Sector)
128 add si, 16
129 cmp eax, ebx
130 jne LTTD_SearchRoot_Loop
131
132 LTTD_SearchPart_NotRootPartition:
133 mov al, dh
134 ; Now convert that crap (AL) to ascii and write it
135 cmp al, 10
136 jb LTTD_Smaller10
137 xor ah, ah
138 mov dl, 10
139 div dl
140 add al, 30h ; Generate number from value 00h -> 30h)
141 stosb
142 mov al, ah
143 LTTD_Smaller10:
144 add al, 30h ; Generate number from value
145 stosb
146 ret
147LINUX_TranslateToDEV EndP
148
149LINUX_InitFAT16access Proc Near Uses es
150 mov dl, ds:[CFG_LinuxKrnlPartition]
151 call PART_GetPartitionPointer ; Partition DL -> SI
152 call FAT16_InitAccess
153
154 call FAT16_ReadRoot
155
156 mov cx, FAT16_NumOfRootEntries
157 mov si, offset Linux_KernelDirectory
158 call FAT16_SearchEntry ; Fills up DX as Cluster-No
159 or dx, dx
160 jz LIFAT16A_NoDirectory
161
162 mov ax, 9000h
163 mov es, ax
164 xor di, di ; Read Cluster DX to 9000:0 (ES:DI)
165 call FAT16_ReadCluster
166 mov ax, cs
167 mov es, ax ; DS == ES == CS
168 call FAT16_ProcessKrnlDirectory
169
170 LIFAT16A_NoDirectory:
171 ret
172LINUX_InitFAT16access EndP
173
174; Initialize FAT-16 access on specified partition (required for following xs)
175; In: DS:SI - 11-Byte Kernel Name to search
176; Out: DL - FFh - if not found, otherwise the entry no is replied
177; Destroyed: None
178LINUX_SearchKernelName Proc Near Uses cx di
179 mov dl, 0FFh ; Nothing found is default...
180 mov cl, LINUX_KernelNo
181 or cl, cl
182 jz LSKN_NotFound
183 mov di, offset LINUX_KernelEntries
184 add di, LocIPT_Name
185 LSKN_SearchLoop:
186 push cx si di
187 mov cx, 11
188 repe cmpsb ; Compare total 11-bytes
189 pop di si cx
190 je LSKN_Found
191 add di, LocIPT_LenOfIPT
192 dec cl
193 jnz LSKN_SearchLoop
194 jmp LSKN_NotFound
195
196 LSKN_Found:
197 mov si, di
198 sub si, LocIPT_Name ; Back to Base-Pointer
199 call PART_GetPartitionNumber ; Get Number of Entry at [SI]
200 LSKN_NotFound:
201 ret
202LINUX_SearchKernelName EndP
203
204Linux_FuzzyString db 'Linux Boot - Alpha', 13, 10, 0
205Linux_GotBadKernel db ' - Bad Kernel/Bad FAT-16 partition', 0
206Linux_INT15error db ' - INT 15 error', 0
207Linux_RootDefine db 'root='
208
209LINUX_LoadKernel Proc Near Uses ; Direct Jump, No Preserves
210 ; TranslateToDev needs UNFILTERED Partition Pointers...
211 call PART_CalculateStraightPartPointers
212 push si
213 mov si, offset Linux_FuzzyString
214 call MBR_Teletype
215 pop si
216 ; DX - Starting-Cluster of Linux Kernel File
217 mov dx, ds:[si+LocIPT_LocationBegin]
218 ; from now on, we don't need si anymore
219
220 ; Linux has 1 'BR' (which is crap) and some setup sectors
221 ; we load them at 9000:0, what a luck, we are at 8000:0 :-))
222 push ds es
223 mov ax, 9000h
224 mov es, ax
225 xor di, di
226 call FAT16_ReadCluster ; Load First Cluster (DX) to 9000:0
227 mov cl, bptr es:[01F1h] ; Setup sectors to load
228 inc cl ; Total sectors to load to 9000:0
229 jmp LLL_CheckLeft
230
231 LLL_LoadSetupCodeLoop:
232 call FAT16_ReadCluster
233 LLL_CheckLeft:
234 sub cl, FAT16_SecsPerCluster
235 jz LLL_GotAllClusterDone
236 jc LLL_GotAllClusterNotEmpty
237 jmp LLL_LoadSetupCodeLoop
238
239 LLL_GotAllClusterDone:
240 xor cx, cx
241 jmp LLL_GotAll
242 LLL_GotAllClusterNotEmpty:
243 ; Damn, Cluster didn't got empty. So we have to copy the rest out...
244 xor ch, ch
245 not cl
246 inc cl ; 0FFh -> 1 sector to get...
247 ; Now copy rest to 6000:0 location for later processing...
248 ; ES:DI - Ending location of Setup Code
249 mov ax, 9000h
250 mov ds, ax
251 mov ax, 6000h
252 mov es, ax
253 push cx si ; Push Kernel-Entry-Pointer
254 mov si, di
255 shl cx, 9 ; Sectors to Byte Count
256 sub si, cx ; DS:SI - Begin of Kernel Data
257 xor di, di
258 shr cx, 1
259 rep movsw ; Copy Data...
260 pop si cx ; Get Kernel-Entry-Pointer back
261 LLL_GotAll:
262 pop es ds
263
264 push cx dx ; Push Missing-Sectors, StartCluster
265 mov ax, 9000h
266 mov ds, ax
267
268 ; Check Signatures for security...
269 cmp wptr ds:[1FEh], 0AA55h
270 jne LLL_BadKernel
271 cmp wptr ds:[202h], 'dH'
272 jne LLL_BadKernel
273 cmp wptr ds:[204h], 'Sr'
274 je LLL_GoodKernel
275 LLL_BadKernel:
276 push es
277 pop ds
278 mov si, offset Linux_GotBadKernel
279 call MBR_Teletype
280 jmp MBR_HaltSystem
281 LLL_GoodKernel:
282
283 ; Now we have at least some of the required sectors loaded
284 mov ax, 9000h
285 mov dx, ax
286 mov al, bptr ds:[01F1h] ; Setup Sectors to load
287 ; -> to 9020:0
288
289 ; Just append parameters to end of Linux boot-block...
290 xor ah, ah
291 mov bl, 20h
292 mul bl ; AX * 20
293 add dx, ax ; add to segment -> Segment of Parameters
294
295 mov wptr ds:[0020h], 0A33Fh
296 mov ax, dx
297 and ax, 0FFFh ; 9100h -> 0100h
298 shl ax, 4 ; 0100h -> 1000h
299 mov wptr ds:[0022h], ax ; offset of parameter relative 9000:0
300
301 ; fill out Linux-Loader byte, so SETUP will do its job
302 mov bptr ds:[0210h], 0A0h ; AiR-BOOT (unknown ID for Linux btw)
303 mov cx, wptr ds:[01F4h] ; Linux Kernel Length in 16-byte blocks
304 shr cx, 5
305 inc cx ; Convert to Sector-Count
306 push cx
307 push cs
308 pop ds ; CS == DS
309 mov es, dx ; ES = Segment for parameters
310 xor di, di ; ES:0 - Parameter Ptr
311 mov dl, cs:[CFG_LinuxRootPartition]
312 cmp dl, 0FFh
313 je LLL_NoRootPartitionFound
314 mov cx, 5
315 mov si, offset Linux_RootDefine
316 rep movsb ; root=
317 call LINUX_TranslateToDEV ; Writes DEV (dl) at ES:DI (/dev/hda9)
318
319 LLL_NoRootPartitionFound:
320 ; Root-Define complete, now for the user Kernel Command-Line...
321 mov si, offset CFG_LinuxCommandLine
322 mov al, ds:[si]
323 or al, al
324 jz LLL_CommandLineLoop
325 mov al, ' '
326 stosb ; If any command-line, insert space
327 LLL_CommandLineLoop:
328 lodsb
329 stosb ; Copy string till and including NUL
330 or al, al
331 jnz LLL_CommandLineLoop
332 stosb ; Write another NUL
333 pop cx
334 pop dx bx ; Pop StartCluster, Missing-Sectors
335 ; CX - Sector-Count of Kernel Image, DX - Starting Cluster of Kernel Image
336 ; BX - Sector-Count left over in 6000:0 area from Setup Code loading
337 ; DS == CS
338
339 ; Now comes some tricky part. Hopefully we have a tiny kernel.
340 ; If we have a big kernel, we have to 'upload' it to PM-memory space.
341 test bptr ds:[0211h], 01h
342 jz LLL_LoadNormalKernel
343 jmp LLL_LoadBigKernel
344
345 LLL_LoadNormalKernel:
346 ; NORMAL KERNEL
347
348 ; Still UNSUPPORTED. This suxxs
349
350 LLL_LoadBigKernel:
351 ; BIG KERNEL - Oh no, we have to load all data to extended memory...
352 mov ax, 6000h
353 mov es, ax
354 shr ax, 4
355 ; Set Source to 06:0000
356 mov bptr cs:[MBR_Linux_GDT_Src+0], al
357 mov wptr cs:[MBR_Linux_GDT_Src+1], ax
358 xor si, si
359 or bx, bx ; No unfinished Cluster ?
360 jz LLL_LoadBigKernelLoop
361 push cx
362 mov cx, bx
363 shl cx, 8 ; Sectors to WORD Count
364 call LINUX_MoveKernelPart ; Copy Data to Extended Memory
365 pop cx
366 LLL_LoadBigKernelLoop:
367 push cx
368 ; DX - Current Cluster
369 ; CX - Total WORDs that need to be loaded
370 ; ES - Segment
371 mov cx, 8000h
372 call LINUX_LoadDataToMemory
373 ; CX - Total WORDs that were loaded...
374 ; Got 6000:0 filled...
375 call LINUX_MoveKernelPart
376 shr cx, 8 ; WORDs to SEGMENTs
377 add si, cx
378 pop cx
379 cmp si, cx
380 jb LLL_LoadBigKernelLoop
381
382 LLL_FinishedLoadKernel:
383 ; either way, we give execution to setup at 9020:0
384 mov ax, 09020h
385 mov ss, ax
386 mov sp, 4000h-12h ; Linux wants it this way...
387 mov ds, ax
388 mov es, ax
389 db 0EAh
390 dw 0
391 dw 09020h
392LINUX_LoadKernel EndP
393
394; Loads Data from Cluster(s) to memory...
395; In: DX - First cluster to read from...
396; CX - Total WORDs that need to be loaded at least
397; ES - Segment, where to load to (Starting Offset is zero)
398; Out: CX - Total WORDs that got loaded
399; DX - Cluster following last loaded cluster
400; (buffer filled)
401; Destroyed: None
402; MUST BE USING CS for addressing Code Segment, DS =! CS
403LINUX_LoadDataToMemory Proc Near Uses di
404 shl cx, 1 ; Convert WORDs to BYTEs
405 dec cx ; 0000h -> FFFFh
406 xor di, di
407 LLDTM_LoadLoop:
408 call FAT16_ReadCluster ; Load Cluster DX to ES:DI
409 ; DX and DI were updated by ReadCluster, so don't modify them...
410 or di, di
411 jz LLDTM_Overflow
412 cmp di, cx
413 jbe LLDTM_LoadLoop
414 mov cx, di
415 shr cx, 1
416 inc cx ; 3FFFh -> 4000h
417 ret
418 LLDTM_Overflow:
419 mov cx, 08000h
420 ret
421LINUX_LoadDataToMemory EndP
422
423; Copies Extended-Memory (clobbered from Linux setup)
424; In: CX - Total WORDs to copy
425; Out: (buffer copied)
426; Destroyed: None
427; MUST BE USING CS for addressing Code Segment, DS =! CS
428LINUX_MoveKernelPart Proc Near Uses ax cx es si
429 mov ax, cs
430 mov es, ax
431 mov si, offset MBR_Linux_GDT
432 push cx
433 mov ax, 08700h
434; IFDEF ReleaseCode
435 int 15h
436 jc LMKP_Error
437; ENDIF
438 pop cx
439 ; now adjust Destination by copied word-count
440 add wptr cs:[MBR_Linux_GDT_Dst], cx
441 adc bptr cs:[MBR_Linux_GDT_Dst+2], 0
442 add wptr cs:[MBR_Linux_GDT_Dst], cx
443 adc bptr cs:[MBR_Linux_GDT_Dst+2], 0
444 ret
445 LMKP_Error:
446 mov ax, cs
447 mov ds, ax
448 mov si, offset Linux_INT15error
449 call MBR_Teletype
450 jmp MBR_HaltSystem
451LINUX_MoveKernelPart EndP
452
453MBR_Linux_GDT: dw 0, 0, 0, 0
454 dw 0, 0, 0, 0
455 dw 0FFFFh
456MBR_Linux_GDT_Src db 0, 0, 06h ; Source is 6000:0
457 db 093h
458 dw 0
459 dw 0FFFFh
460MBR_Linux_GDT_Dst db 0, 0, 10h ; Dest is "10000:0"
461 db 093h
462 dw 0
463 dw 0, 0, 0, 0
464 dw 0, 0, 0, 0
465 dw 0
466
467;
468; Example of boot setup command under lilo prompt:
469;
470; lilo: linux root=/dev/sda2 sym53c8xx=tags:4,sync:10,debug:0x200
471;
Note: See TracBrowser for help on using the repository browser.