wok view syslinux/stuff/iso2exe/bootiso.S @ rev 25682

Up libqcow (20240308)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Mar 24 18:25:46 2024 +0000 (5 weeks ago)
parents 5c1ce90eb1d6
children
line source
1 .text
2 .code16
3 .arch i8086
4 .org 0
6 CODESZ = 0x8000 // 16 sectors = 32Kb
7 #define EXEADRS(x) x+0xC0
8 #define EXELOC(x) x-0x40
9 #define EXESTR(x) x-0x7F40
11 .globl _start
12 _start:
13 decw %bp // Magic number: MZ
14 popw %dx
15 jmp start0 // Bytes on last page of file
16 .word (CODESZ+511)/512 // Pages in file
17 .word 0 // Relocations
18 .word (end_header-_start)/16 // Size of header in paragraphs
19 .word 4064-(CODESZ/16) // Minimum extra paragraphs needed
20 .word 4064-(CODESZ/16) // Maximum extra paragraphs needed
21 .word 0xFFF0 // Initial (relative) SS value
22 .word 0xFFFE // Initial SP value
23 magic:
24 .word 0 // Checksum
25 .word EXEADRS(exestart) // Initial IP value
26 .word 0xFFF0 // Initial (relative) CS value
27 initramfssize:
28 .word 0 // File address of relocation table
29 fdcnt: // Overlay number
30 .byte 0 // Bootstrap floppy sector count
31 .ascii "slitaz"
33 /////////////////////// Master Boot Record code //////////////////////////////
35 moved = 0x8000
36 start0:
37 //pushw %dx // restore %sp
38 //incw %bp // restore %bp
39 movw %ds, %ax
40 xorw %bx, %bx
41 movw %bx, %ds
42 movb $0x7C, %bh
43 pushw %ds
44 popw %ss
45 movw %bx, %sp
46 pushw %bx // return address
47 pushw %di
48 pushw %es // save %es:%di
49 pushw %si
50 cld
51 call setreg
52 rep
53 movsw
54 movw $0x80, %dx
55 ljmp $0, $moved+start2
56 .byte 0
57 // .org 60
58 // .long 0x0080 // PE header offset
59 .org 64
60 end_header:
61 comstart:
62 .word 0
64 .org 66
65 start2:
66 pushw %ax // original %ds
67 sti
68 dxloop:
69 call readsector1 // look for the boot device
70 repe
71 cmpsw
72 je dxfound
73 movb $0, %cl // ch = 0
74 addb $0x7D, %dl // try every hard disk
75 jno dxloop
77 dxfound:
78 call readsectorX // read isolinux boot sector
79 cmpw (%bx), %cx
80 movw $moved+nobsmsg, %si
81 jnc puts // read fail or no isohydrid boot sector
82 call bootpartition // assume DS=SS SI=BX=7C00 CX=0100 DL=<drive> DI=table+66
83 popw %ds
84 popw %si
85 popw %es
86 popw %di // isolinux boot needs %es:%di and %dx
87 putsret:
88 ret
90 putstrlp:
91 movw $7, %bx
92 movb $0xE, %ah
93 int $0x10
94 puts:
95 lodsb
96 cmp $0, %al
97 jnz putstrlp
98 halt:
99 hlt
100 jmp halt
101 nobsmsg:
102 .asciz "No isolinux."
104 .org 0x0080,0xEE
105 ////////////////////////////// EXE/PE header //////////////////////////////////
106 .org 0x0178,0xFF
107 ////////////////////////// partition boot code ////////////////////////////////
108 // assume DS=SS SI=BX=7C00 CX=0100 DL=<drive> DI=table+66
110 bootpartition:
111 movw $4,%cx
112 movw $16,%ax
113 next:
114 subw %ax,%di
115 cmpb %ch,-2(%di) // boot flag ?
116 loope next
117 cmpw $63,2-2(%di) // empty or isolinux partition ?
118 jbe default
119 .arch i486
120 pushl $0
121 pushl 8-2(%di)
122 pushw %cs
123 pushw %bx
124 pushw $1
125 pushw %ax
126 movw %sp,%si // assume %ds = %ss
127 movb $0x42,%ah
128 int $0x13
129 add $16,%sp
130 .arch i8086
131 default:
132 ret
134 .org 0x01A0,0xFF
135 readsectorX: // read isolinux boot sector
136 movb $3, %cl // isolinux/512
137 readsector1:
138 andb $0x83, %dl // disk and floppy disk
139 movw %cx, (%bx)
140 incw %cx
141 movw $0x201, %ax
142 int $0x13
143 setreg:
144 pushw %ds
145 popw %es
146 movw %bx, %si
147 movw $moved, %di
148 movw $0x0100, %cx
149 ret
150 .org 0x01B8,0xEE // partition table
152 .org 0x0270,0xFF
154 ////////////////////////////// DOS EXE code ///////////////////////////////////
156 cmdline:
157 .ds.b 128,0
158 linldofs: // offset of linld.com in iso
159 .long 0 // Updated by iso2exe
160 linldsz: // size-1
161 .word 0 // Updated by iso2exe
162 exestart:
163 movb $0x30,%ah // get DOS version
164 int $0x21
165 cmpb $3,%al
166 jc abort
168 // load linld.com
170 cld
171 linldbuf = 0x8000
172 isopath = 0x7000
173 movw $0x8000,%cx // clear 8000-FFFF
174 movw %cx,%di
175 movb %cl,%al
176 rep
177 stosb
179 movw %di,%ax
180 movw 0x2C(%di),%es
181 decw %cx
182 scalp:
183 repne
184 scasb
185 scasb
186 jne scalp
187 scasw // %es:%di = programme pathname
188 pushw %es
189 pushw %cs
190 popw %es
191 popw %ds
192 #define CONONICALIZE_FILENAME insert obsolute path
193 #ifdef CONONICALIZE_FILENAME
194 movw %di,%si // %ds:%si = programme pathname
195 movw $EXEADRS(isopath),%di // to filename %es:%di
196 movb $0x60,%ah // canonicalize filename
197 int $0x21
198 pushw %es
199 popw %ds
200 #endif
201 movw %di,%si // %ds:%si = programme pathname
202 #define LONG_FILENAME
203 #ifdef LONG_FILENAME
204 pushw %si
205 movw $0x716C,%ax
206 xorw %bx,%bx // R/O
207 xorw %cx,%cx // attributes
208 cwd // action = open
209 stc
210 int $0x21
211 jnc opened
212 popw %dx
213 #else
214 movw %si,%dx
215 #endif
216 pushw %si
217 movw $0x3D00,%ax
218 // movb $0,%cl
219 int $0x21
220 jc popNabort
221 opened:
222 xchgw %ax,%bx // fd = %bx
223 movw $32,%cx
224 movw $EXEADRS(headbuf),%dx
225 movb $0x3F,%ah
226 int $0x21 // read(%bx,%dx,%cx)
227 jc popNabort
228 les EXEADRS(linldofs),%dx
229 movw %es,%cx
230 movw $0x4200,%ax // lseek(%bx,%cx:%dx,SEEK_SET)
231 int $0x21
232 jc popNabort
233 movw EXEADRS(linldsz),%cx
234 jcxz popNabort
235 movw $EXEADRS(linldbuf),%dx
236 movw %cx,%di
237 addw %dx,%di
238 movb $0x3F,%ah
239 int $0x21 // read(%bx,%dx,%cx)
240 jnc copycmdline
241 popNabort:
242 popw %si
243 abort:
244 movw $EXEADRS(stopmsg),%dx
245 movb $9,%ah
246 int $0x21
247 int $0x20
249 // installed args (ex: image=/boot/bzImage initrd=rootfs4.gz,! autologin rdinit=/init.exe)
251 copycmdline:
252 pushw %ds
253 popw %es
254 movw $EXEADRS(cmdline),%si
255 movw %di,%bx
257 copylp:
258 lodsb
259 stosb
260 orb %al,%al
261 jnz copylp
263 // magic=<magic> arg
265 decw %di
266 movw $7,%cx
267 movw $EXEADRS(magicstr),%si
268 rep
269 movsb
270 movw EXEADRS(headbuf+18),%ax // magic
271 movw $10,%bp
272 magiclp1:
273 xorw %dx,%dx
274 divw %bp
275 pushw %dx
276 incw %cx
277 orw %ax,%ax
278 jnz magiclp1
279 magiclp2:
280 popw %ax
281 addb $'0',%al
282 stosb // store magic
283 loop magiclp2
285 // iso=<file> arg
287 movb $5,%cl
288 //movw $EXEADRS(isostr),%si
289 rep
290 movsb
291 popw %si
292 isolp:
293 lodsb
294 stosb
295 orb %al,%al
296 jne isolp
297 decw %di
299 // append user args
301 movw $0x80,%si
302 lodsb
303 movb $0xFF,-1(%si) // long cmdline flag
304 cbw
305 xchgw %ax,%cx
306 rep
307 movsb
308 movb $0,(%di)
310 // set cmdline size
312 movw %di,%ax
313 subw %bx,%ax
314 incw %ax
315 movb %al,-1(%bx)
317 // run linld.com
319 movw $EXEADRS(mvNjump),%si
320 incw %di
321 movb $endmvNjump-mvNjump,%cl
322 mvNjump:
323 pushw %di
324 rep
325 movsb
326 movw $EXEADRS(linldbuf),%si
327 movw $0x0100,%di
328 popw %cx
329 pushw %cx
330 subw %si,%cx
331 ret
332 endmvNjump:
334 magicstr: .ascii " magic="
335 isostr: .ascii " iso="
337 .org 0x0400,0xEE
338 headbuf:
339 .org 0x0600,0xFF
340 isolinux:
342 .arch i486
343 #define PARTITION_SUPPORT
344 /* -----------------------------------------------------------------------
345 *
346 * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
347 * Copyright 2009 Intel Corporation; author: H. Peter Anvin
348 *
349 * Permission is hereby granted, free of charge, to any person
350 * obtaining a copy of this software and associated documentation
351 * files (the "Software"), to deal in the Software without
352 * restriction, including without limitation the rights to use,
353 * copy, modify, merge, publish, distribute, sublicense, and/or
354 * sell copies of the Software, and to permit persons to whom
355 * the Software is furnished to do so, subject to the following
356 * conditions:
357 *
358 * The above copyright notice and this permission notice shall
359 * be included in all copies or substantial portions of the Software.
360 *
361 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
362 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
363 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
364 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
365 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
366 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
367 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
368 * OTHER DEALINGS IN THE SOFTWARE.
369 *
370 * ----------------------------------------------------------------------- */
372 HYBRID_MAGIC = 0x7078c0fb
373 isolinux_start_hybrid = 0x7c00+64+4
375 isolinux_hybrid_signature = 64
377 stack = 0x7c00
378 ebios_flag = (stack-20)
380 BIOS_page = 0x462
382 _start2:
383 .byte 0x33, 0xed /* xorw %bp, %bp */
385 /* Check to see if we have a partition table entry */
386 #ifdef PARTITION_SUPPORT
387 xorl %ebx, %ebx
388 xorl %ecx, %ecx
389 andw %si, %si /* %si == 0 -> no partition data */
390 jz 1f
391 testb $0x7f, (%si) /* Invalid active flag field? */
392 jnz 1f
393 orb 4(%si), %cl /* Partition type zero == invalid? */
394 je 1f
396 cmpb $0xed, %cl /* EFI partition type? */
398 /* Get non-GPT partition information */
399 movl 8(%si), %ecx
401 jne 1f
402 cmpl $0x58504721, %eax /* !GPT signature in EAX? */
403 jne 1f
405 /* We have GPT partition information */
406 movl (32+20)(%si), %ecx
407 movl (36+20)(%si), %ebx
408 #endif
409 1:
410 movw %bp, %ds
411 movw $stack, %sp
413 /* We have no partition information */
414 #ifdef PARTITION_SUPPORT
415 pushl %ebx /* -4: partoffset_hi */
416 pushl %ecx /* -8: partoffset_lo */
417 #else
418 pushl $0 /* -4: partoffset_hi */
419 pushl $0 /* -8: partoffset_lo */
420 #endif
421 partoffset = -8
422 pushw %es /* -10: es:di -> $PnP header */
423 pushw %di /* -12: es:di -> $PnP header */
426 //ADJUST_DRIVE
427 pushw %dx /* -14: dl -> drive number */
428 driveno = -14
430 pushw %ds
431 popw %es
433 /* Copy down to 0:0x600 */
434 movw $2f-0x600+0x7C00, %si
435 movw $2f, %di
436 movb $(512 >> 8), %ch
437 pushw %es
438 pushw %di
439 rep; movsb
441 retf
442 2:
444 /* Check to see if we have EBIOS */
445 pushw %dx /* drive number */
446 movb $0x41, %ah /* %al == 0 already */
447 movw $0x55aa, %bx
448 //xorw %cx, %cx
449 xorb %dh, %dh
450 int $0x13
451 andw $1,%cx /* Bit 0 = fixed disk subset */
452 jz 1f
453 decw %cx /* Clear EBIOS flag. */
454 cmpw $0xaa55, %bx
455 jne 1f
456 incw %cx /* Set EBIOS flag. */
458 /* We have EBIOS; patch in the following code at
459 read_sector_cbios: movb $0x42, %ah ; jmp read_common */
460 movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
461 (read_sector_cbios)
462 1:
463 popw %dx
464 pushw %cx /* EBIOS flag */
466 /* Get (C)HS geometry */
467 movb $0x08, %ah
468 int $0x13
469 popw %bx /* EBIOS flag */
470 movzbw %dh, %ax /* dh = max head */
471 incw %ax /* From 0-based max to count */
472 pushw %ax /* -16: Save heads on the stack */
473 heads = -16
474 andw $0x3f, %cx /* Sector count */
475 pushw %cx /* -18: Save sectors on the stack */
476 sectors = -18
477 mulw %cx /* Heads*sectors -> sectors per cylinder */
479 pushw %bx /* -20: EBIOS flag */
481 /* Save sectors/cylinder in %esi */
482 pushw %dx
483 pushw %ax
484 popl %edi
486 /*
487 * Load sectors. We do this one at a time mostly to avoid
488 * pitfalls and to share code with the stock MBR code.
489 */
490 movw $0x7c00, %bx
491 movw %bx, %bp
492 xorl %eax, %eax
493 cdq
494 movb $17*4, %al /* EL TORITO spec */
495 call read_sector
496 movl 71(%bx), %eax /* catalog */
497 shll $2, %eax
498 call read_sector
499 movl 40(%bx), %eax /* boot code */
500 shll $2, %eax
501 movb $4, %cl /* Sector count */
503 2:
504 call read_sector
505 incl %eax
506 addb $(512 >> 8), %bh
507 loopw 2b
509 /*
510 * Okay, that actually worked... update the stack pointer
511 * and jump into isolinux.bin...
512 */
513 cmpl $HYBRID_MAGIC,isolinux_hybrid_signature(%bp)
514 jne error_os
516 cli
517 //movw $ebios_flag, %sp
519 /*
520 * Use a ljmpw here to work around a bug in some unknown version
521 * of gas or ld when it comes to jumping to an absolute symbol...
522 *
523 * Look more closely into it if we ever are short on space.
524 */
525 //ljmpw $0, $isolinux_start_hybrid
526 pushw $isolinux_start_hybrid
527 ret
529 /*
530 * read_sector: read a single sector pointed to by %eax to %es:%bx.
531 * All registers saved.
532 */
533 read_sector:
534 pushal
535 #ifdef PARTITION_SUPPORT
536 addl partoffset(%bp), %eax
537 adcl partoffset+4(%bp), %edx
538 #endif
539 pushl %edx /* MSW of LBA */
540 pushl %eax /* LSW of LBA */
541 pushw %es /* Buffer segment */
542 pushw %bx /* Buffer offset */
543 pushw $1 /* Sector count */
544 pushw $16 /* Size of packet */
545 movw %sp, %si
547 /* This chunk is skipped if we have ebios */
548 /* Do not clobber %eax before this chunk! */
549 /* This also relies on %bx and %edx as set up above. */
550 read_sector_cbios:
551 divl %edi
552 shlb $6, %ah
553 xchgb %al, %ah
554 xchgw %ax, %cx
555 xchgw %dx, %ax
556 divb sectors(%bp)
557 movb %al, %dh
558 orb %ah, %cl
559 incw %cx /* Sectors are 1-based */
560 movw $0x0201, %ax
562 read_common:
563 movb driveno(%bp), %dl
564 int $0x13
565 movw $disk_error, %si
566 jc error
567 addw $16, %sp /* Drop DAPA */
568 popal
569 ret
571 /*
572 * Print error messages. This is invoked with "call", with the
573 * error message at the return address.
574 */
575 error_os:
576 movw $bad_signature, %si
577 error:
578 lodsb
579 movb $0x0e, %ah
580 movb (BIOS_page), %bh
581 movb $0x07, %bl
582 int $0x10 /* May destroy %bp */
583 cmpb $10, %al /* Newline? */
584 jne error
586 int $0x18 /* Boot failure */
587 die:
588 hlt
589 jmp die
591 bad_signature:
592 .ascii "isolinux.bin "
593 .ascii "missing or corrupt.\r\n"
594 disk_error:
595 .ascii "Operating system "
596 .ascii "load error.\r\n"
598 .org 0x0750,0xBB
599 stopmsg:
600 .ascii "This program cannot be run in DOS mode.$"
601 .org 0x0778,0xEE
603 .macro apple_partition count=2, start=1, size=2, name, namesz, type, typesz, start_data, size_data, status
604 .byte 0x50, 0x4D, 0, 0 /* PM */
605 #define BE(x) (((x)>>24)|((((x)>>16)&255)<<8)|((((x)>>8)&255)<<16)|(((x)&255)<<24))
606 .long BE(\count)
607 .long BE(\start)
608 .long BE(\size)
609 .ascii "\name"
610 .ds.b 32-\namesz, 0
611 .ascii "\type"
612 .ds.b 32-\typesz, 0
613 .long BE(\start_data)
614 .long BE(\size_data)
615 .long BE(\status)
616 .ds.b 44,0 /* boot code & processor info */
617 .endm
619 .org 0x800,0
620 apple_partition 2, 1, 2, "Apple", 5, "Apple_partition_map", 19, 0, 2, 3 /* valid, allocated */
621 .org 0x1000,0
622 apple_partition 2, 1, 2, "EFI", 3, "Apple_HFS", 9, 0, 0, 0x40000013 /* valid, allocated, readable, automatically mount at startup */
624 .end