OSDev.org https://forum.osdev.org/ |
|
Jump into protected mode is fail[solved] https://forum.osdev.org/viewtopic.php?f=1&t=33574 |
Page 1 of 2 |
Author: | Klakap [ Mon Mar 11, 2019 12:41 pm ] |
Post subject: | Jump into protected mode is fail[solved] |
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 |
Author: | quirck [ Mon Mar 11, 2019 1:04 pm ] |
Post subject: | Re: Jump into protected mode is fail |
gdt_desc: dw gdt_end - gdt dd gdt |
Author: | nullplan [ Mon Mar 11, 2019 1:07 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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. |
Author: | Klakap [ Mon Mar 11, 2019 2:25 pm ] |
Post subject: | Re: Jump into protected mode is fail |
Thank you for replies, but I have still problem. qemu is reboot after Code: mov eax, cr0
or eax, 1 mov cr0, eax |
Author: | crosssans [ Mon Mar 11, 2019 3:11 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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.
|
Author: | MichaelPetch [ Mon Mar 11, 2019 3:14 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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 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: start: mov ax, 07C0h ;set data segment mov ds, ax ;load number into register Code: gdt_desc: 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: db gdt_end - gdt dw gdt Code: gdt_desc: 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 dw gdt_end - gdt - 1 dd gdt + 0x7c00 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: 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:cli xor ax, ax mov ds, ax lgdt [gdt_desc] Code: load_gdt: Since you loaded the kernel at 0x1000:0x0000 and you are now in 32-bit protected mode at the point you do this:cli lgdt [gdt_desc] Code: ;JUMP TO EXECUTE KERNEL! 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 jmp 0x1000:0x0 Code: ;JUMP TO EXECUTE KERNEL! 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 jmp 0x08:0x10000 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 |
Author: | MichaelPetch [ Mon Mar 11, 2019 4:06 pm ] |
Post subject: | Re: Jump into protected mode is fail |
On top of my now heavily edited last comment, I wanted to point out this Code: mov ah, 0x02 ;read function 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: 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 Code: mov ah, 0x02 ;read function 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.
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 |
Author: | MichaelPetch [ Mon Mar 11, 2019 4:50 pm ] |
Post subject: | Re: Jump into protected mode is fail |
crosssans wrote: Correct me if I'm wrong, but this part 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.
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. |
Author: | crosssans [ Tue Mar 12, 2019 10:18 am ] |
Post subject: | Re: Jump into protected mode is fail |
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! |
Author: | Klakap [ Tue Mar 12, 2019 12:01 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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? |
Author: | MichaelPetch [ Tue Mar 12, 2019 12:15 pm ] |
Post subject: | Re: Jump into protected mode is fail |
If you had done everything else properly the problem is not here: Code: jmp 0x0008:clear_pipe 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.
clear_pipe: mov ax, 0x0010 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax |
Author: | Klakap [ Tue Mar 12, 2019 12:19 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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. |
Author: | MichaelPetch [ Tue Mar 12, 2019 12:31 pm ] |
Post subject: | Re: Jump into protected mode is fail |
It fails because you need to remove these lines: Code: mov ax, 07C0h ;Set data segment to where we're loaded 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)
mov ds, ax |
Author: | Klakap [ Tue Mar 12, 2019 1:25 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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? |
Author: | MichaelPetch [ Tue Mar 12, 2019 1:57 pm ] |
Post subject: | Re: Jump into protected mode is fail |
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. |
Page 1 of 2 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |