I can't switch back to real mode properly (Gave up)

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.
zdz
Member
Member
Posts: 47
Joined: Tue Feb 10, 2015 3:36 pm

Re: I can't switch back to real mode properly

Post by zdz »

neon wrote:Just use something like nasm, have it output a win32 object file, and tell the linker to import it in. You can either do this separately or have it as a "special build step" within the visual c++ IDE. Also, you have not addressed any of my questions regarding the GDT nor its Wiki page. Why is that?
Pretty much this. I prefer yasm, but that doesn't matter. I like to make the assembler a project dependency, to make it easier to move projects around, but I think I'm getting off topic here.
One thing you should be careful about: if your target platform is x64, trying to link 16-bit code may cause the linker to complain in some situations that involve relocations. There are tricks that make the linker do what you want, so it isn't a huge problem, but at first you may not know what to do.

I looked over the VS page on the wiki and it has nice explanations regarding some topics, but forgets to address some VS-specific challenges. I also find the rebase and multi-boot related stuff to be more complicated than needed, and maybe a bit old. VS 2015 is easier to configure in this regard.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: I can't switch back to real mode properly

Post by neon »

Interestingly, we had similar problems with 16 bit relocation errors when we were implementing BIOS support in our 32 bit loader. It wasn't a linker error though - it was an nasm error. Easy to get around, but does require a small hack. So I don't think the problem is specific to x64 - I think its more of a problem with the object files (how relocations are stored.)

In any case, its little details like this that the original poster needs to watch out for and isn't something that can just be copied and pasted to work.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
zdz
Member
Member
Posts: 47
Joined: Tue Feb 10, 2015 3:36 pm

Re: I can't switch back to real mode properly

Post by zdz »

neon wrote:Interestingly, we had similar problems with 16 bit relocation errors when we were implementing BIOS support in our 32 bit loader. It wasn't a linker error though - it was an nasm error. Easy to get around, but does require a small hack. So I don't think the problem is specific to x64 - I think its more of a problem with the object files (how relocations are stored.)

In any case, its little details like this that the original poster needs to watch out for and isn't something that can just be copied and pasted to work.
It's a problem related to how relocations work. It makes sense for it to not be x64 specific.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: I can't switch back to real mode properly

Post by alexfru »

neon wrote:Interestingly, we had similar problems with 16 bit relocation errors when we were implementing BIOS support in our 32 bit loader. It wasn't a linker error though - it was an nasm error. Easy to get around, but does require a small hack.
I'm curious what it was since I'm using NASM. Care to elaborate?
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: I can't switch back to real mode properly

Post by Ycep »

neon wrote:Hello,
Not sure what did you mean by that "i didn't addressed" your questions regarding GDT
To quote what I wrote before:
Do you know what all of the fields in the GDT entries actually are? Have you read what was provided to you? Was there any questions or doubts that you had regarding what you read?
The reason why I am asking is because you don't appear to understand what the GDT is for. So I am trying to get to the root of the problem here: Did you not read the article provided? Was there anything you were not sure about?
Hmmm... Is there any way to switch to any non-outdated graphical mode without using any interrupts or using real mode which isn't Bochs Graphics Adapter?
Sure. If you have an embedded controller or external graphics card and an Intel motherboard, get its datasheet and program it directly. Or, get the video card information from some emulator and program it directly. In the former case (writing a driver for your specific hardware) you'll be on your own and at your own risk. In the latter case (writing a driver for a device used by an emulator) you can get working source for Virtual Box, QEmu, Bochs, etc and am sure many people here worked with it before.

