为什么我的操作系统没有切换到保护模式

问题描述 投票:0回答:0

我开始完全用汇编创建一个操作系统,我想完全在实模式下完成它,但是当我意识到我所拥有的限制时,我决定在实模式下创建引导加载程序,在保护模式下创建内核 我尝试在引导加载程序中设置 gdt,但似乎不起作用。你能告诉我为什么吗?

这是代码

bootloader.asm:


bits 16

section .boot
global _start

KERNEL_ADDRESS equ 0x7E00

_start:
        cld
        xor  ax, ax
        mov  ds, ax
        mov  es, ax
        mov  ss, ax
        mov  sp, 9000h

        mov  di, 5        ; Allow 5 tries
    BOOT_TryNext:
        mov  dh, 0        ; CHS = (0,0,2), DL is drive number from BIOS
        mov  cx, 0002h
        mov  bx, 7E00h    ; ES:BX is buffer
        mov  ax, 0201h    ; BIOS.ReadDiskSector
        int  13h          ; -> AX CF
        jnc  BOOT_Loaded
        mov  ah, 00h      ; BIOS.ResetDiskSystem
        int  13h          ; -> AH CF
        dec  di
        jnz  BOOT_TryNext
    BOOT_Exit:
        
        call BOOT_notLoaded

        BOOT_Exit_Loop:
            cli
            hlt
            jmp  BOOT_Exit_Loop
    BOOT_Loaded:
        GDT_Start:
            null_descriptor:
                dd 0
                dd 0
            code_descriptor:
            dw 0xffff
            dw 0
            db 0
            db 10011010
            db 11001111
            db 0
            data_descriptor:
                dw 0xffff
                dw 0
                db 0
                db 10010010
                db 11001111
                db 0
        GDT_End:
        
        GDT_Descriptor:
            dw GDT_End - GDT_Start - 1
            dd GDT_Start

        CODE_SEG equ code_descriptor - GDT_Start
        DATA_SEG equ code_descriptor - GDT_Start

        cli
        lgdt [GDT_Descriptor]
        mov eax, cr0
        or eax, 1
        mov cr0, eax

        jmp CODE_SEG:boot_trampoline

        boot_trampoline:
            ; Setup dei segmenti per il kernel
            mov ax, DATA_SEG     ; Carica il segmento dati del kernel
            mov ds, ax
            mov es, ax
            mov fs, ax
            mov gs, ax

            ; Imposta lo stack pointer per il kernel
            mov ax, KERNEL_STACK_SIZE
            mov ss, ax
            mov sp, KERNEL_STACK_START

            ; Salta al kernel
            jmp KERNEL_ADDRESS

; Definisci le costanti per lo stack del kernel
KERNEL_STACK_SIZE equ 0x1000        ; Dimensione dello stack del kernel (4KB)
KERNEL_STACK_START equ 0x8000 - KERNEL_STACK_SIZE
    
    BOOT_notLoaded:
        pusha

        mov ax, 0x0700  ; function 07, AL=0 means scroll whole window
        mov bh, 0x07    ; character attribute = white on black
        mov cx, 0x0000  ; row = 0, col = 0
        mov dx, 0x184f  ; row = 24 (0x18), col = 79 (0x4f)
        int 10h         ; call BIOS video interrupt

        popa

        mov ah, 0x02
        xor bh, bh
        xor dx, dx
        int 10h

        mov si, boot_err
        mov ah, 0x0e
        boot_characterLoop2:
            lodsb
            or al, al
            jz BOOT_Exit_Loop
            int 10h

        jmp boot_characterLoop2

boot_msg: db "Il sistema operativo e' stato caricato correttamente!", 0
boot_err: db "Il sistema operativo non e' stato caricato correttamente!", 0

times 510-($-$$) db 0
dw 0xAA55

内核.asm:

bits 32

section .kernel
global _start_kernel

_start_kernel:
    mov al, 'A'
    mov ah, 0x0f
    mov [0xb8000], ax

链接器.ld:

OUTPUT_FORMAT(binary)
ENTRY(_start)

SECTIONS
{
    . = 0x7c00;

    bootloader :
    {
        bootloader.bin(.boot)
    }
    
    kernel :
    {
        kernel.bin(.kernel)
    }

    /DISCARD/ :
    {
        *(.bss*);
        *(COMMON*);
    }
}

生成文件:

boot = bootloader.asm
kernel = kernel.asm

boot_o = bootloader.bin
kernel_o = kernel.bin

bin = myos.bin

asm_compiler = nasm
qemu = qemu-system-i386

compile:
    $(asm_compiler) -f elf32 -g $(boot) -o $(boot_o)
    $(asm_compiler) -f elf32 -g $(kernel) -o $(kernel_o)
    ld -m elf_i386 -nmagic -T linker.ld -o $(bin) $(boot_o) $(kernel_o)

run:
    $(qemu) -fda $(bin)

clean:
    -rm $(boot_o)
    -rm $(kernel_o)
    -rm $(bin)
assembly protected osdev gdt
© www.soinside.com 2019 - 2024. All rights reserved.