problem in protected mode

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
shahzad

problem in protected mode

Post by shahzad »

in the following code when i changed base addresse of code descriptor
to 1000h insted of 0000h , nothing gets printed and system just restarts.
can you explain what's the problem.

"my loader code is"

Code: Select all


[bits 16]
[ORG 0xC7c00]

jmp 0000:start
start:
   mov ax,cs  ;initialize the data segment
   mov ds,ax
   mov es,ax
   
   mov ax,3   ;clear screen
   int 10h

resetFloppy:
   mov ah,0
   int 13h
   jc resetFloppy

;now read the kernel from the floppy
readFloppy:
        ;es:bx==> 1000:0000h
        mov ax,1000h
   mov es,ax
        mov bx,0
   
   mov ah,2
   mov al,1   ;load 1 sectors
   mov ch,0   ;cylinder=0
   mov cl,3   ;sector=3
   mov dh,0   ;head=0
   mov dl,0   ;floppy drive
   int 13h    ;read it
   jc readFloppy

jmp 0x1000:0x0000         ;jmp now


times 510- ($-$$) db 0
dw 0AA55h

"my kernel code is"

Code: Select all



[BITS 16]       ; We need 16-bit intructions for Real mode

 start:
        
cli                     

  
        lgdt [gdt_desc]         

        mov eax, cr0           
        or eax, 1              
        mov cr0, eax           

        jmp 08h:clear_pipe      

[BITS 32]                       
clear_pipe:
        mov ax, 10h            
        mov ds, ax              
        mov ss, ax             
        mov esp, 090000h        

        mov byte [ds:0B8000h], 'T'      
        mov byte [ds:0B8001h], 1Bh      

hang:
        jmp hang                ; Loop, self-jump


gdt:                    

gdt_null:               ; Null Segment
        dd 0
        dd 0

gdt_code:               
        dw 0FFFFh
        dw 1000h
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0

gdt_end:                



gdt_desc:                       
        dw gdt_end - gdt - 1    
        dd gdt                 


"my script file for jloc linker is"

Code: Select all

ALL:
   system1.o

VLOAD: 1000 0 0
*
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:problem in protected mode

Post by Pype.Clicker »

1. it looks to me that you defined 64K-wide segments, so trying to access 0xb8000 from the data segment will not work. (Though i might get wrong on this as i didn't took the time to decode your binary fields and assumed i was remembering correctly the GDT fields order).

2. the base for your code segment is wrong. By setting the code at real-mode address 0x1000:0000, you should use 0x10000 as the base, rather than 0x1000. Check the recent post about linear addresses for explanations.

btw, i suggest you rather keep the base 0 and use an [org 10000] instruction instead ... hmm ... though your 16 bits part may not like it at all :(
shahzad

Re:problem in protected mode

Post by shahzad »

rather i should say the problem occurs when i change first 16 bits of base address of code descriptor to 1000h.

in other words i'm trying to set the base limit of code descriptor to 10000000h instead of 00000000h
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:problem in protected mode

Post by Pype.Clicker »

hey! you may not load something to 0x1000000 in real mode ! you'll need either unreal mode or to copy things using BIOS extended memory copy or something ...

I think you should either use GRUB or go back to a realmode/protected mode tutorial ...
shahzad

Re:problem in protected mode

Post by shahzad »

in almost every code or tutorial that i've looked has set the base adresses of their segments to 0.

but when i tried to change that address to something else (0x1000000 for code segment) my PC is rebooting.
can u help me how to do it or point out the error in above given code.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:problem in protected mode

Post by Neo »

[q]
;now read the kernel from the floppy
readFloppy:
;es:bx==> 1000:0000h
mov ax,1000h
   mov es,ax
mov bx,0
...
jmp 0x1000:0x0000 ;jmp now
[/q]
If you want to read the the kernel file to the address 0x1000:0000h then you have to use
[tt]
mov ax,100h   ; this becomes 1000h internally
mov es,ax
mov bx,0
...
jmp   0x1000:0x0 ; this jumps to 0x10000:0x0
[/tt]
just remember that the processor shifts the base address by 4 bits to get the intended segment's base address. I think you should follow Pype's adivce on keeping the base 0 and using a different offset as it avoids this mix-up.
          Regards NEO.
Only Human
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:problem in protected mode

Post by Pype.Clicker »

uh oh ... i start being completely confused, and i fear Neo is a bit wrong. Let's try to clarify ...

Please guys, use the "0x1234:0x5678" notation only to refer real mode segment:offset addressing, thus when the physical address actually is 0x12340+0x5678 = 0x0001_79b8.

If you want to talk about long (32bits) physical (or linear) addresses, use something else than ':' to split things (for instance, Tim uses '_' and i align on him to improve readability. We could have used ',' aswell)

the first byte after 64K is then at 0x0001_0000 which can be accessed with 0x1000:0000 (i.e. load ES with 0x1000 and bx with 0x0000).
The first byte after 1MB is at 0x0010_0000 and can only be accessed when A20 gate is on with 0xFFFF:0x0010 (as you cannot load anything higher than 0xFFFF in a segment register, we need to compensate with a small offset, even for the first byte. This is all explained in Perica's tutorial)

0x0100_0000 is 16MB. You cannot access that in real mode. 0x1000_0000 is (hmm, lemme compute) 256MB and it cannot be accessed in real mode either. Even in protected mode, you shouldn't assume 0x1000_0000 is available unless you explicitly checked the amount of available memory or have paging installed.

Hope this will help.
Post Reply