In short, you'll have to either use real mode, virtual 8086 mode, or custom drivers. There is the VBE protected mode interface, but it is not well supported and as addressed before by Brendan, when UEFI takes over your VBE code will no longer work.
I mean, can VESA be loaded without using interrupts or real mode?
Again, there is the protected mode interface but its not well supported. Your only real options are real or virtual 8086 mode.
There isn't anything i'm not sure about... (Read PMs, i said that i understand GDT very clear now, it's like some kind of memory protection).
How to use V8086? Sounds like better idea than going to real mode and returning back to protected mode to set video mode.
And hell no, i think that making driver for every ******* single graphics card isn't normal for homemade OS. There is over 10000 diffrent graphics cards!
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: I can't switch back to real mode properly

Post by iansjack »

lukaandjelkovic wrote:And hell no, i think that making driver for every single graphics card isn't normal for homemade OS. There is over 10000 different graphics cards!
But how many different computers is your OS going to run on? For almost all home-brew OSs the answer is 1.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: I can't switch back to real mode properly

Post by Ycep »

Not sure about that... You say that almost every OSDever want to make its OS only work on its computer? Example, Dell Xperison Grandma 4100GR Z1 is only computer that ExDOS can run...
or something like:
It can run only on Cochs (Bochs clone. You can install it by typing this into powershell : "cpZ 10 tAr ^$" ?A> yhsA COCHS" about 4000 times. If you make mistake while typing you need to type it all over.
Any tutorial for V8086?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: I can't switch back to real mode properly

Post by neon »

Hello,
There isn't anything i'm not sure about... (Read PMs, i said that i understand GDT very clear now, it's like some kind of memory protection).
Almost. The GDT has to do with segmentation. Each entry in the GDT describes a segment. (Think back to segments in real mode. Its almost the same idea here.) Segments can be anywhere and may overlap. A segment has a start address (this is the base) and an ending address (this is limit.) If you want a code segment, you would make it executable and read only. If you want a data segment, you want it to be non-executable but writable. If you want a stack segment, you would want the segment to grow downward. Segments can be 16 bit or 32 bit. Segments can also be protected using a Descriptor Privilege Level (DPL).

The GDT (and LDT) are from the days of 16 bit protected mode (think of DOS extenders.) Since no one uses segmentation anymore (what is the point when you can achieve the same benefits and more using paging without the problems with segments?) So all major operating systems just create different segments with the same base and limit (they can overlap, after all.) To make the CPU happy, we set CS to an executable segment and all data segments to non-execute read/write.

There is one more important deal - the selector registers CS, DS, ES, FS, GS, SS all have a specific format:

Code: Select all

Table Index (13 bits) | Table Type (1 bit) | RPL (2 bits)
Where Table Index (starts from 0) is the index into the table. Table Type is either 0 (for current GDT) or 1 (for current LDT), and the RPL is the Requested Privilege Level. So, you tell the CPU what segments to use by writing to one of these registers. Don't worry about the LDT stuff unless you ever plan to use it.

For example, if your 32 bit code segment (with DPL 0) is at GDT index 1, you would tell the CPU to select this segment by doing a mov ax, 8 mov cs, ax. This selects GDT index 1, RPL 0, Table GDT. You won't have to worry about setting the RPL bits unless you plan to switch to a segment in a different privilege level (such as user mode).

In your specific case, you needed to create a new 16 bit code segment. To do this, you would add the descriptor and load CS like above to select that new code segment in order to run 16 bit code.

In summary - yes, protection is a part of it. But the primary thing the GDT does is segmentation.
How to use V8086? Sounds like better idea than going to real mode and returning back to protected mode to set video mode
Unfortunately, virtual 8086 mode still requires you setting that 16 bit segment in the GDT (what you have been struggling with above.) It also requires supporting user mode (which in turn requires a basic (minimal though so don't worry too much) -- TSS. It isn't as much work as it might sound at first.

Work on the GDT stuff first though cus you'll need that for either supporting virtual 8086 mode or real mode anyways.
And hell no, i think that making driver for every ******* single graphics card isn't normal for homemade OS. There is over 10000 diffrent graphics cards!
Most hobbyist operating systems set the video mode once during boot and do not do what you are wanting to do.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: I can't switch back to real mode properly

Post by neon »

Hello,
alexfru wrote:
neon wrote:Interestingly, we had similar problems with 16 bit relocation errors when we were implementing BIOS support in our 32 bit loader. It wasn't a linker error though - it was an nasm error. Easy to get around, but does require a small hack.
I'm curious what it was since I'm using NASM. Care to elaborate?
The error in question was COFF format does not support 16 bit relocations. The error occurred when we attempted to jump from 16 bit protected mode to a label in 16 bit real mode. Note as a workaround what we did was manually calculate the segment:offset address and performed a retf rather than a direct jump. I suppose I should mention that in our system, nasm generates a COFF object file which gets linked into the C part of the loader. If you aren't using COFF object files or Visual Studio, you probably won't run into this specific error.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: I can't switch back to real mode properly

Post by alexfru »

neon wrote:Hello,
alexfru wrote:
neon wrote:Interestingly, we had similar problems with 16 bit relocation errors when we were implementing BIOS support in our 32 bit loader. It wasn't a linker error though - it was an nasm error. Easy to get around, but does require a small hack.
I'm curious what it was since I'm using NASM. Care to elaborate?
The error in question was COFF format does not support 16 bit relocations. The error occurred when we attempted to jump from 16 bit protected mode to a label in 16 bit real mode. Note as a workaround what we did was manually calculate the segment:offset address and performed a retf rather than a direct jump. I suppose I should mention that in our system, nasm generates a COFF object file which gets linked into the C part of the loader. If you aren't using COFF object files or Visual Studio, you probably won't run into this specific error.
Oh, my Smaller C compiler, which emits assembly code for NASM, uses the ELF object format for both 32-bit and 16-bit code. NASM supports 16-bit (and even 8-bit?) relocation extensions in ELF. While a linking error is still possible when object files are mixed and matched carelessly (my linker doesn't enforce 16-bit relocations for 16-bit code and 32-bit relocations for 32-bit code), I'm glad I chose NASM+ELF from the very beginning. My linker links ELF object files into DOS (regular MZ and MZ stub + glued relocatable a.out for DPMI), Windows and Linux executables (and flat binaries too). One object format for everything. Of course, I do need to work around segmentation and I do tricks similar to yours above in the startup code of DOS executables compiled for the huge memory model (all pointers are 32-bit flat (with usable range up to 1MB) and undergo relocation and runtime conversion into segments and offsets).
zdz
Member
Member
Posts: 47
Joined: Tue Feb 10, 2015 3:36 pm

Re: I can't switch back to real mode properly

Post by zdz »

neon wrote:Hello,
alexfru wrote:
neon wrote:Interestingly, we had similar problems with 16 bit relocation errors when we were implementing BIOS support in our 32 bit loader. It wasn't a linker error though - it was an nasm error. Easy to get around, but does require a small hack.
I'm curious what it was since I'm using NASM. Care to elaborate?
The error in question was COFF format does not support 16 bit relocations. The error occurred when we attempted to jump from 16 bit protected mode to a label in 16 bit real mode. Note as a workaround what we did was manually calculate the segment:offset address and performed a retf rather than a direct jump. I suppose I should mention that in our system, nasm generates a COFF object file which gets linked into the C part of the loader. If you aren't using COFF object files or Visual Studio, you probably won't run into this specific error.
This is what I also experienced. I use a similar trick for addressing a label or jumping to one (I don't do retf instead of call / jmp but that is a matter of choice). I think someone should update the wiki with this information.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: I can't switch back to real mode properly

Post by Ycep »

I already have user-mode and i use it. Readed your tutorial for User-mode.
Hmmm...
I do not want to switch that in protected mode. I'm sick of my 120 tries to make it do what i want. I'll just put it into bootloader, my console shell will be graphical. My final solution. I think it's best.
Post Reply