16 到 32 保护模式 BIOS 任务的概念验证

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

我一直想展示我的 i386 实验室在过去一年的研究中是如何进行的。这个主题是我在 NASM 论坛上的帖子的延续,可以在下面的链接中找到 https://forum.nasm.us/index .php?topic=3828.0

在这里,我正在寻找一个简洁的 kernel.asm 文件来完成基本任务,其中包括一个通用的保护模式来执行 BIOS 模式调用(在本例中为模式 13 设置视频)。我主要担心的是,当我尝试在模式段之间添加小部分时,我的 gdb 对象调试会发生巨大变化。这个模型理论上看起来像这样(Use32 => Real mode => protected16 => rm BIOS calls => protected32)

现在我的问题是与这些段之间的跳转相关的 BIOS/pmode 设置容器。这里我有测试代码,当我尝试为键盘输入添加标准代码时,您可以在其中观察目标文件的路径效果。 所以有没有其他人经历过这个。我真的希望我没有把自己逼到墙角,所以我很乐意通过你的回应继续这个对话。如果有人想要完整测试的配置文件副本,也请告诉我。 干杯!

这里是kernel.asm的运行代码

``
;[ORG 0x7E00]

%define BUILD_GDT_DESC(bounds,base,access,flags) \
((( base & 0x00FFFFFF) << 16) | \
(( base & 0xFF000000) << 32) | \
( bounds & 0x0000FFFF) |        \
(( bounds & 0x000F0000) << 32) | \
(( access & 0xFF) << 40) |      \
(( flags & 0x0F) << 52))        

TSS_IO_MAP_SIZE     EQU 0x400/8


%define REBASE_ADDRESS(A)  (0x7E00 + ((A) - BIOS32_PREP))

[BITS 16]

section .data

ROWS    EQU 25
COLS1   EQU 80

section .text

_prep_module2:
;   jmp _prep_module2_

[bits 32]
BIOS32_PREP:use32
    pusha
    ; save current esp to edx
    mov edx, esp
    ; jumping to 16 bit protected mode
    ; disable interrupts
    cli
    ; clear cr3 by saving cr3 data in ebx register
    xor ecx, ecx
    mov ebx, cr3
    mov cr3, ecx
    ; load new empty GDT
    lgdt [REBASE_ADDRESS(bios32_gdt_ptr)]
;    lgdt [REBASE_ADDRESS(gdt32Ptr)]
    ; load new empty IDT
    lidt [REBASE_ADDRESS(bios32_idt_ptr)]
    ; jump to 16 bit protected mode


    jmp 0x30:REBASE_ADDRESS(__protected_mode_16)
;    jmp code16_post:REBASE_ADDRESS(__protected_mode_16)


; 16 bit protected mode
__protected_mode_16:use16
    ; jumping to 16 bit real mode
    mov ax, 0x38
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    ; turn off protected mode
    ; set bit 0 to 0
    mov eax, cr0
    and al,  ~0x01
    mov cr0, eax
    jmp 0x0:REBASE_ADDRESS(__real_mode_16)

; 16 bit real mode
__real_mode_16:use16
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov sp, 0x8c00
    ; enable bios interrupts to call
    sti
    ; save current context, all general, segment registers, flags
    pusha
    mov cx, ss
    push cx
    mov cx, gs
    push cx
    mov cx, fs
    push cx
    mov cx, es
    push cx
    mov cx, ds
    push cx
    pushf
    ; get current stack pointer & save it to current_esp
    mov ax, sp
    mov edi, current_esp
    stosw
    ; load our custom registers context
    mov esp, REBASE_ADDRESS(bios32_in_reg16_ptr)
    ; only use some general register from the given context
    popa
    ; set a new stack for bios interrupt
    mov sp, 0x9c00
    ; call immediate interrupt opcode to execute context
    pusha

    jmp bios32_GraphicCtrlA

