Page 1 of 3

Access more memory in Real Mode?

Posted: Sun Apr 30, 2006 4:03 pm
by Jaffe
Hi, all fellow OS developers :)

I'm making a small real mode OS, just to enhance my assembly knowledge a little... I was just wondering how I can access the extended memory while still in real mode, like for example MS-DOS does using HIMEM.SYS? What is HIMEM.SYS' "trick" to access the extended memory? Some kind of unreal mode, or what?

Thanks for any answers!

Re:Access more memory in Real Mode?

Posted: Sun Apr 30, 2006 4:17 pm
by GLneo
as far as i know all you do is set your pmode tables, jmp to pmode, jmp back and you should(if you dont mess with seg regs)get access to all memory

p.s. if you mean just past 1meg, A20 enable should work too.

Re:Access more memory in Real Mode?

Posted: Sun Apr 30, 2006 4:18 pm
by earlz
i believe this is in the faq but anyway
What happens is you enable A20 gate and then you switch to protected mode, make a generic "full address" set of selectors and then load the gdt using lgdt; load the new selectors into the appropriate segment registers. then you switch back to real mode and voila you got access to everything. You will have to make a pokeb32() in asm(don't have time to go into detail) because no C compiler i know of supports both 16 and 32 bit instructions

Re:Access more memory in Real Mode?

Posted: Sun Apr 30, 2006 4:24 pm
by Jaffe
First of all, I'm writing the OS in assembly only (since it's a small real mode OS).

Are you sure that's what HIMEM.SYS does in MS-DOS? It use the unreal mode trick? For some reason, that seems strange to me, but I don't know... Enabling the A20 gate alone will just give me access to the first 64KB of the extended memory, right?

If I set up unreal mode, I still won't be able to for example read from disk using int 13h, and stright into EBX, right? I will have to read into a buffer in the conventional memory, and transfer the data into a final location in the extended memory afterwards?

Re:Access more memory in Real Mode?

Posted: Sun Apr 30, 2006 5:37 pm
by Dex4u
I see little point in what you are doing, if it's a small realmode OS, you should not need the extended memory.
Much better to implement a function for going to and from realmode, this way you can have the best of both worlds, that what i do in my OS, if i need to use realmode function for vesa or mode switching.
Here's a demo i made to do that, with asm code may help
http://www.dex4u.com/images/DemoVesa.zip
Note: needs vesa2.

Re:Access more memory in Real Mode?

Posted: Sun Apr 30, 2006 6:01 pm
by Jaffe
I know it's not important in such a small OS, but remember, I do this to learn more assembly, etc. From what I've read until now, the best thing to do is probably going into unreal mode, but I've read that it's much slower than protected mode and real mode, and I can't use the 32-bit offset values with any BIOS interrupt, so maybe unreal mode aint the best choice anyway (are there any other?)

Still, I wonder how MS-DOS does this?

EDIT: I found out how HIMEM.SYS does it; it does as people mentioned before. I sets up a GDT entry that covers the whole memory, load it, enable PE-bit, far jump, and then it goes back to real mode. So it's some kind of unreal mode trick.

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 4:56 am
by Dex4u
Note: only data selectors is changed not code, when using unrealmode.

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 5:08 am
by Jaffe
Ah, of course. So no far jump is needed, I suppose. However, I tried to write some small piece of code that copies a string into 100000h, and then printing it from that location. This didn't work; it hanged while in the loop that copies the string at DS:ESI to DS:EDI (not using any MOVSx instruction) where ESI points at the start of the string within the program, and EDI points to 100000h... Why doesn't this work?

Code: Select all

   [bits 16]
   org 1000h

   mov esi, msg_test
   mov edi, 100000h

MoveString:
   mov al, byte [ds:esi]
   cmp al, 0
   je PrintString
   mov byte [ds:edi], al
   inc esi
   inc edi
   jmp MoveString

PrintString:
   mov esi, 100000h

PrintLoop:
   mov al, byte [ds:esi]
   cmp al, 0
   je Halt
   mov ah, 0Eh
   int 10h
   inc esi
   jmp PrintLoop

Halt:   
   mov ah, 0Eh
   mov al, 'O'
   int 10h

   jmp $

   msg_test db "Just some testing...",0
EDIT: I might add that this code is loaded from a floppy into 0000:1000h.

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 5:38 am
by Dex4u
Here's is a good example:

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 10:52 am
by Jaffe
Thanks!

But what's wrong with the code I posted over? A20 is enabled, system is in protected mode, and all!

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 11:19 am
by Dex4u
Jaffe wrote: Thanks!

But what's wrong with the code I posted over? A20 is enabled, system is in protected mode, and all!
The code you posted is just a print string function, how can we see whats wrong ?.

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 11:51 am
by Jaffe
No, it copies a string from its location in the program space and into offset 100000h of the flat memory, and then it tries to print the string starting at 100000h, but that doesn't work. Nothing get's printed on the screen. It seems that it's something with the loop that copies the string to 100000h.

And yes, I have tested the print routine. It works if ESI points to the string in the program (msg_test).

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 12:31 pm
by Dex4u
Try diffant A20 enable codes, as some just do not work.

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 12:38 pm
by Jaffe
Ok... So the code is fine? I'll try another way of enabling A20... The method I use, is the one that's recommended in the OS-FAQ.

Re:Access more memory in Real Mode?

Posted: Mon May 01, 2006 3:01 pm
by blip
Be careful with unreal mode and BIOS routines!

Code: Select all

PrintLoop:
  mov al, byte [ds:esi]
  cmp al, 0
  je Halt
  mov ah, 0Eh
  int 10h
  inc esi
  jmp PrintLoop
What's stopping INT 10h from reloading DS somewhere? Yeah it'll probably restore the old value but not the old base and limit.