address in PMode

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
drizzt

address in PMode

Post by drizzt »

[attachment deleted by admin]
Tim

Re:address in PMode

Post by Tim »

You need to specify an origin, otherwise the assembler or linker won't know what values to write to the output file when you refer to a variable. If you don't want to bind your image to a certain address, you might want to look at the relocation records supported by formats such as COFF, PE and ELF.
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:address in PMode

Post by Pype.Clicker »

the idea behind relocations is the following: with your binary code, you receive a list of offsets where position-dependent places are. All you have to do to get a relocated image is

Code: Select all

for (r=reloc_entries;r<reloc_entries+nbrelocs;r++) {
    *(dword*)(image+r.offset)+=base;
}
so for instance

Code: Select all

org 0x8000000 ;; assume default loading @8MB
msg: db 'Hello World'
start:
  mov esi, msg
  mov al, PRINT_SYSCALL
  int SYSCALL
  mov al, EXIT_SYSCALL
  int SYSCALL
will be assembled something like

Code: Select all

.data: 
08000000:    H e l l o   W o r l d 
.text
0800000b    msi_imm 00 00 00 08
08000010    mal_imm 01
08000012    cc            80
08000014    mal_imm 02
08000016    cc            80
...
your relocation list one single entry [080000b]
When relocating, you'll compute the difference between the requested address (0x0800.0000) and the effective load address (0x1234.5678) and add it to each entry

thus your program will look like

Code: Select all

0x12345678 : H e l l o   W o r l d
0x12345683 : mi 78 56 34 12
0x12345688 : mi 01
0x1234568a : cc  80
...
If you don't like relocating, you can use an ORG 0 and create a specific data & code segment for your program ;)
drizzt

Re:address in PMode

Post by drizzt »

Thanks a lot for your posts pype & tim... I will try one of these solutions a.s.a.p.
drizzt

Re:address in PMode

Post by drizzt »

[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:address in PMode

Post by Pype.Clicker »

by "creating specific" etc. i meant creating a code descriptor with base address = program load address and run it in this segment (a bit like DOS .com program worked) and do the same with the data segment.
drizzt

Re:address in PMode

Post by drizzt »

OK, this was my first idea, but I had thought that it was not the best way to relocate code... Now I think that I will do so.

My aim is to execute code in extended memory... I wrote a real mode kernel but in real mode you can't do this, because CS segment is limited by a 16 bit offset (IP). So I would like to switch in protected mode, step by step, from my real mode kernel...

Maybe it's not the best way to realize a good kernel, but probably it's a good way to learn something about this difficult kind of programming...

So you must expect million questions from a PMode newbie... ;D
drizzt

Re:address in PMode

Post by drizzt »

Ufff... this problem makes me dizzy... I try to update data & code selectors before jumping to the extended memory location but it continues to give me problems...

Well... first I load my image program at 0x200000 (2MB), then in my kernel I write:

Code: Select all

...

; Update code & data selectors
mov   eax, 0x200000   ;<-- absolute address of the program image
mov   [gdt_data+2], ax
mov   [gdt_code+2], ax
shr   eax, 16
mov   [gdt_data+4], al
mov   [gdt_code+4], al
mov   [gdt_data+7], ah
mov   [gdt_code+7], ah

; Jump to the memory location 0x200000
jmp   CODE_SEL:0
And here is my GDT:

Code: Select all

gdt:    dw 0                    ; limit 15:0
        dw 0                    ; base 15:0
        db 0                    ; base 23:16
        db 0                    ; access byte (descriptor type)
        db 0                    ; limit 19:16, flags
        db 0                    ; base 31:24
DATA_SEL        equ     $-gdt
gdt_data:
   dw 0xFFFF      ; Limit/Length
   dw 0         ; Base 0
   db 0         ; Base 0
        db 0x92             ; present, ring 0, data, expand-up, writable
   db 0xCF         ; page-granular, 32-bit
   db 0         ; Base 0
CODE_SEL   equ   $-gdt
gdt_code:
   dw 0xFFFF      ; Limit/Length
   dw 0         ; Base 0
   db 0         ; Base 0
   db 10011110b      ; P=1, DPL=0, DT=0, ?, Code: conforming, exec/read (1,0,0,1,1110)
   db 0xCF         ; G=1, D=1, 0, AVL=0, 1111=F: Limit/Length (1,1,0,0,1111)
   db 0         ; Base 0
REAL_CODE_SEL   equ   $-gdt
   dw 0xFFFF      ; Limit/Length
   dw 0         ; Base 0
   db 0         ; Base 0
   db 0x9A         ; P=1, DPL=0, DT=0, ?, Code: conforming, exec/read (1,0,0,1,1110)
   db 0
   db 0         ; Base 0
gdt_end:
Why it doesn't work?! I mistake if modify GDT in this manner?
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:address in PMode

Post by Pype.Clicker »

ouch ouch ouch !

You need to know that changes made to the GDT are commited to cpu only when the segment registers are re-loaded (they hold a cached version of the actual base & limit ...)
so you'll at least need a

Code: Select all

mov ds,PROG_DATA_SEL
jmp PROG_CODE_SEL:0
Moreover, i suggest you use separate selectors for kernel & program codes...
drizzt

Re:address in PMode

Post by drizzt »

ok... it was a stupid problem ::), but there's another error; if I don't use a jmp far when I jump to the program in extended memory it doesn't work. It seems to me strange... I thought that a simple jmp was ok to update code selector... and then it do a triple fault when my application (in ext mem) do an int instruction... maybe there's a problem also in the IDT... well I will have to study my IDT better. Thanks a lot for now...
Curufir

Re:address in PMode

Post by Curufir »

drizzt wrote: ...if I don't use a jmp far when I jump to the program in extended memory it doesn't work. It seems to me strange... I thought that a simple jmp was ok to update code selector...
HelpPC:
JMP - Unconditional Jump

Usage: JMP target
Modifies flags: None

Unconditionally transfers control to "label". Jumps by default are within -32768 to 32767 bytes from the instruction following the jump. NEAR and SHORT jumps cause the IP to be updated while FAR jumps cause CS and IP to be updated.


Unless you explicitly do a far jump the code segment isn't changed. I think you can do the same thing with a RETF after pushing selector (Certainly can with segments in real mode) and ip onto the stack, but I haven't tried it yet.

Curufir
drizzt

Re:address in PMode

Post by drizzt »

Yes, but if I write jmp CODE_SEL:0 I think that it's automatically assembled with a far jump.

P.S. I forgot to say that I'm using NASM 0.98 for windows.
drizzt

Re:address in PMode

Post by drizzt »

[attachment deleted by admin]
Post Reply