OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Mar 19, 2019 7:43 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Jump into protected mode is fail[solved]
PostPosted: Mon Mar 11, 2019 12:41 pm 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 111
Good day!

I have problem with my bootloader. If I enter into protected mode, qemu is reboot. Please where is bug?
Code:
bits 16

start:
  mov ax, 07C0h  ;set data segment
  mov ds, ax     ;load number into register
  mov sp, 4096   ;set stack pointer

  ;set VESA graphic mode
  mov ax, 0x4F02  ;set VBE
  mov bx, 0x4103  ;set graphic mode 800x600 256 colours
  int 0x10  ;start BIOS interrupt

  ;LOAD KERNEL
  ;reset floppy
  mov ah, 0
  mov dl, 0
  int 13h  ;call reset

  ;read floppy
  mov ax, 1000h  ;load kernel to 1000h
  mov es, ax  ;load kernel to 1000h
  mov bx, 0  ;segment 0

  mov ah, 0x02  ;read function
  mov al, 100  ;100 sectors
  mov ch, 1  ;track 1
  mov cl, 2  ;start sector is 2
  mov dh, 0  ;head 0
  mov dl, 0  ;floppy A

  int 13h  ;call read

  jmp load_gdt

  ;global descriptor table
  gdt:

  gdt_null:
  dq 0

  gdt_code:
  dw 0FFFFh
  dw 0

  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:
   db gdt_end - gdt
   dw gdt

  ;load gdt
  load_gdt:
    cli
    xor ax, ax
    mov ds, ax
    lgdt [gdt_desc]

  ;jump into protected mode
  mov eax, cr0
  or eax, 1
  mov cr0, eax
  jmp 0x0008:clear_pipe

  ;NOW WE ARE IN PROTECTED MODE
  bits 32
  clear_pipe:
    mov ax, 0x0010
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

  mov esp, 090000h  ;set stack pointer

  ;JUMP TO EXECUTE KERNEL!
  jmp 0x1000:0x0

times 510-($-$$) db 0 ;Pad remainder of boot sector with 0s
dw 0xAA55  ;The standard PC boot signature


Last edited by Klakap on Sat Mar 16, 2019 2:15 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 1:04 pm 
Offline

Joined: Sun Nov 23, 2008 5:56 am
Posts: 21
Location: Russia, Saint-Petersburg
gdt_desc:
dw gdt_end - gdt
dd gdt


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 1:07 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 166
And the long jump at the end... you are in protected mode. That long jump does not mean what you think it means. You are trying to jump into code segment 0x1000, which you don't have in the GDT, so that will raise a GPF.


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 2:25 pm 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 111
Thank you for replies, but I have still problem. qemu is reboot after
Code:
  mov eax, cr0
  or eax, 1
  mov cr0, eax


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 3:11 pm 
Offline
User avatar

Joined: Fri Mar 01, 2019 3:50 pm
Posts: 6
Location: France
Correct me if I'm wrong, but this part
Code:
    mov ax, 0x0010
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

is not at the right place, since you don't have segments in protected mode. Segmentation is a concept that only exists in real mode, but not in protected or long mode. You must put that part before actually setting the "Protected Mode Enable" bit in the Control Register (see https://en.wikipedia.org/wiki/Control_register).

Since there's no segmentation, the instruction
Code:
jmp 0x1000:0x0
has to be instead
Code:
jmp 0x10000
, or whatever location you loaded your kernel at.


Last edited by crosssans on Mon Mar 11, 2019 3:16 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 3:14 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 373
One of the reasons I don't like the tutorial that this comes from because it creates more headaches for people that use it when they want to enter protected mode. The top of the file is where all the badness starts:
Code:
bits 16

start:
  mov ax, 07C0h  ;set data segment
  mov ds, ax     ;load number into register
By itself there is nothing wrong with this, BUT if you want to put an address in the GDT record it has to be relative to the beginning of physical memory and not the beginning of the segment. So this:
Code:
gdt_desc:
   db gdt_end - gdt
   dw gdt
places the address of gdt in gdt_desc. The address of gdt is relative to the beginning of the segment 0x7c0 not the beginning of memory. To make it relative to the beginning of memory you have to add 0x7c00. You also make the mistake of making the length a byte rather than a word so it should be dw gdt_end - gdt -1(the size also should have 1 subtracted from it) and dw gdt should have originally been dd gdt. Your gdt_desc should look like:
Code:
gdt_desc:
   dw gdt_end - gdt - 1
   dd gdt + 0x7c00
I have fixed up the address of gdt by using dd 0x7c00+gdt . Unfortunately you have the same problem with the FAR JMP getting into protected mode. It too needs fixing up so it would be
Code:
jmp 0x0008:(clear_pipe+0x7c00)
but then any addresses you use in clear_pipe have to be adjusted. You also have this code that sets DS to 0:
Code:
load_gdt:
    cli
    xor ax, ax
    mov ds, ax
    lgdt [gdt_desc]
