Я создаю загрузчик со ссылкой на this
У меня есть две проблемы относительно этого.
Когда я запускаю код на qemu, он никогда не переходит к функции switch_to_pm.
Когда я добавляю '.include load.s 'в файле main.s, то он застревает в ljmp
.
Может ли кто-нибудь дать мне какие-то указания по этому поводу?
main.s
section .data
MSG_PROT:
.asciz "Protected mode"
.section .text
.global start16
start16:
mov $0x9000, %bp
mov %bp, %sp
mov $'C', %al
mov $0x0E, %ah
int $0x10
call switch_to_pm
.code32
.type BEGIN_PM, @function
.global BEGIN_PM
BEGIN_PM:
lea MSG_PROT, %ebx
#call print_string_pm
. = start16 + 510
.word 0xaa55
load.s
.section .data
.include "gdt.S"
.section .text
.code16
.type switch_to_pm, @function
.global switch_to_pm
switch_to_pm:
mov $'Z', %al
mov $0x0E, %ah
int $0x10
cli
lgdt (gdt_descriptor)
mov %cr0, %eax
or $0x01, %eax
mov %eax, %cr0
ljmp $CODE_SEG, $init_pm
.code32
init_pm:
lea DATA_SEG, %ax
mov %ax, %ds
mov %ax, %ss
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov $0x90000, %ebp
mov %ebp, %esp
call BEGIN_PM
gdt.S
gdt_start:
.double 0x00000000
.double 0x00000000
gdt_code:
.word 0xffff #segment length or limit 00 -15
.word 0x0000 #segment base 00 - 15
.byte 0x00 #segment base 16 - 23
.byte 0b10011010 # flags (8 bit)
# Type : lower 4 bit
# from upper (11th bit) to lower (8th bit) in upper byte
# 1. code : 1 for code segment, since it is code segment
# 2. conforming : 0 , by not conforming means code in a segment with a lower privilege may not # call code , key to memory protection
# 3. Readable: 1, if readable , 0 for executable
# 4. accessed : 0, this is often used for debugging and virtual memory techniques.
# upper 4 bit ( from 15th bit to 11th bit)
# 1. present : 1 , since segment is present in the memory - used for virtual memory
# 2. DPL (privilige) : 0, ring 0 represent highestt privilige( occupies 2 bit)
# 3. Descriptor : 1 for code segment , 0 for data segment
.byte 0b11001111 # flags (8 bit)
# from 16th bit to 23 bit
# 1. lower 4 bit represent segment limit.
# 2. AVL : used for debugging. set it 0
# 3. L: set it for 64 bit. 0 , for 32 bit segment
# 4. D/b (default operation) : 1, for 32 bit operation, 0 for 16 bit operation
# 5. Granularity: 1, if set , this multiplies our limit by 4k, so 0xffff becomes 0xffff000, allowing segment to span 4 gb of memory
.byte 0x00
gdt_data:
.word 0xffff
.word 0x0000
.byte 0x00
.byte 0b10010010
.byte 0b11001111
.byte 0x00
gdt_end:
gdt_descriptor:
.word gdt_end - gdt_start - 1
.long gdt_start
.equ CODE_SEG, gdt_code - gdt_start
.equ DATA_SEG, gdt_data - gdt_start