Page 1 of 1

Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 7:44 am
by begin
Hi,

I´m in my 16bit bootloader. I searched (E820h) for a big memory region (above 1MB) and want to load my kernel file to that position.
I cant access this region in real mode, I know, but I dont want to, I just want to load the file.
This is my structure for the AH 42h call:

Code: Select all

.dap:
.dap_sz		db	0
.dap_zero		db	0
.dap_sread		dw	0
.dap_ptr_off	dw	0
.dap_ptr_seg	dw	0
.dap_ssec_lo	dd	0
.dap_ssec_hi	dd	0
.dap_qaddr_lo	dd	0
.dap_qaddr_hi	dd	0
I cant use the segment:offset for the address, so I want to use the 64-bit flat address.
I initialize the structure like this:

Code: Select all

.dap_sz = 0x18
.dap_sread = 1
.dap_ptr_off = 0xffff
.dap_ptr_seg = 0xffff
.dap_ssec_lo = fat32_sector_of_the_file
.dap_qaddr_lo = a_big_address
;other fields are set to 0
I´m using Bochs 2.6.6 for Windows.
The problem:
CF is cleared, 1 sector is loaded. But if I look at the destination address ("a_big_address"), nothing is loaded here.
So do I misunderstand the 64-bit-address-field of the structure?

Thanks for the help!

Edit:
I dumped the memory of bochs and searched for the loaded sector. It is loaded, but at address 0xFFEF.
I used 0x8000 (for debug) as address for the sector and I also used 0x9000. The sector is always loaded at 0xFFEF...

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:04 am
by Combuster
The relevant documentation (emphasis mine):
RBIL 13h/AH=42h wrote:10h QWORD (EDD-3.0, optional)
Chances are the BIOS actually tries to load to 0xffff:0xffff (or some interpretation thereof because that address triggers numerous edge cases of itself)

That said, BIOSes are not exactly reliable in loading above 1M in the first place, so the only truly safe option is to load below 1M and manually copy the data.


P.S.: Your edit shows it does exactly that: 0xffff:0xffff = 0x(1)0FFEF - note the truncation to 20 bits.

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:13 am
by M2004
I use following steps:

1) Enable A20 gate.
2) Enable flat real mode/unreal mode.
3) Use temporary buffer locating below 1mb.
4) Relocate each loaded chunk from the temporary buffer to it's final position (above 1mb mark).

(you should get the idea.)

Regards
M2004

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:16 am
by begin
Okay.... makes sense.
So there is no way to load a big (some MBytes) file in real mode?
Do I have to switch to PM or LM and create/use a ATA driver?

Edit:
I think "M2004" answered my question. Didnt see the post before I wrote this, thank you :)

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:19 am
by M2004
You can use flat real mode /unreal mode.

regards
M2004

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:27 am
by begin
Just to be on the safe side:
I read this http://wiki.osdev.org/Unreal_Mode.
Todo:
- enable A20 gate
- load "generic" GDT (all segments from 0 to "-1")
- Switch to huge unreal mode (big unreal isnt enough, right?)
- loop start
- load file chunk to buffer below 1MB
- copy chunk to any memory location (So can I use any address up to 2^32?)
- loop end

Does this work?
Thanks!

Edit:
I am a bit confused now. I have to switch between unreal and real mode every time I load(real mode) and relocate(unreal mode) a chunk, right?
Edit2:
Forget this, I was wrong ;)

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:44 am
by Octocontrabass
begin wrote:- load "generic" GDT (all segments from 0 to "-1")
I like to load the GDT inside a GPF handler. That way, all attempts to access data beyond 64k will automatically set up the GDT, even if the BIOS changes it back for some reason.
begin wrote:- Switch to huge unreal mode (big unreal isnt enough, right?)
"Big" unreal mode allows you to access any address up to 4GB. It will be enough. Don't use "huge" unreal mode.
begin wrote:I am a bit confused now. I have to switch between unreal and real mode every time I load(real mode) and relocate(unreal mode) a chunk, right?
No, there is no need to switch back to "regular" real mode. (However, the BIOS might do something like that, which is why I like to use the GPF handler.)

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:48 am
by begin
Thank you guys!

I think I can go on now.
Is the huge unreal mode only for executing code above the 64K limit?

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 8:56 am
by Combuster
Does this work?
Been there, done that
I like to load the GDT inside a GPF handler. That way, all attempts to access data beyond 64k will automatically set up the GDT
Or just always load the GDT and stick in protected mode for the nanoseconds it takes to copy the few sectors you just managed to load. Simple and stupid. Probably less code too. :wink:
Is the huge unreal mode only for executing code above the 64K limit?
Unreal mode doesn't quite fix the 64K limit imposed by the 16-bit instruction pointer. Not that you need it though.

Re: Extended Read (int 13h, AH 42h) above 1MB

Posted: Tue Jul 01, 2014 9:14 am
by begin
Alright guys, you saved me from hours of error debugging I think :D
Thank you so much! =D>