Перейти в ядро после перехода в защищенный режим в сборке
Мой первый вопрос здесь
Я работаю над простой операционной системой в 32-битном режиме (просто для удовольствия), но столкнулся с проблемой, которая заключается в том, что я не могу перейти к своему ядру после перехода в (32-битный) защищенный режим
Вот мой bootloader.asm
[ BITS 16 ]
[ ORG 0x7c00 ]
jmp start_boot
start_boot:
KERNEL_OFFSET equ 0x1000
mov [BOOT_DRIVE] , dl
mov bp , 0x9000
mov sp , bp
mov bx , MSG_REAL_MODE
call print
call load_kernel
mov ax , [0x1000]
mov word [reg16] , ax
call print_hex
call switch_to_pm
jmp $
[ BITS 16 ]
load_kernel :
mov bx , MSG_LOAD_KERNEL
call print
mov bx , KERNEL_OFFSET
mov dh , 15
mov dl , [BOOT_DRIVE]
call disk_load
ret
[ BITS 32 ]
;Including files
%include "bootloader/include/print_pm.asm"
%include "bootloader/include/print_hex_pm.asm"
start_pm:
mov ebx , MSG_PRO_MODE
call print_pm
mov ax , [0x1000]
mov word [reg16] , ax
call print_hex_pm
jmp $
jmp CODE_SEG:0x1000
;Including files
%include "bootloader/include/print.asm"
%include "bootloader/include/print_hex.asm"
%include "bootloader/include/disk.asm"
%include "bootloader/include/gdt.asm"
%include "bootloader/include/switch_to_pm.asm"
;Data
BOOT_DRIVE db 0
check db "check" , 0
MSG_LOAD_KERNEL db "loading Kernel" , 0
MSG_REAL_MODE db "Boot 16" , 0
MSG_PRO_MODE db "Boot 32 " , 0
;Padding
times 510- ($ -$$) db 0
dw 0xAA55
вместо
call KERNEL_OFFSET
Я использовал
jmp KERNEL_OFFSET:0x0
or
jmp CODE_SEG:KERNEL_OFFSET
но ни одна из этих работ
НО ЕСЛИ Я только что загрузил свое ядро без перехода в защищенный режим, оно работает
Кстати, вот мой disk.asm, включенный в bootloader.asm
disk_load:
push dx
mov ah , 0x02
mov al , dh
mov ch , 0x00
mov dh , 0x00
mov cl , 0x02
int 0x13
jc .error
pop dx
cmp dh , al
jne .error
ret
.error :
mov bx , Err
call print
call disk_load
;Data
Err db "Disk error" , 0
РЕДАКТИРОВАТЬ: все, что включено switch_to_pm.asm
[ BITS 16 ]
switch_to_pm:
CLI
LGDT [ gdtd ]
MOV EAX , CR0
OR EAX , 0x1
MOV CR0 , EAX
JMP CODE_SEG:init_pm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[ BITS 32 ]
init_pm:
MOV AX , DATA_SEG
MOV DS , AX
MOV ES , AX
MOV SS ,AX
MOV FS , AX
MOV GS , AX
MOV EBP , 0x90000
MOV ESP , EBP
CALL start_pm
gdt.asm
;GDT
gdt_start:
gdt_null:
dd 0x0 ; null descriptor
dd 0x0
; Offset 0x8 bytes from start of GDT: Descriptor code therfore is 8
gdt_code: ; code descriptor
dw 0xFFFF ; limit low
dw 0x0 ; base low
db 0x0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0x0 ; base high
; Offset 16 bytes (0x10) from start of GDT. Descriptor code therfore is 0x10.
gdt_data: ; data descriptor
dw 0xFFFF ; limit low (Same as code)
dw 0x0 ; base low
db 0x0 ; base middle
db 10010010b ; access
db 11001111b ; granularity
db 0x0 ; base high
;...Other descriptors begin at offset 0x18. Remember that each descriptor is 8 bytes in size?
; Add other descriptors for Ring 3 applications, stack, whatever here...
gdt_end:
gdtd:
dw gdt_end - gdt_start - 1 ; limit (Size of GDT)
dd gdt_start ; base of GDT
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
Извините за мои ошибки, так как я редактировал заголовок, добавил большинство из того, что включено, и попробовал Babysteps, и я использовал отладчик, и ядро загружено, так что в чем проблема
3 ответа
Можете ли вы вставить Bochs отладки или что-то? По моему опыту, вы можете lgdt
неправильный адрес. Иногда адрес неверный, иногда вы ошибаетесь в отношении лимита, проверьте его внимательно, это может помочь вам.
Слишком много кода скрыто в %include
файлы, чтобы увидеть, что на самом деле здесь происходит, Мохамед.
jmp CODE_SEG:KERNEL_OFFSET
должно работать, но я ожидаю, что это будет частью switch_to_pm
рутина.
Вы, кажется, игнорируете регистры сегментов, которые должны быть установлены! Я очень рекомендую http://www.osdev.org/ - начните с "маленьких шагов" и вернитесь к этому...
Причина, по которой мы запрашиваем все части, а не только "большую часть того, что включено", заключается в том, что мы можем воспроизвести именно то, что у вас есть, и делать это без особых хлопот. Мы пытаемся помочь вам в конце концов.
В любом случае, поскольку вы все еще не предоставили все (в частности, процедуры печати и собственно ядро), мне пришлось удалить некоторые вещи, чтобы собрать их без ошибок, и добавил мое простое ядро, состоящее из jmp $
, Я могу сказать вам, что он отлично работает с jmp CODE_SEG:KERNEL_OFFSET
и jmp KERNEL_OFFSET
и то и другое.