;TestCode
;keyboardCtrlA:
;.loopstep1:
;   mov ah,01h
;   int 16h
;   jz .loopstep1
;
;   call GraphicPrint
;
;   mov ah,00h
;   int 16h
;
;   cmp ah,48h
;   jnz .SetOn
;   cmp dl,0
;   jz .SetOn
;   dec dl
;
;SetOn:
;
;   cmp ah,50h
;   jnz .SetOff
;   cmp dl,24
;   jz .SetOff
;   inc dl
;
;SetOff:
;
;   cmp ah,48h
;   jnz .SetNotLeft
;   cmp dh,0
;   jz .SetNotLeft
;   dec dh  
;
;.SetNotLeft:
;
;   cmp ah,4Dh
;   jnz .SetNotRight
;   cmp dh,39
;   jz .SetNotRight
;   inc dh  
;
;.SetNotRight:
;
;   call GraphicPrint
;   jmp graphic_function2




bios32_GraphicCtrlA:
; will be bios interrupt number passed
    ; put the actual interrupt number here
;   db 0xCD
;    db 0x10
;   db 0x01

    mov ax,0x13
    
    int 0x10
;graphic_function2:

;   call bios32_int_number_ptr
    mov dh,1
    mov dl,1
    call GraphicPrint

;   jmp loopstep1
    popa
    mov ax,0x13
    
    int 0x10
    
    jmp poll_function

GraphicPrint:
    mov cx,0A000h
    mov es,cx
;   mov ax

    push dx

    mov ax,8
    mul dh
    mov bp,ax

    mov ax,8*320
    mov bx,0
    add bl,dl
    mul bx
    add bp,ax

    pop dx

    mov si,GraphicA
    mov cl,8
    
PrintGraphicY:
    push bp

    mov ch,8

PrintGraphicX:
    mov al,[ds:si]
    xor al,[es:bp]
    mov [es:bp],al
    inc si
    inc bp
    dec ch
    jnz PrintGraphicX

    pop bp
    add bp,320
    dec cl
    jnz PrintGraphicY
;   mov sp,dx
;GraphicCtrlRet:
    hlt

;   popa
    ret
;   jmp poll_function
;   jmp GraphicCtrlRet
;   ret

GraphicA:
    db 00h,00h,0Eh,0Eh,0Eh,0Eh,00h,00h  
    db 00h,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,00h
    db 0Eh,0Eh,03h,0Eh,0Eh,03h,0Eh,0Eh
    db 0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh
    db 0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh,0Eh
    db 0Eh,0Eh,02h,0Eh,0Eh,02h,0Eh,0Eh
    db 00h,0Eh,0Eh,02h,02h,0Eh,0Eh,00h
    db 00h,00h,0Eh,0Eh,0Eh,0Eh,00h,00h




poll_function:
    ; get our output context here
    mov esp, REBASE_ADDRESS(bios32_out_reg16_ptr)
    add sp, 28 ; restore stack used for calling our context
    ; save current context, all general, segment registers, flags
    pushf
    mov cx, ss
    push cx
    mov cx, gs
    push cx
    mov cx, fs
    push cx
    mov cx, es
    push cx
    mov cx, ds
    push cx
    pusha
    ; restore the current_esp to continue
    mov esi, current_esp
    lodsw
    mov sp, ax
    ; restore all current context, all general, segment registers, flags
    popf
    pop cx
    mov ds, cx
    pop cx
    mov es, cx
    pop cx
    mov fs, cx
    pop cx
    mov gs, cx
    pop cx
    mov ss, cx
    popa

;    jmp _prep_module2_
    

    ; jumping to 32 bit protected mode
    ; set bit 0 in cr0 to 1
;testGate:
    lgdt[gdt32Ptr]
    mov eax, cr0
;   inc eax
    or eax,1
    mov cr0, eax
;   smsw eax
;    jmp 0x08:REBASE_ADDRESS(__protected_mode_32)
 ;   jmp 0x10:REBASE_ADDRESS(__protected_mode_32)
        
_prep_module2_:
    cld
    cli

    in al,0x92
    or al,2
    out 0x92,al

;   mov [saved_segment],ds

;   lidt[Idtpipe32]
;   jmp code32_post:REBASE_ADDRESS(__protected_mode_32)
    jmp code32_post:__protected_mode_32
    
;   jmp 0x08:REBASE_ADDRESS(__protected_mode_32)
;   jmp 0x10:REBASE_ADDRESS(__protected_mode_32)


