This message was edited by lateef at 2005-11-12 0:55:35
This message was edited by lateef at 2005-11-12 0:52:19
: : : : This message was edited by bogdanul2003 at 2005-10-30 3:12:44
: : : : I'm using a bootloader that loads a number of sectors begining with the 2 sector at the address 1000h:100h.I use it to load a program that initiate pmode.Before entering pmode I run some real mode instructions that work well using my bootloader.The problem apears when doing the far jump to change the selector in the cs jmp 0x10:pmode where 0x10 refers to a segment descriptor that has the base at 0 and the limit of 4 GB.The initialization of the pmode using the same code works perfect if I put the code on the first sector and is executed at boot time(offset 0x7c00) without my bootloader.I don't understand why when loaded at 1000h:100h the CPU resets when doing the far jump.
: : : :
: : : : Can you tell me what is wrong?
: : : : 10x
: : : :
: : :
: : : Maybe it is something like this:
: : :
: : : When you are executing a far jump (jmp 0x10:pmode) the 'pmode' part probably gets calculated like:
: : : offset of the pmode label + the number in the ORG xxxxh (if any)
: : :
: : : Even if your bootloader copies the code to some other location, the compiler still calculates the address in the same way.
: : : You could probably adjust it manually. (like: jmp 0x10:10100h+offset of pmode)
: : :
: :
: : Well, ORG can be used in the middle of code too, not only before start:.
: : That might be the problem. You are changing from 0 based addressing(7c00h:0) to 100h based addressing(1000h:100h), did you consider this?
: :
: : You should post your code, bogdanul, Its hard to analyse all this without any.
: :
:
:
: Here is the code that gets loaded at 1000h:100h and works when loaded at offset 0x7c00(nasm syntax).Take a look at how I calculate the base of the GDT that is puted in gdtr.Should I calculate that address at runtime?
:
: [BITS 16]
: : [ORG 0x100]
: :
: : start:jmp initpmode
: :
: : ;********************************************************
: : initpmode:xor eax,eax
: : mov ax,cs
: : mov ds,ax
: : mov ah, 00h
: : mov al, 3h
: : int 10h
: :
: : cli
: : lgdt [gdtr]
: : mov eax,cr0
: : or al,0x1
: : mov cr0,eax
: : jmp 0x10: protected
: :
: : [BITS 32]
: :
: :
: : protected:mov ax,0x8
: : mov ds,ax
: : mov es,ax
: : mov ss,ax
: : mov esp,0x7C00
: :
: : mov dx,3F2h
: : mov al,0
: : out dx,al
: :
: : mov word [0xB8000],0x8258
: : mov ax,0x18
: : mov es,ax
: : mov word [es:2],0x8258
: :
: : jmp $
: :
: :
: : gdt: dw 0x0000, 0x0000, 0x0000, 0x0000
: : sys_data: dw 0xFFFF, 0x0000, 0x9200, 0x00CF
: : sys_code: dw 0xFFFF, 0x0000, 0x9A00, 0x00CF
: : sys_video: dw 0x0FA0
: : dw 0x8000
: : db 0x0b
: : db 0x92
: : db 0x40
: : db 0
: : gdt_end:
: :
: : gdtr: dw gdt_end - gdt - 1
: : dd gdt
:
:
Did not consider your ORG defination earlier! Reviewed what I posted.
1. The code you are trying to jump to is in the region
1000h:0100h
which is equivalent to linear address
10000h + 0100h = 00010100h
2. Since the addresses in your code are computed with an
offset equal to 100h ( See [ORG 0x100] ), All you need is
a descriptor with a base address of 00010000h.
3. Define a descriptor whose base address is equivalent to this.
4. Use it for your jump.
You could redefine your gdt with an extra descriptor like this:
gdt: dw 0x0000, 0x0000, 0x0000, 0x0000
sys_data: dw 0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code: dw 0xFFFF, 0x0000, 0x9A00, 0x00CF
sys_video: dw 0x0FA0
dw 0x8000
db 0x0b
db 0x92
db 0x40
db 0
sys_fix: dw 0xFFFF, 0x0000, 0x9A01, 0x00CF
gdt_end:
Then modify your jump to:
jmp 0x28: protected