32位保护模式下开发贪吃蛇OS无法绘制白色像素问题
32位保护模式下无法绘制像素的问题
我正在开发一款运行贪吃蛇的OS,当前处于32位保护模式,但无法在屏幕上绘制像素。实模式下切换到Mode 0x13(320x200x256色)模式后屏幕变黑,进入保护模式内核运行后,绘制的像素仍不显示。我参考了OSDev上的《Drawing_In_Protected_Mode》文章进行开发。以下是相关代码:
kernel.c
#include "display.h" // Include Display Drivers #include "constants.h" // Include constants that C doesn't have included #include "keyboard.h" // Include the custom keyboard driver void _start(){} // Remove LD Warning DisplayDetails globalDisplayDetails; // The display details. int main(){ // Init the display details DisplayDetails details = display_init(); globalDisplayDetails = details; bool running = true; while(running){ // This is the OS loop putpixel(100, 100, 0x00FFFFFF); } // return 0; }
display.h(显示驱动)
#define VRAM 0xA0000 typedef struct DisplayModeDetails { int width; // Width of one line of pixels int height; // Height of display in pixels int colors; // How many colors are supported int pitch; // How many bytes of VRAM to skip when going 1 pixel down int pixelWidth; // How many bytes of VRAM to skip when going 1 pixel right } DisplayDetails; struct DisplayModeDetails display_init(){ struct DisplayModeDetails details; // Setup display mode details details.width = 640; details.height = 480; details.colors = 16; details.pitch = 1; details.pixelWidth = 1; return details; } void putpixel(int pos_x, int pos_y, unsigned long VGA_COLOR) { unsigned char* location = (unsigned char*)0xA0000 + 320 * pos_y + pos_x; *location = VGA_COLOR; }
boot_sect.asm
[bits 16] [org 0x7C00] mov [BOOTDRIVE], dl ; call clear_screen ; Clear screen call load_kernel load_kernel: mov bx, KERNELOFFSET mov dh, 0x05 mov dl, [BOOTDRIVE] ; mov dl, 0x80 call clear_screen ; Clear Screen call disk_load ; Load From Disk mov ah, 0x00 ; Start setting video mode mov al, 0x13 ; 320x200 256 color graphics int 0x10 cli ; Disable Interrupts lgdt [gdt_descriptor] ; GDT start address mov eax, cr0 or eax, 1 mov cr0, eax ; Jump to Protected 32 bit mode jmp CODESEG:start_protected_mode jmp $ clear_screen: pusha mov ah, 0x07 ; Scroll al lines; 0 = all mov bh, 0x0f ; white on black mov cx, 0x00 ; row=0, col=0 mov dx, 0x184f ; row = 24, col = 79 int 0x10 ; Call interrupt mov ah, 0x02 mov dh, 0x00 mov dl, 0x00 mov bh, 0x00 int 0x10 popa ret disk_load: pusha push dx mov ah, 0x02 ; read mode mov al, dh ; read dh number of sects mov cl, 0x02 ; read from sect 2 (1 = boot) mov ch, 0x00 ; cylinder 0 mov dh, 0x00 ; head 0 int 0x13 jc disk_error pop dx cmp al, dh jne sectors_error popa ret disk_error: mov ah, '1' ; Error Code jmp err_loop sectors_error: mov ah, '2' ; Error Code jmp err_loop err_loop: call clear_screen mov dh, ah ; Print Error Message mov ah, 0x0e mov al, 'E' int 0x10 mov al, 'r' int 0x10 int 0x10 mov al, ' ' int 0x10 mov al, dh ; Print Error Code int 0x10 jmp $ ; create infinite loop ; Constants KERNELOFFSET equ 0x1000 CODESEG equ gdt_code - gdt_start DATASEG equ gdt_data - gdt_start gdt_start: dq 0x0 gdt_null: dd 0x0 dd 0x0 gdt_code: dw 0xffff dw 0x0 db 0x0 db 0b10011010 db 0b11001111 db 0x0 gdt_data: dw 0xffff dw 0x0 db 0x0 db 0b10010010 db 0b11001111 db 0x0 gdt_end: gdt_descriptor: dw gdt_end - gdt_start dd gdt_start [bits 32] start_protected_mode: ; Load the kernel mov ax, DATASEG mov dx, ax mov ss, ax mov es, ax mov fs, ax mov gs, ax mov ebp, 0x9000 mov esp, ebp call KERNELOFFSET jmp $ BOOTDRIVE db 0 ; Marking as bootable. times 510-($-$$) db 0 dw 0xaa55
kernel_entry.asm
[bits 32] [extern main] call main jmp $
构建测试脚本
gcc -m32 -fno-pie -ffreestanding -g -c kernel.c -o obj/main.o nasm -f elf kernel_entry.asm -o obj/entry.o nasm -f bin boot_sect.asm -o obj/boot.bin ld -m elf_i386 -o obj/kernel.bin -Ttext 0x1000 obj/main.o obj/entry.o --oformat binary cat obj/boot.bin obj/kernel.bin > bin/os.bin qemu-system-x86_64 -drive format=raw,file=bin/os.bin -display sdl
内容的提问来源于stack exchange,提问作者SKZI
相关产品推荐
相关产品推荐