; 32 bit protected mode
__protected_mode_32:use32
;    mov ax, 0x10
    mov ax,data32_post
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
;    mov ss, ax
    ; restore cr3
    mov cr3, ebx
    ; restore esp
    mov esp, edx

;    sti
    popa

    hlt
    jmp $
.loopcheck:
    hlt
    jmp .loopcheck

;    ret


__padding:
    db 0x0
    db 0x0
    db 0x0
bios32_gdt_entries:
    ; 8 gdt entries
    resb 64
bios32_gdt_ptr:
    dd 0x00000000
    dd 0x00000000
bios32_idt_ptr:
    dd 0x00000000
    dd 0x00000000
bios32_in_reg16_ptr:
    resw 14
bios32_out_reg16_ptr:
    dd 0xaaaaaaaa
    dd 0xaaaaaaaa
    dd 0xaaaaaaaa
    dd 0xaaaaaaaa
    dd 0xaaaaaaaa
    dd 0xaaaaaaaa
    dd 0xaaaaaaaa
current_esp:
    dw 0x0000





section .data 

gdt32:
    dq BUILD_GDT_DESC(0,0,0,0)
gdt32code:
    dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1100b)
gdt32data:
    dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1100b)
gdt16code:
    dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1000b)
gdt16data:
    dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1000b)

    ;gdt16tss:dq BUILD_GDT_DESC(0x8230,TSS_SIZE-1,10001001b,0000b) & 0 << 22
gdt32tss:
    dq BUILD_GDT_DESC(TSS_SIZE-1,0x8280,10001001b,0000b)
;   dq BUILD_GDT_DESC(TSS_SIZE-1,0x9260,10001001b,0000b)    
.stub1:

    code32_post: equ gdt32code -gdt32
    data32_post: equ gdt32data -gdt32
;.stub:
    code16_post: equ gdt16code -gdt32
    data16_post: equ gdt16data -gdt32

    tss32_post: equ gdt32tss -gdt32
    
    gdt32Len: equ $-gdt32   
    gdt32Ptr: dw gdt32Len-1
        dd gdt32


align 4
;vidmem_ptr: dd VIDEO_TEXT_ADDR
pm_str: db 'protected mode string ',0
pm_str_length: equ $-pm_str
vm_str: db 'virtual',0
;vidmem_address: dw 0

;resb 512
times 512 db 0

align 16
tss:
.back_link:     dd 0
.esp0:          dd 0
.ss0:           dd 0
.esp1:          dd 0
.ss1:           dd 0
.esp2:          dd 0
.ss2:           dd 0
.cr3:           dd 0
.eip:           dd 0
.eflags:        dd 0
.eax:           dd 0
.ecx:           dd 0
.edx:           dd 0
.ebx:           dd 0
.esp:           dd 0
.ebp:           dd 0
.esi:           dd 0
.type2:         dd 0
.es:            dd 0
.cs:            dd 0
.ss:            dd 0
.ds:            dd 0
.fs:            dd 0
.gs:            dd 0
.ldt:           dd 0
.trap:          dw 0
.iomap_base:    dw 0

.iomap: TIMES TSS_IO_MAP_SIZE db 0x00

%if TSS_IO_MAP_SIZE > 0
.iomap_pad:db 0xff

%endif
.end:
TSS_SIZE: EQU tss.end -tss

align 4

ColorTable: db 00h,01h,02h,03h,04h,05h,06h,07h
            ;db 10h,11h,12h,13h,14h,15h,16h,17h
            db 38h,39h,3Ah,3Bh,3Ch,3Dh,3Eh,3Fh
ColorTableSize: equ $-ColorTable

save_cr0    dd 0
save_cr3    dd 0
saved_segment   resd 0
gate_voucher    dw 1

;X  dd 0
;Y   dd 0
;color_pkg  dw 5

section .bss
align 16 
;ring0_proc_stack: resb RING0_PROC_STACK_SIZE
ring0_proc_stack_placer:

align 4
save_esp:   resd 1`
save_ss:    resd 1`


``
assembly x86 nasm protected-mode
© www.soinside.com 2019 - 2024. All rights reserved.