перейти к ядру после перехода в защищенный режим в сборке

Мой первый вопрос здесь

Я работаю над простой операционной системой в 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, и я использовал отладчик, и ядро ​​загружено, так в чем проблема


person Mohamed Anwar    schedule 27.05.2013    source источник
comment
Сделайте все файлы доступными и исправьте вводящий в заблуждение заголовок. Что касается проблемы, убедитесь, что вы знаете, где ваше ядро ​​загружено в карте памяти защищенного режима. Также научитесь пользоваться отладчиком.   -  person Jester    schedule 28.05.2013


Ответы (3)


Слишком много кода спрятано в %include файлах, чтобы понять, что здесь происходит на самом деле, Мохамед.

jmp CODE_SEG:KERNEL_OFFSET должно работать, но я ожидаю, что это будет частью switch_to_pm рутины.

Похоже, вы игнорируете сегментные регистры, которые необходимо настроить! Я настоятельно рекомендую http://www.osdev.org - начните с "маленьких шагов" и вернитесь к нему. ...

person Frank Kotler    schedule 28.05.2013
comment
Спасибо, Мохамед. Это помогает, но, боюсь, я все еще не вижу проблемы. Поскольку у вас загружено cs, просто jmp KERNEL_OFFSET должно работать. Перезарядка cs не должна повредить. Подпрограмма чтения с диска загружает сектор 2 (и последующие) в es:bx. На самом деле мы не видим, что такое es, но я ДУМАЮ, что это то же самое, что и ds (вы можете сделать это явно - не повредит - должно быть равно нулю). Я предполагаю, что ваше ядро ​​на самом деле находится в секторе 2. Извините, я ничем не могу вам помочь ... - person Frank Kotler; 29.05.2013

Причина, по которой мы запрашиваем все части, а не только «большую часть того, что включено», заключается в том, чтобы мы могли воспроизвести именно то, что у вас есть, и сделать это без особых хлопот. В конце концов, мы пытаемся вам помочь.

В любом случае, поскольку вы еще не предоставили все (в частности, процедуры печати и собственно ядро), мне пришлось удалить некоторые вещи, чтобы собрать его без ошибок, и добавил мое простое ядро, состоящее из файла jmp $. Я могу вам сказать, что он отлично работает с jmp CODE_SEG:KERNEL_OFFSET и jmp KERNEL_OFFSET обоими.

person Jester    schedule 28.05.2013

Можете ли вы вставить отладку bochs или что-то в этом роде? По моему опыту, вы можете lgdt неправильный gdt. Иногда адрес неправильный, иногда gdt ошибается с лимитом, внимательно проверьте gdt, это может вам помочь.

person Community    schedule 02.06.2013