Linking and Loading

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
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Linking and Loading

Post by Neo »

I just can't understand this. It seems positively crazy. My kernel (plain binary) is linked to run at the 3GB+1MB and loaded at 1MB. The first function called is the one to disable IRQ's, the next function Remaps the PIC, only after this do i enable paging.
What i cant understand is how the first 2 functions are called correctly. I mean i never thought about this before because it was working. The objdump of my kstart.o file is here

Code: Select all

kstart.o:     file format coff-go32

Disassembly of section .text:

00000000 <start>:
   0:   e8 fb ff ff ff          call   0 <start>
   5:   e8 f6 ff ff ff          call   0 <start>
   a:   5b                      pop    %ebx   // saving bootloader info to ebx
   b:   e8 f0 ff ff ff          call   0 <start>
..........................
The third call is the one that enables paging. Now since my kernel is linked to run at 3GB+1MB these functions should have addresses in that range, they do as the kernel.map shows here

Code: Select all

Memory Configuration

Name             Origin             Length             Attributes
*default*        0x00000000         0xffffffff

Linker script and memory map

                0x00100000                physical=0x100000
                0xc0100000                virtual=(0xc0000000+physical)

.text           0xc0100000     0x5000 load address 0x00100000
                0xc0100000                kernstart=.
                0xc0100000                code=.
 *(.text)
 .text          0xc0100000       0x78 kstart.o
                0xc0100000                start
 .text          0xc0100078       0x3b pic.o
                0xc01000a7                EnableIRQ
                0xc0100078                RemapPIC
                0xc010009f                DisableIRQ
 *fill*         0xc01000b3        0x1
So I would expect the first 2 function calls to be something like

Code: Select all

call c010009f
call c0100078
Now comes the crazy part, the bochs debugger output of the start of my kernel is shown here

Code: Select all

Next at t=0
(0) context not implemented because BX_HAVE_HASH_MAP=0
[0x000ffff0] f000:fff0 (unk. ctxt): jmp f000:e05b             ; ea5be000f0
<bochs:1> lb 0x100000
<bochs:2> c
(0) Breakpoint 1, 0x100000 in ?? ()
Next at t=625082
(0) [0x00100000] 0008:00100000 (unk. ctxt): call 0010009f             ; e89a000000
<bochs:3> s
Next at t=625083
(0) [0x0010009f] 0008:0010009f (unk. ctxt): cli                       ; fa
<bochs:4> s
Next at t=625084
(0) [0x001000a0] 0008:001000a0 (unk. ctxt): push EAX                  ; 50
<bochs:5> s
Next at t=625085
(0) [0x001000a1] 0008:001000a1 (unk. ctxt): mov AL, ff                ; b0ff
<bochs:6> s
Next at t=625086
(0) [0x001000a3] 0008:001000a3 (unk. ctxt): out 21, AL                ; e621
<bochs:7> dump_cpu
eax:0xff
ebx:0x84c2
ecx:0xffff0000
edx:0x3f2
ebp:0x1f90006
esi:0x8327
edi:0xf2f
esp:0x9bff0
eflags:0x46
eip:0x1000a3
cs:s=0x8, dl=0xffff, dh=0xcf9a00, valid=1
ss:s=0x10, dl=0xffff, dh=0xcf9300, valid=5
ds:s=0x10, dl=0xffff, dh=0xcf9200, valid=1
es:s=0x10, dl=0xffff, dh=0xcf9300, valid=1
fs:s=0x10, dl=0xffff, dh=0xcf9300, valid=1
gs:s=0x10, dl=0xffff, dh=0xcf9300, valid=1
ldtr:s=0x0, dl=0x0, dh=0x0, valid=0
tr:s=0x0, dl=0x0, dh=0x0, valid=0
gdtr:base=0xf00, limit=0x2f
idtr:base=0x0, limit=0x3ff
dr0:0x0
dr1:0x0
dr2:0x0
dr3:0x0
dr6:0xffff0ff0
dr7:0x400
tr3:0x0
tr4:0x0
tr5:0x0
tr6:0x0
tr7:0x0
cr0:0x60000011
cr1:0x0
cr2:0x0
cr3:0x0
cr4:0x0
inhibit_mask:0
done
<bochs:8> s
Next at t=625087
(0) [0x001000a5] 0008:001000a5 (unk. ctxt): pop EAX                   ; 58
<bochs:9> s
Next at t=625088
(0) [0x001000a6] 0008:001000a6 (unk. ctxt): ret_near                  ; c3
<bochs:10> s
Next at t=625089
(0) [0x00100005] 0008:00100005 (unk. ctxt): call 00100078             ; e86e000000
How the heck is it being called at its physical address? I mean thats what i want but can't understand how its happening.
Only Human
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Linking and Loading

Post by Candy »

calls are relative. As long as you don't chop anything up or use absolute addresses (absolute jump, data) you can **** up the linking any which way and it'll still work. Look at the bytecode, it says E9 9A 00 00 00, which is a call 9A forward (from its end).
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:Linking and Loading

Post by Neo »

Oh! so the only waythat would have screwed up was if i had done something like

Code: Select all

call CODE_SEL:EnableIRQ
?
Only Human
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Linking and Loading

Post by Candy »

Neo wrote: Oh! so the only waythat would have screwed up was if i had done something like

Code: Select all

call CODE_SEL:EnableIRQ
?
That would be a valid way to screw up. Another is trying to print a text to screen, just search for people that can do anything normally but can't access data. 1/3 is not including .rodata and 2/3 is screwing up linking.

Note, it's not valid what you do. But, it can be explained why it does work. Same with using a bike to win the race-to-the-finish when the rest has to run, pretty obvious that you win. But, you don't comply to the rules.
Post Reply