You can't do this since gdt_desc is relative to the beginning of the segment, not the beginning of physical memory.Since I've made the address adjustments above it should be:
Code:
load_gdt:
    cli
    lgdt [gdt_desc]
Since you loaded the kernel at 0x1000:0x0000 and you are now in 32-bit protected mode at the point you do this:
Code:
;JUMP TO EXECUTE KERNEL!
  jmp 0x1000:0x0
you have the problem that 0x1000:0x0000 is a real mode segmented address.You just need a JMP to the linear address that 0x1000:0x0000 represents. The linear address of 0x1000:0x0000 is (0x1000<<4)+0x0000=0x10000. So what you really need is
Code:
;JUMP TO EXECUTE KERNEL!
  jmp 0x08:0x10000
You could have also used a near 32-bit jump but it has to be adjusted by the same value 0x7c00 again which would be
Code:
jmp 0x10000-0x7c00
. All this adjusting of addresses is very messy though,and could have been avoided if we set ORG to 0x7c00 and DS to 0 at the start. Since 0x0000:0x7c00 and linear address 0x07c00 point to the same place we can avoid all the address fixups and do this in a more sane fashion:
Code:
org 0x7c00         ; Use an ORG relative to beginning of physical memory
bits 16

start:
  xor ax, ax       ;set data segment to 0
                   ;    since we use ORG 0x7c00 ((0x0000<<4)+0x7c00)=0x07c00
  mov ds, ax
  mov ss, ax
  mov sp, 0x7c00   ;set stack pointer just below bootloader out of the way at 0x0000:0x7c00

  ;set VESA graphic mode
  mov ax, 0x4F02  ;set VBE
  mov bx, 0x4103  ;set graphic mode 800x600 256 colours
  int 0x10  ;start BIOS interrupt

  ;LOAD KERNEL
  ;reset floppy
  mov ah, 0
  mov dl, 0
  int 13h  ;call reset

  ;read floppy
  mov ax, 1000h  ;load kernel to 0x1000:0x0000
  mov es, ax  ; Set segment to 0x1000
  mov bx, 0  ; and offset to 0

  mov ah, 0x02  ;read function
  mov al, 100  ;100 sectors
  mov ch, 1  ;track 1
  mov cl, 2  ;start sector is 2
  mov dh, 0  ;head 0
  mov dl, 0  ;floppy A

  int 13h  ;call read

  jmp load_gdt

  ;global descriptor table
  gdt:

  gdt_null:
  dq 0

  gdt_code:
  dw 0FFFFh
  dw 0

  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

  ;load gdt
  load_gdt:
    cli
    lgdt [gdt_desc]

  ;jump into protected mode
  mov eax, cr0
  or eax, 1
  mov cr0, eax
  jmp 0x0008:clear_pipe

  ;NOW WE ARE IN PROTECTED MODE
  bits 32
  clear_pipe:
    mov ax, 0x0010
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

  mov esp, 090000h  ;set stack pointer

  ;JUMP TO EXECUTE KERNEL!
  jmp 0x10000

times 510-($-$$) db 0 ;Pad remainder of boot sector with 0s
dw 0xAA55  ;The standard PC boot signature


Last edited by MichaelPetch on Mon Mar 11, 2019 4:26 pm, edited 6 times in total.

Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 4:06 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 373
On top of my now heavily edited last comment, I wanted to point out this
Code:
mov ah, 0x02  ;read function
  mov al, 100  ;100 sectors
  mov ch, 1  ;track 1
  mov cl, 2  ;start sector is 2
  mov dh, 0  ;head 0
  mov dl, 0  ;floppy A

  int 13h  ;call read
I'm not sure if your intention was to start on Track 1 or not. CHS=(0,1,2) as you are using it is NOT the sector after the master boot record. Track numbers start at 0 (unlike sector numbers). If your intention was to load sectors starting at the first sector right after the bootloader then CHS should be (0,0,2) and the code would be:
Code:
mov ah, 0x02  ;read function
  mov al, 100  ;100 sectors
  mov ch, 0  ;track 0
  mov cl, 2  ;start sector is 2
  mov dh, 0  ;head 0
  mov dl, 0  ;floppy A

  int 13h  ;call read
Of course if your kernel is placed further down the disk image at CHS=(0,1,2) then you can ignore this entire comment. It should be noted that when the BIOS passes control to your bootloader it put the boot drive in DL. If you use the value in DL passed by the bootloader rather than hard coding it to 0, you can boot off different drive numbers and not have to adjust the code. The same goes with hard coding DL to zero when resetting the disk.


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Mon Mar 11, 2019 4:50 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 373
crosssans wrote:
Correct me if I'm wrong, but this part
Code:
    mov ax, 0x0010
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

is not at the right place, since you don't have segments in protected mode. Segmentation is a concept that only exists in real mode, but not in protected or long mode.
Protected mode doesn't use segment:offset addressing, but the segment registers become a selector instead. Updating the selectors to point to the DATA descriptor in the GDT is correct. The GDT he wrote has the data descriptor at offset 0x10 so setting the selectors to 0x10 is okay and this is properly done in protected mode.


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 10:18 am 
Offline
User avatar

