Help!! loading up GDT (switching to protected mode) assembly AT&T syntax
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Help!! loading up GDT (switching to protected mode) assembly AT&T syntax
Hello people,
This is starting to drive me crazy. I'm not sure this is the appropriate forum but i'll give it a shot. I've been trying to create my own operating system and for that I need to be able to load the GDT and i'm having a little bit of a problem figuring things out using AT&T syntax. Could anybody help me out.
I don't think i'm do the far jump correctly. I know i'm switching the PE bit correctly. I'm not sure i'm loading the GDT correctly.
This is what i have so far:
.org 0x0000
.code16 # We compile the code in 16 bits mode
.code32 # This part is compiled in 32 bits mode
start32:
movw $0x8, %ax # We set up %ds and %ss pointing on the Data segment
movw %ax, %ds
movw %ax, %ss
This lil bit of code is dd written to the first sector of a floppy disk so it's booted up in 0x07C00; I understand the 20 bits addressing and the 4 bit shift to the left to calculate Real addresses from a segment and an offset (segment*16+offset). I guess i'm having a little bit of trouble with AT&T and what the GAS compiler does and doesn't do. I've tried many things but nothing seems to work. I get a triple fault (automatic reboot) every time i boot up the computer with floppy. Help!!! Going nuts here!!!
if you are getting into protected mode then the first interrupt that occurs(they happen very quickly) is gonna triple fault because you have no idt, so the first thing to do (before you set pe mode bit) is disable interrupts. I dont think youve set the gdtr correctly but my mental hex arithmatic aint too good so thats probably me. you also have no idea how cs is set at bootup I suggest the first thing you do is a long jump to ensure its set to either 0 or 0x7c0 but i dont see how that would triple fault you.
you should try using bochs instead of a floppy cos it'd be much quicker, pehaps it can even single step through your code for you. if you cant do that then you could at least start poking stuff into video memory to see where it gets to.
<edit>
oops you did disable interrupts, i just didnt see it, ive checked your gdt and its correct, the only thing that doesnt add up to me is the gdtr(remember movl-s are relative to ds)
00110179319e[CPU ] jump_protected: gate type 0 unsupported
00110179319e[CPU ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
Hmmm yeah knew I was tripple faulting, I just don't quite understand why. Thanks for taking the time to check things out though. Here's what i got off the internet on the GPL ( exception 13 )
"possible in real mode if non-stack memory access straddles 0 or FFFFh, or if instruction is longer than 15 bytes, or if a 32-bit address greater than FFFFh is used "
Whats bochs exactly? A bootup emulator? It would probably be faster yeah than booting up all the time. I'll check into Bochs later today; thanks for the advice.
Another thing that i don't understand, and maybe thats part of why I can't get this to work. How is it possible to address 4Gb of memory if we only have 20 bits of real addressing. Well we have 20 bits in 16-bit real mode but I don't quite get how the 32-bit mode addressing is done. It seems to also be based on 20 bits?
Bochs is an x86 emulator, similar to vmware, except that its free and opensource.
The 20 bit scheme is used in real mode, and is why we can only access 1MB of memory,
(unless we use unreal mode, which I wont even touch right now :-X ). In protected mode
segment registers are used differently. There is a totally different scheme used, load up this
page : http://www.nondot.org/sabre/os/files...e/PMODE-OS.txt . This page
describes the addressing scheme and implementation better than I can
.code32 # This part is compiled in 32 bits mode
start32:
movw $0x8, %ax # We set up %ds and %ss pointing on the Data segment
movw %ax, %ds
movw %ax, %ss
movw $0x741,0xb8000 #prints 'A' in top left to show we've not crashed
Yes -- I was using -Ttext 0x0, dont ask why Moment of random stupidity :-P
edit: Actually...I could have compiled it with -Ttext 0x0, but I would of had to
manually add "+ 0x7c00" to the lgdt statement and jmp to 32bit land. Either way
is ok.
Couple of notes:
You're code works...for now, since you dont access memory above 1MB, but once
you do - fault city. You need to enable the A20 line. Also, remember that LGDT
doesnt use DS, but instead accepts a linear 20bit address.
not sure if your notes were directed at me or the original poster but i'll answer them anyway
by jinksys since you dont access memory above 1MB, but once you do - fault city.
actually its not a fault, its a design feature(like most crap things ), in the days before protected mode naughty programmers in there attempt to optimize used the fact that in a 20bit number system 0xFFFFF + 0x1 = 0, so they actually relied on the fact that the memory wrapped round to 0. and because intel needed to maintain compatibility to sell its new processors the 20th address line was disabled by default.
You need to enable the A20 line
no you dont, that is not part of the definition of protected mode, however you do need to do it if you wish to access all memory. i would do it in either the second stage bootloader or the kernel itsself, cos a 1 disk sector is too small(imo) to fit all that code in.
Also, remember that LGDT doesnt use DS, but instead accepts a linear 20bit address.
i didnt know this but apparently its a 16 bit address(in real mode at least)
from this website i just googled for Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH; Interrupt 6 if the source operand is a register
Sorry people, I tried posting a few messages yesterday and day before but it seems they didn't make it through. My account was messed up for some reason; no idea why as it was working fine before. Pfff (i'll just blame it on Windows, hehe)
Yeah I had the same problem it would still triple fault on me but I had forgotten to change my script from ld -Ttext 0x0 --oformat binary bootsector.o -o bootsector.binary
Works like a charm. Thanks alot to everybody who contributed to help me on this, I'm very grateful as I can now stop wasting time trying to figure some "simple" things out and concentrate on my kernel ( finally ).
One last thing though.
I'm wondering how the ljmp works and why $0x10, $start32
jumps to the right place. Unless i'm wrong, the $0x10 is the segment and will be shifted 4 bits to the left so we'd have 0x100 + $start32. I'm guessing that 0x800 is already part of the base from loading the GTD or something as we need to be jumping to the codeselector which is situated at 0x810. I'm guessing thats where the 0x10 comes from but i'm not positive. will the 0x800 be shifted too? the resulting address of the whole thing being "$0x8100"(shifted already), $start32?
Also, enabling gate A20 on recent computers through port 0x92 is 3 lines of code . And enabling it through the keyboard controler isn't so bad either and would probably fit in the first sector of the floppy without much trouble. I already had code to enable bootloader, but I was concentrating on trying to make pmode work .
by aXoneX I'm wondering how the ljmp works and why $0x10, $start32
the 4 bit shift is for real mode addressing only, segments are completely different in protected mode.
at this point you have enabled protected mode, so when the processor encounters a jump to segment 0x10 it looks in the gdt at the second entry (0x10th byte) and gets the information for the defined segment which in your case is a 4GB executable segment starting a address 0 and going upwards. the code then jumps to the offset start32 which is 0x7c00 (start of text) + the small offset into file (dissassemble to find out)
by aXoneX Also, enabling gate A20 on recent computers through port 0x92 is 3 lines of code . And enabling it through the keyboard controler isn't so bad either and would probably fit in the first sector of the floppy without much trouble. I already had code to enable bootloader, but I was concentrating on trying to make pmode work .
i never heard of port 0x92 so its not as bad as i remember with the kbd controller but if you want appropriate error messages and you want to check youve been successful you really need to do a lot of squeezing to get it into a single 512 byte block. its much easier to put it in a second stage loader.
not sure if your notes were directed at me or the original poster but i'll answer them anyway
They were directed at the original poster.
Quote:
You need to enable the A20 line
no you dont, that is not part of the definition of protected mode, however you do need to do it if you wish to access all memory. i would do it in either the second stage bootloader or the kernel itsself, cos a 1 disk sector is too small(imo) to fit all that code in.
I know its not a definition of protected mode, but seriously, whats the use of
going through all this if only for less than 1MB of memory?
Quote:
Also, remember that LGDT doesnt use DS, but instead accepts a linear 20bit address.
i didnt know this but apparently its a 16 bit address(in real mode at least)
Its been a long night, I dont whos right or wrong anymore, so Ill just post what
the intel manual says:
The source operand specifies a 6 byte memory location that contains the base address
(linear address) and the limit (size in bytes) of the GDT.
by aXoneX Also, enabling gate A20 on recent computers through port 0x92 is 3 lines of code . And enabling it through the keyboard controler isn't so bad either and would probably fit in the first sector of the floppy without much trouble. I already had code to enable bootloader, but I was concentrating on trying to make pmode work .
i never heard of port 0x92 so its not as bad as i remember with the kbd controller but if you want appropriate error messages and you want to check youve been successful you really need to do a lot of squeezing to get it into a single 512 byte block. its much easier to put it in a second stage loader. [/B][/QUOTE]
Simply put, turning on the a20 is a pain in the ass. There are many methods to do it and some may work on one machine and not on another.
Here is a document that will help you through this:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.