9515278e9bc5103d7bfbea8ce57262dba23a6030
[reactos.git] / reactos / boot / freeldr / bootsect / isombr.S
1 /*
2 * PROJECT: ReactOS MBR Boot Sector for ISO file system ("isohybrid mode")
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
4 * COPYRIGHT: Copyright 2017 Colin Finck <colin@reactos.org>
5 */
6
7 #include <asm.inc>
8
9 .code16
10
11 // The "isohybrid" tool patching our ISO will write the LBA of the El Torito BIOS Boot Sector to this address.
12 pBootSectorLBA = start+432
13
14 // Our BIOS Boot Sector contains this signature at the specified position and our third-party imported "isohybrid" patching tool checks for it.
15 // This is also why it's the same signature ISOLINUX uses.
16 HybridSignature = HEX(7078C0FB)
17 pBootSectorHybridSignature = HEX(7C00)+64
18 pBootSectorHybridEntryPoint = HEX(7C00)+64+4
19
20 start:
21 // The MBR needs to start with 33h, because some dumb BIOSes check for that (cf. syslinux commit d0f275981c9289dc4b8df64e72cd9902bf85aebe).
22 // The following line encodes a "xor ax, ax" (but it's not the only way to encode it, so we can't just write that instruction here).
23 .byte HEX(33), HEX(C0)
24
25 // Set up our stack and a flat addressing model.
26 cli
27 mov ss, ax
28 mov sp, offset start
29 mov ds, ax
30 mov es, ax
31 mov fs, ax
32 mov gs, ax
33 sti
34
35 // Our boot sector has been loaded to address 0x7C00.
36 // Relocate our 512 bytes boot sector to the given base address (should be 0x7000).
37 cld
38 mov cx, 512 / 4
39 mov si, HEX(7C00)
40 mov di, offset start
41 rep movsd
42
43 // Jump to the relocated code.
44 ljmp16 0, relocated
45
46 relocated:
47 // Prepare the Disk Access Packet (DAP) for INT 13h, Function 42h: Extended Read Sectors from Drive.
48 // Read 4 sectors to address 7C00h, which is exactly our 2K-sized BIOS Boot Sector.
49 push 0
50 push 0
51 push dword ptr es:[pBootSectorLBA]
52 push es
53 push HEX(7C00)
54 push 4
55 push HEX(10)
56
57 // Call the BIOS function. Note that we haven't clobbered DL up to this point, so the Drive Number passed by the BIOS is still there.
58 // Read errors are indicated by the Carry Flag.
59 mov ah, HEX(42)
60 mov si, sp
61 int HEX(13)
62 jc read_error
63
64 // Verify the Hybrid Signature.
65 cmp dword ptr es:[pBootSectorHybridSignature], HybridSignature
66 jne invalid_signature
67
68 // Signature is valid, so jump to the entry point for the hybrid code.
69 ljmp16 0, pBootSectorHybridEntryPoint
70
71 read_error:
72 call die_with_error
73 .ascii "ISOMBR: Read Error!", CR, LF
74
75 invalid_signature:
76 call die_with_error
77 .ascii "ISOMBR: Invalid Boot Sector Hybrid Signature!", CR, LF
78
79 die_with_error:
80 // Fetch the message to output stored at the return address on the stack.
81 pop si
82
83 // Call BIOS INT 10h, Function 0Eh to output a single character.
84 // Do this in a loop and stop after we have printed the newline LF character.
85 next_character:
86 lodsb
87 mov ah, HEX(0E)
88 xor bx, bx
89 int HEX(10)
90 cmp al, 10
91 jne next_character
92
93 // Die gracefully, that means in an infinite HLT loop to not put any stress on the CPU.
94 die:
95 hlt
96 jmp die
97
98 // The "isohybrid" tool will add the remaining information, including the infamous 0xAA55 MBR signature.
99 .org 431
100 .byte 0
101
102 .endcode16
103
104 END