error when assembling asm with idt

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

error when assembling asm with idt

Post by ncsu121978 »

[attachment deleted by admin]
ncsu121978

Re:error when assembling asm with idt

Post by ncsu121978 »

i see that it is assembling fine
its in the linking stage
i have included a zip file with all the files
run build.bat to build the system......
nasm and gcc must be in your path.....
you need a disk in the floppy since the bat copies the .bin over to the floppy in the build.bat file


[attachment deleted by admin]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:error when assembling asm with idt

Post by Pype.Clicker »

you're guessing it right: your 32-bits linker doesn't like the 16-bits relocations (as your code could virtually be relocated at any 32-bits address, a 16-bits field isn't large enough ... (shame on Intel guys not to have thought about that with their descriptors splitting))

Now, the way i found to get it working is to have a list of DD pointers to the code handlers plus a function that will unpack them and generate the IDT at run time ...
PlayOS

Re:error when assembling asm with idt

Post by PlayOS »

Hi,

Just a note about your source, I was having a look at your IDT and your IRQ's will cause problems eventually, the second lot of IRQs 8-15 require you to do this :-

mov al, 0x20
out 0x20, al
out 0xa0, al

you must send the End of Interrupt to the second (slave) pic also.

This will save you some headaches.... :)
ncsu121978

Re:error when assembling asm with idt

Post by ncsu121978 »

thanks Pype.Clicker for the info
do you have any sample code I could get my hands on because I cant seem to get that to work right
Curufir

Re:error when assembling asm with idt

Post by Curufir »

The IDT and interrupt code you're showing there is an example I threw together quickly for someone (Tom I think) to illustrate some points in a different thread, mainly that the IDT is a simple lookup table. I was as surprised as anyone else that it functioned within someone's code seeing as that wasn't its intended purpose.

There's an infinitely better set of examples written by Christopher Giese which also handle integrating C and assembly code files. Look here http://my.execpc.com/~geezer/osd/index.htm at the "Throw-away source code" section. Seeing as it looks like you're using that combination of languages these are likely to be of far more use to you.

Curufir
ncsu121978

Re:error when assembling asm with idt

Post by ncsu121978 »

ok i looked at the code on that link Curufir...it is pretty overwhelming so I am trying to pick it apart peice by piece. One things that stands out at me it

Code: Select all

/* IMPORTS:
from STARTUP.ASM */
extern unsigned long _virt_to_phys;

// then later down in main
void main()
{
.
.
.
/* set up video */
   if((port_inportb(VGA_MISC_READ) & 0x01) != 0)
   {
      _fb_adr = (unsigned short *)(0xB8000L - _virt_to_phys);
      _crtc_io_adr = 0x3D4;
   }
what is _virt_to_phys ? I look in the startup.asm file but i dont see it in there anyway.
I am changing the printing to screen functions from his code to my own print functions and they didnt work initially. Previsouly i was just using 0xb8000 as the place for video memory without offsetting by _virt_to_phys and it was working fine with the code i was using. Now it didnt work with his code so I modified my text output to include that _virt_to_phys offset and it works fine again........can someone tell me what is going on with that. I was going to try to figure it out myself but i didnt see virt_to_phys ot _virt_to_phys anywhere in the startup.asm file
Curufir

Re:error when assembling asm with idt

Post by Curufir »

I'm not trying to be picky, but there's a hell of a lot of code on that site, and at least 9 separate tutorials just in the archive I suggested might be useful. I played hunt the tutorial for a while, but couldn't figure out which one you were using so gave up :).

What I can do, maybe :), is tell you what that virt_to_phys variable probably means. If he's set up the selector so that the base isn't at 0 then a selector:offset address will no longer correspond to a physical address (Ie starting at 0). The virt_to_phys variable is probably the value of the base of the selector the video operations are being done in. So when he subtracts this base he's making the selector:offset address correspond to the physical address again so that these video operations happen on the video memory at 0xB8000 physical. Without that offset those operations are actually taking place at 0xB8000 + selector base, which unless the selector base is 0 will most likely not correspond to your video memory.

At least I think that's what is happening, which means the most likely place to start searching for the elusive virt_to_phys declaration is wherever he has setup the gdt (Which from the looks of it is in this startup.asm).

Incidentally this is why some people prefer to have a video selector in their GDT whose base is set to 0xB8000. Then they can just use that selector and operate on video ram without the constant need to offset their operations.

Tell me which tutorial you're using (A link would be nice) and I'll see if I can't help out a bit more.

Curufir
ncsu121978

Re:error when assembling asm with idt

Post by ncsu121978 »

[link]http://my.execpc.com/~geezer/osd/intr/x86-32.zip[/link]
there is a link to the zip file of what i am working with
now i mean i have the thing booting and it is all working with interrupts going and i have worked it into my code for video, file system, keyboard, ect....
i just had to subtract that virt_to_physical to get the video working properly. I am wondering if I am going to have to do something similar to that in other parts of my code.
It seems to work fine right now
And thanks alot for the help :)
Curufir

Re:error when assembling asm with idt

Post by Curufir »

Ok, here's the relevant bits in startup.asm.

Code: Select all

At line 79

; patch things that depend on the load adr
???xor ebp,ebp
???mov bp,cs
???shl ebp,4
???mov [_virt_to_phys],ebp
He then proceeds to patch up some of the gdt selectors' base addresses so that they correspond to the address the code has being loaded at. In this case it's the linear address based on the code segment that's currently being used. So if for example he's loaded the code at 0500:0000 _virt_to_phys contains 0x5000 which is the linear address at the start of that 64k segment. The gdt entries then get patched so that their base is the same as the linear address for the start of this segment (Can't see why myself, but there must be a reason, possibly for ease of addressing). He does this by loading the top and bottom 16 bits of _virt_to_phys in the appropriate parts of the gdt entries.

Code: Select all

At line 85

???mov eax,ebp
???mov [gdt2 + 2],ax
???mov [gdt3 + 2],ax
???shr eax,16
???mov [gdt2 + 4],al
???mov [gdt3 + 4],al
???mov [gdt2 + 7],ah
???mov [gdt3 + 7],ah
And if you look at the gdt entries you can see a brief clue as to what's going on. Namely that the 2 word and 4th and 7th bytes of the gdt entry are being set by the previous code so that they are no longer 0 and instead contain the linear address of the code segment's start.

Code: Select all

At line 474

; ring 0 kernel data segment descriptor
SYS_DATA_SEL???equ???$-gdt
gdt3:
???dw 0FFFFh
???dw 0??????; (base gets set above)
???db 0
???db 92h??????; present,ring 0,data,expand-up,writable
???db 0CFh
???db 0
The variable _virt_to_phys is marked as exported to the linker here, at the same place he reserves space for it.

Code: Select all

At line 419

EXPORT _virt_to_phys
???dd 0
So what happens is that he patches the base address of the selectors in the GDT to some more relevant value (For him) which makes the selector:offset address no longer correspond to a linear address starting at 0 (As I explained above) forcing him to correct addresses for operations that must be done on specific linear addresses. So things like read/writing the VGA will have to be corrected, as will things like reading the BIOS data block etc. If the operation doesn't involve some fixed, known, linear address then you shouldn't need to do the translation.

Hope that's helpful.

Curufir
BTW, you'll notice he has actually left himself a convenient way of accessing linear addresses without translation with a full 4gb selector starting at 0 (I'll leave you to figure out which it is).
Post Reply