Hey, i like to think im OK at OSDEV... but in reality im probably not too great, and i dislike making posts like this, but i can't find the answers to my questions, and as such... well, i thought id ask
Ok, well... im using Brans Kernel as a base of my OS, and on my todo before 0.1 list i would like a function which can take me back into real mode, so i can perform tasks such as successfully set VGA mode using BIOS ints.
i know this is probably relatively simple, but despite my efforts, i cannot seem to get this to work, could somebody please link/write me a difinitive list in order of what i need to do to disable RMODE, as there are so many variations on the internet, or, if someone has one that works, show me the snippet? i would appreciate it greatly, as although i dont want to copy and paste (no point, its my OS, what fun is ctrl-c,ctrl-ving?), but i would learn alot from it i am sure.
my next problem is that of CMOS (read/write - getting actual time in particular), i got it to work on my last OS, but i cannot find any of the documents i used, and the readCMOS() function along with the snippet i used in my last one just brings up zeroes for every digit :S
could somebody link me to a document that explains this?
i appologise if any of this sounds in any way demanding, as i sometimes come across like that on forums, i mean it in a very honest, coming to you for help sort of way. i also respect that you are doing this out of free will etc, and am grateful.
merry xmas, lukem95!
A question or two
Re: A question or two
Hi!
* Jump to an identity mapped area in virtual memory and disable paging.
* Select a 16-bit protected mode code segment, otherwise the cpu won't switch to 16 bit code even though you are in real mode! Do a far jump to some 16 bit code through your 16bit code segment. Ideally, this code segment is aligned just like a real mode segment somewhere in low memory, so you can later just reload it with the corresponding realmode segment selector.
* Disable protected mode.
* Do a far jump to a real mode code segment.
* Reload all data segments and stack segment with real mode segment selectors.
* You are now back in real mode!
Those steps could be combined just as well, I guess. You could jump to the 16bit pmode code segment while paging is enabled, then disable both the paging and pmode bit, then do a jump to the realmode segment. It's just important that you are in 16bit code while you disable protected mode.
Feel free to ask if there are any questions remaining about the above!
cheers
Joe
If you mean disabling PMODE (and going back to real mode), this is what I did in my bootloader (for calling int 0x13):lukem_95 wrote:could somebody please link/write me a difinitive list in order of what i need to do to disable RMODE, as there are so many variations on the internet, or, if someone has one that works, show me the snippet?
* Jump to an identity mapped area in virtual memory and disable paging.
* Select a 16-bit protected mode code segment, otherwise the cpu won't switch to 16 bit code even though you are in real mode! Do a far jump to some 16 bit code through your 16bit code segment. Ideally, this code segment is aligned just like a real mode segment somewhere in low memory, so you can later just reload it with the corresponding realmode segment selector.
* Disable protected mode.
* Do a far jump to a real mode code segment.
* Reload all data segments and stack segment with real mode segment selectors.
* You are now back in real mode!
Those steps could be combined just as well, I guess. You could jump to the 16bit pmode code segment while paging is enabled, then disable both the paging and pmode bit, then do a jump to the realmode segment. It's just important that you are in 16bit code while you disable protected mode.
Feel free to ask if there are any questions remaining about the above!
cheers
Joe
thanks, that clears up a lot in my mind, but could explain what you mean by "identity mapped area in virtual memory"?
i follow the rest, although ill probably still get stuck somewhere along the line, but i cant try it if i dont understand the first step lol.
EDIT: ignore all that, i just realised what it means, and i dont even have paging implemented yet, so it doesnt make a difference.
however i am confused about something else now (never ends huh), when you say i need to be in 16bit pmode (as i have done) to disable pmode, then jump to a realmode segment, how does this differ from a piece of [BITS 16] code in my asm file?
~Lukem95
i follow the rest, although ill probably still get stuck somewhere along the line, but i cant try it if i dont understand the first step lol.
EDIT: ignore all that, i just realised what it means, and i dont even have paging implemented yet, so it doesnt make a difference.
however i am confused about something else now (never ends huh), when you say i need to be in 16bit pmode (as i have done) to disable pmode, then jump to a realmode segment, how does this differ from a piece of [BITS 16] code in my asm file?
~Lukem95
Last edited by lukem95 on Tue Dec 25, 2007 4:04 pm, edited 1 time in total.
-
- Member
- Posts: 368
- Joined: Sun Sep 23, 2007 4:52 am
Hi,
You must make sure the assembler is generating code that matches the mode the CPU is in. This means if you switch from 32-bit protected mode to 16-bit protected mode you need to tell the assembler to start generating 16-bit code instead of 32-bit code by using "bits 16". If you don't your code will crash because the assembler won't know what mode the CPU is in and will generate incorrect code.
As an example, code to switch from 32-bit protected mode (without paging) to real mode would go something like:
Note: Due to the way the CPU works, you don't necessarily need to set DS, ES, FS and GS to "16-bit with 64 KB limits". If you don't then you'll end up in "unreal mode", which is almost the same as real mode but data segments will keep the old segment limits. Lots of people use this trick to access 4 GB of physical address space in real mode.
You don't need to tell the assembler when you switch from 16-bit protected mode code to real mode because the instructions have the same format in both modes. The only difference is how you use segments, which the assembler doesn't need to know about.
Cheers,
Brendan
There's 2 seperate things - which mode the CPU is in (real mode, 16-bit protected mode, 32-bit protected mode, 64-bit long mode, etc) and which mode the assembler is creating code for (16-bit, 32-bit, 64-bit).lukem_95 wrote:however i am confused about something else now (never ends huh), when you say i need to be in 16bit pmode (as i have done) to disable pmode, then jump to a realmode segment, how does this differ from a piece of [BITS 16] code in my asm file?
You must make sure the assembler is generating code that matches the mode the CPU is in. This means if you switch from 32-bit protected mode to 16-bit protected mode you need to tell the assembler to start generating 16-bit code instead of 32-bit code by using "bits 16". If you don't your code will crash because the assembler won't know what mode the CPU is in and will generate incorrect code.
As an example, code to switch from 32-bit protected mode (without paging) to real mode would go something like:
Code: Select all
;Change all segment registers to 16-bit protected mode with 64 KB limits
mov ax,SEG_16bit_DATA
mov ds,ax ;See note
mov es,ax ;See note
mov fs,ax ;See note
mov gs,ax ;See note
mov ss,ax
jmp SEG_16bit_CODE:.here
;Tell the assembler the CPU mode changed
bits 16
;Now CPU is in 16-bit protected mode
.here:
;Disable protected mode
mov eax,cr0
and al,0xFE
mov cr0,eax
;Flush instruction pipeline and load real mode CS
jmp REAL_MODE_SEG:.flush
.flush:
;Load real mode data segment registers
mov ax,REAL_MODE_SEG
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
You don't need to tell the assembler when you switch from 16-bit protected mode code to real mode because the instructions have the same format in both modes. The only difference is how you use segments, which the assembler doesn't need to know about.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
wow, thanks for the great reply brendan, that cleared up a lot for me!
if this forum had rep (i see no reason for it though lol), id definatly + you!
There is just one more thing i need to ask however, and i have to say, it is very nooby, but i cant get my head round it. In order to jump back into RMODE i have to have the .here (in your example) in memory under the 64k limit, but how would i get the code here if GRUB drops you at a memory location above this?
memcpy() came to mind, but is there an easier (more obvious perhaps) way of doing this? preferably in ASM as i am using this to code this function.
if this forum had rep (i see no reason for it though lol), id definatly + you!
There is just one more thing i need to ask however, and i have to say, it is very nooby, but i cant get my head round it. In order to jump back into RMODE i have to have the .here (in your example) in memory under the 64k limit, but how would i get the code here if GRUB drops you at a memory location above this?
memcpy() came to mind, but is there an easier (more obvious perhaps) way of doing this? preferably in ASM as i am using this to code this function.
I have code a demo for vesa mode changing from pmode, its coded in asm, demos set up vesa goes to pmode waiting 10 seconds and then going back to realmode to switch to text mode. It come with is own boot loader, that will load a exe off the floppy.
It may help you.
http://www.dex4u.com/demos/DemoVesa.zip
NOTE: I was called "ASHLEY4" when i made it, but in some country's its a girls name.
It may help you.
http://www.dex4u.com/demos/DemoVesa.zip
NOTE: I was called "ASHLEY4" when i made it, but in some country's its a girls name.