Access more memory in Real Mode?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Jaffe

Access more memory in Real Mode?

Post 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!
GLneo

Re:Access more memory in Real Mode?

Post 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.
earlz

Re:Access more memory in Real Mode?

Post 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
Jaffe

Re:Access more memory in Real Mode?

Post 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?
Dex4u

Re:Access more memory in Real Mode?

Post 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.
Jaffe

Re:Access more memory in Real Mode?

Post 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.
Dex4u

Re:Access more memory in Real Mode?

Post by Dex4u »

Note: only data selectors is changed not code, when using unrealmode.
Jaffe

Re:Access more memory in Real Mode?

Post 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.
Dex4u

Re:Access more memory in Real Mode?

Post by Dex4u »

Here's is a good example:
Jaffe

Re:Access more memory in Real Mode?

Post by Jaffe »

Thanks!

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

Re:Access more memory in Real Mode?

Post 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 ?.
Jaffe

Re:Access more memory in Real Mode?

Post 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).
Dex4u

Re:Access more memory in Real Mode?

Post by Dex4u »

Try diffant A20 enable codes, as some just do not work.
Jaffe

Re:Access more memory in Real Mode?

Post 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.
blip

Re:Access more memory in Real Mode?

Post 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.
Post Reply