Joined: Fri Mar 01, 2019 3:50 pm
Posts: 6
Location: France
MichaelPetch wrote:
Protected mode doesn't use segment:offset addressing, but the segment registers become a selector instead. Updating the selectors to point to the DATA descriptor in the GDT is correct. The GDT he wrote has the data descriptor at offset 0x10 so setting the selectors to 0x10 is okay and this is properly done in protected mode.

Apologies then! :?


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 12:01 pm 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 111
Very thank for you comments! Now is jumping into protected mode good. But I have new error with:(I use org as you recommended me)
Code:
jmp 0x0008:clear_pipe

clear_pipe:
  mov ax, 0x0010
  mov ds, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  mov ss, ax


After this is qemu reboot. If I delete it, qemu is after jumping into kernel get fatal error TGC. Please where is problem?


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 12:15 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 373
If you had done everything else properly the problem is not here:
Code:
jmp 0x0008:clear_pipe

clear_pipe:
  mov ax, 0x0010
  mov ds, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  mov ss, ax
You will have to show us all the code that is now failing for you. Likely something else is causing your issue and any failure here is just a symptom.


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 12:19 pm 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 111
Here is my code:

Code:
org 0x7c00  ;beginning of physical memory
bits 16

start:
  xor ax, ax       ;set data segment to 0
                   ;since we use ORG 0x7c00 ((0x0000<<4)+0x7c00)=0x07c00
  mov ds, ax
  mov ss, ax
  mov sp, 0x7c00   ;set stack pointer just below bootloader out of the way at 0x0000:0x7c00

  mov ax, 07C0h  ;Set data segment to where we're loaded
  mov ds, ax

  ;set VESA graphic mode
  ;mov ax, 0x4F02  ;set VBE
  ;mov bx, 0x4103  ;set graphic mode 800x600 256 colours
  ;int 0x10  ;start BIOS interrupt

  ;LOAD KERNEL
  ;reset floppy
  mov ah, 0
  mov dl, 0
  int 13h  ;call reset

  ;read floppy
  mov ax, 1000h  ;load kernel to 1000h
  mov es, ax  ;load kernel to 1000h
  mov bx, 0  ;offset 0

  mov ah, 0x02  ;read function
    mov al, 100  ;100 sectors
    mov ch, 0  ;track 1
    mov cl, 2  ;start sector is 2
    mov dh, 0  ;head 0
    mov dl, 0  ;floppy A

  int 13h  ;call read

  jmp load_gdt

  ;global descriptor table
  gdt:

  gdt_null:
  dq 0

  gdt_code:
  dw 0FFFFh
  dw 0

  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

  ;load gdt
  load_gdt:
    cli
    lgdt [gdt_desc]

  ;jump into protected mode
  mov eax, cr0
  or eax, 1
  mov cr0, eax
  jmp 0x0008:clear_pipe

  ;NOW WE ARE IN PROTECTED MODE
  bits 32
  clear_pipe:
    mov ax, 0x0010
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

  mov esp, 090000h  ;set stack pointer

  ;JUMP TO EXECUTE KERNEL!
  jmp 0x10000
  ;hlt  ;for debug

times 510-($-$$) db 0 ;Pad remainder of boot sector with 0s
dw 0xAA55  ;The standard PC boot signature


//EDIT
I have sometimes this error in qemu:
Code:
qemu-system-i386: Trying to execute code outside RAM or ROM at 0x457e0000


Or other number.


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 12:31 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 373
It fails because you need to remove these lines:
Code:
mov ax, 07C0h  ;Set data segment to where we're loaded
  mov ds, ax
The code just above it sets DS to zero since you are now using ORG 0x7c00. Setting DS to 0x07c0 only works if you leave off the ORG (or use ORG 0x0000)


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 1:25 pm 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 111
Very thank you! Now is it good, but I have one little problem. After jumping into kernel, qemu say error
Code:
qemu-system-i386: Trying to execute code outside RAM or ROM at 0x457e0000


Please why?


Top
 Profile  
 
 Post subject: Re: Jump into protected mode is fail
PostPosted: Tue Mar 12, 2019 1:57 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 373
The only way it will fail at this point (assuming you used the exact code) is that the kernel wan't properly read into 0x1000:0x0000 (linear address 0x10000) or your kernel has a bug. You don't show the code of the kernel you are reading so I can't help. Another concern I have is that some BIOSes may not handle reading 100 sectors at once. I know BOCHS will choke on reading more than 72. I'd try reading in the minimum number needed for the kernel you have (keep it under <= 17 sectors if you can for test purposes). If the problem is in your kernel itself then you would have to provide that code in your post as well. I highly recommend using BOCHS and its debugger to work on issues this early in your kernel development.


Last edited by MichaelPetch on Tue Mar 12, 2019 2:33 pm, edited 2 times in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group