Octocontrabass wrote: ↑Fri Apr 04, 2025 8:45 pm
It might be an issue if you're loading stage2 directly into one of the buffers stage1 uses to keep track of what it's loading.
Yea but, to my understanding, it shouldn't be an issue this "early". I say this because my "disk_read" function (which is just an abstraction for calling the BIOS to load memory for us) can load up to 128 sectors in a single call meaning that we'd need to be exceeding 65KB in size and we're at 1.4 (according to Windows).
I don't think I fully understand your point about the buffers though, in this implementation only a single buffer is used and it's one that starts at 0x7E00 and we have no definitive end for it.
Octocontrabass wrote: ↑Fri Apr 04, 2025 8:45 pm
This is because your disassembler assumes a 32-bit ELF contains 32-bit code. If you disassemble it as 16-bit code, it will match your source code.
Ah yea this makes sense, already found the the flag for it, thanks.
Octocontrabass wrote: ↑Fri Apr 04, 2025 8:45 pm
How is that supposed to work? Won't your FDC driver depend on the rest of the kernel to handle IRQs and DMA, since those might be shared with other devices? And won't you have to include a whole bunch of different drivers for all the different devices that might be hiding behind INT 0x13?
Well normally I'd say yes but I'm going the polling only route, since it's the bootloader there isn't anything else to do like in a multitasking enviroment and I'd just need to call Init and Read. I have considered adding interrupts to the bootloader so that the drivers could also them but for some reason that doesn't really appeal to me and I
think it's possible to do it this way. If I do find out that being stubborn is costing me the project I'll add interrupts and maybe even a "specialized" driver just for the bootloader, this move of borrowing the driver from the kernel was to prevent me from having duplicate code in my project
Octocontrabass wrote: ↑Fri Apr 04, 2025 8:45 pm
Have you tried setting a breakpoint on the call to FdcInit and stepping through the following code to see where it stops working correctly?
Well technically no, but that's because I can't get that far with GDB, I've left a screenshot in the attachments, and you can see that after instruction 0x7c42 we jump to 0x5606 which sounds very very invalid. After this involuntary jump we get "stuck" in the 0x5000's. Now I was investigating why this may be happening and I did the following:
Code: Select all
objdump -b binary -m i8086 -D build/bootloader/bin/stage1_FAT12.bin
and I got the following disassembly for the stage1 of the bootloader (posting it all here)
Code: Select all
build/bootloader/bin/stage1_FAT12.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: eb 3c jmp 0x3e
2: 90 nop
3: 47 inc %di
4: 45 inc %bp
5: 43 inc %bx
6: 4b dec %bx
7: 4f dec %di
8: 53 push %bx
9: 20 20 and %ah,(%bx,%si)
b: 00 02 add %al,(%bp,%si)
d: 01 01 add %ax,(%bx,%di)
f: 00 02 add %al,(%bp,%si)
11: e0 00 loopne 0x13
13: 40 inc %ax
14: 0b f0 or %ax,%si
16: 09 00 or %ax,(%bx,%si)
18: 12 00 adc (%bx,%si),%al
1a: 02 00 add (%bx,%si),%al
...
24: 00 00 add %al,(%bx,%si)
26: 29 12 sub %dx,(%bp,%si)
28: 34 56 xor $0x56,%al
2a: 78 47 js 0x73
2c: 45 inc %bp
2d: 43 inc %bx
2e: 4b dec %bx
2f: 4f dec %di
30: 53 push %bx
31: 20 20 and %ah,(%bx,%si)
33: 20 20 and %ah,(%bx,%si)
35: 20 46 41 and %al,0x41(%bp)
38: 54 push %sp
39: 31 32 xor %si,(%bp,%si)
3b: 20 20 and %ah,(%bx,%si)
3d: 20 b4 00 b0 and %dh,-0x5000(%si)
41: 03 cd add %bp,%cx
43: 10 fa adc %bh,%dl
45: fc cld
46: 31 c0 xor %ax,%ax
48: 89 c3 mov %ax,%bx
4a: 89 c1 mov %ax,%cx
4c: 89 c2 mov %ax,%dx
4e: 8e c0 mov %ax,%es
50: 8e d0 mov %ax,%ss
52: bc 00 7c mov $0x7c00,%sp
55: e9 96 00 jmp 0xee
58: fa cli
59: f4 hlt
5a: eb fe jmp 0x5a
5c: 56 push %si
5d: 50 push %ax
5e: 53 push %bx
5f: ac lods %ds:(%si),%al
60: 08 c0 or %al,%al
62: 74 08 je 0x6c
64: b4 0e mov $0xe,%ah
66: b7 00 mov $0x0,%bh
68: cd 10 int $0x10
6a: eb f3 jmp 0x5f
6c: 5b pop %bx
6d: 58 pop %ax
6e: 5e pop %si
6f: c3 ret
70: 50 push %ax
71: 53 push %bx
72: 51 push %cx
73: 52 push %dx
74: 57 push %di
75: 51 push %cx
76: e8 28 00 call 0xa1
79: 58 pop %ax
7a: b4 02 mov $0x2,%ah
7c: bf 03 00 mov $0x3,%di
7f: 60 pusha
80: f9 stc
81: cd 13 int $0x13
83: 73 0b jae 0x90
85: 61 popa
86: e8 0e 00 call 0x97
89: 4f dec %di
8a: 85 ff test %di,%di
8c: 75 f1 jne 0x7f
8e: eb 30 jmp 0xc0
90: 61 popa
91: 5f pop %di
92: 5a pop %dx
93: 59 pop %cx
94: 5b pop %bx
95: 58 pop %ax
96: c3 ret
97: 60 pusha
98: b4 00 mov $0x0,%ah
9a: f9 stc
9b: cd 13 int $0x13
9d: 72 21 jb 0xc0
9f: 61 popa
a0: c3 ret
a1: 50 push %ax
a2: 52 push %dx
a3: 31 d2 xor %dx,%dx
a5: f7 36 18 7c divw 0x7c18
a9: 42 inc %dx
aa: 89 d1 mov %dx,%cx
ac: 31 d2 xor %dx,%dx
ae: f7 36 1a 7c divw 0x7c1a
b2: 88 d6 mov %dl,%dh
b4: 88 c5 mov %al,%ch
b6: c0 e4 06 shl $0x6,%ah
b9: 08 e1 or %ah,%cl
bb: 58 pop %ax
bc: 88 c2 mov %al,%dl
be: 58 pop %ax
bf: c3 ret
c0: be ca 7c mov $0x7cca,%si
c3: e8 96 ff call 0x5c
c6: eb fe jmp 0xc6
c8: fa cli
c9: f4 hlt
ca: 45 inc %bp
cb: 52 push %dx
cc: 52 push %dx
cd: 4f dec %di
ce: 52 push %dx
cf: 20 2d and %ch,(%di)
d1: 20 46 41 and %al,0x41(%bp)
d4: 49 dec %cx
d5: 4c dec %sp
d6: 45 inc %bp
d7: 44 inc %sp
d8: 20 54 4f and %dl,0x4f(%si)
db: 20 52 45 and %dl,0x45(%bp,%si)
de: 41 inc %cx
df: 44 inc %sp
e0: 20 46 52 and %al,0x52(%bp)
e3: 4f dec %di
e4: 4d dec %bp
e5: 20 46 4c and %al,0x4c(%bp)
e8: 4f dec %di
e9: 50 push %ax
ea: 50 push %ax
eb: 59 pop %cx
ec: 0d 0a a1 or $0xa10a,%ax
ef: 16 push %ss
f0: 7c 8a jl 0x7c
f2: 1e push %ds
f3: 10 7c 30 adc %bh,0x30(%si)
f6: ff f7 push %di
f8: e3 03 jcxz 0xfd
fa: 06 push %es
fb: 0e push %cs
fc: 7c 50 jl 0x14e
fe: a1 11 7c mov 0x7c11,%ax
101: c1 e0 05 shl $0x5,%ax
104: 31 d2 xor %dx,%dx
106: f7 36 0b 7c divw 0x7c0b
10a: 85 d2 test %dx,%dx
10c: 74 01 je 0x10f
10e: 40 inc %ax
10f: 88 c1 mov %al,%cl
111: 58 pop %ax
112: 8a 16 24 7c mov 0x7c24,%dl
116: bb 00 7e mov $0x7e00,%bx
119: e8 54 ff call 0x70
11c: 31 db xor %bx,%bx
11e: bf 00 7e mov $0x7e00,%di
121: be b4 7d mov $0x7db4,%si
124: b9 0b 00 mov $0xb,%cx
127: 57 push %di
128: f3 a6 repz cmpsb %es:(%di),%ds:(%si)
12a: 5f pop %di
12b: 74 0c je 0x139
12d: 83 c7 20 add $0x20,%di
130: 43 inc %bx
131: 3b 1e 11 7c cmp 0x7c11,%bx
135: 7c ea jl 0x121
137: eb 71 jmp 0x1aa
139: 8b 45 1a mov 0x1a(%di),%ax
13c: a3 de 7d mov %ax,0x7dde
13f: a1 0e 7c mov 0x7c0e,%ax
142: bb 00 7e mov $0x7e00,%bx
145: 8a 0e 16 7c mov 0x7c16,%cl
149: 8a 16 24 7c mov 0x7c24,%dl
14d: e8 20 ff call 0x70
150: bb 00 00 mov $0x0,%bx
153: 8e c3 mov %bx,%es
155: bb 00 7e mov $0x7e00,%bx
158: a1 de 7d mov 0x7dde,%ax
15b: 83 c0 1f add $0x1f,%ax
15e: b1 01 mov $0x1,%cl
160: 8a 16 24 7c mov 0x7c24,%dl
164: e8 09 ff call 0x70
167: 03 1e 0b 7c add 0x7c0b,%bx
16b: a1 de 7d mov 0x7dde,%ax
16e: b9 03 00 mov $0x3,%cx
171: f7 e1 mul %cx
173: b9 02 00 mov $0x2,%cx
176: f7 f1 div %cx
178: be 00 7e mov $0x7e00,%si
17b: 01 c6 add %ax,%si
17d: 3e 8b 04 mov %ds:(%si),%ax
180: 09 d2 or %dx,%dx
182: 74 05 je 0x189
184: c1 e8 04 shr $0x4,%ax
187: eb 03 jmp 0x18c
189: 25 ff 0f and $0xfff,%ax
18c: 3d ff 00 cmp $0xff,%ax
18f: 73 05 jae 0x196
191: a3 de 7d mov %ax,0x7dde
194: eb c2 jmp 0x158
196: 8a 16 24 7c mov 0x7c24,%dl
19a: b8 00 00 mov $0x0,%ax
19d: 8e d8 mov %ax,%ds
19f: 8e c0 mov %ax,%es
1a1: ea 00 7e 00 00 ljmp $0x0,$0x7e00
1a6: fa cli
1a7: f4 hlt
1a8: eb fe jmp 0x1a8
1aa: be bf 7d mov $0x7dbf,%si
1ad: e8 ac fe call 0x5c
1b0: fa cli
1b1: f4 hlt
1b2: eb fe jmp 0x1b2
1b4: 53 push %bx
1b5: 54 push %sp
1b6: 41 inc %cx
1b7: 47 inc %di
1b8: 45 inc %bp
1b9: 32 20 xor (%bx,%si),%ah
1bb: 20 42 49 and %al,0x49(%bp,%si)
1be: 4e dec %si
1bf: 45 inc %bp
1c0: 52 push %dx
1c1: 52 push %dx
1c2: 4f dec %di
1c3: 52 push %dx
1c4: 20 2d and %ch,(%di)
1c6: 20 53 54 and %dl,0x54(%bp,%di)
1c9: 41 inc %cx
1ca: 47 inc %di
1cb: 45 inc %bp
1cc: 32 2e 42 49 xor 0x4942,%ch
1d0: 4e dec %si
1d1: 20 4e 4f and %cl,0x4f(%bp)
1d4: 54 push %sp
1d5: 20 46 4f and %al,0x4f(%bp)
1d8: 55 push %bp
1d9: 4e dec %si
1da: 44 inc %sp
1db: 2e 0d 0a 00 cs or $0xa,%ax
...
1fb: 00 00 add %al,(%bx,%si)
1fd: 00 55 aa add %dl,-0x56(%di)
Right at the beginning we have a jump to 0x3e which doesn't match any instruction... Is the objdump correctly done from my side? Or did I screw up something in the command? From the screenshot we can see that it in fact does jump to 0x7c3e which could explain the weird behavior but I'm not sure why adding more code to an unrelated (at build time) part of the code is breaking things...
This whole behavior is very weird specially since this isn't the instruction QEMU.log said was the last to be ran...
I'll definitely keep looking more into this.
Octocontrabass wrote: ↑Fri Apr 04, 2025 8:45 pm
Your stage2 linker script is missing the appropriate wildcards. Wildcards are especially important when you use -ffunction-sections and/or -fdata-sections.
Ok, I'm going to read up on those and see how they can help me out here.
Octocontrabass wrote: ↑Fri Apr 04, 2025 8:45 pm
You don't need -mno-red-zone for 32-bit code. You probably do need -mgeneral-regs-only.
Alright I'll make that switch, thanks for the reply
