我正在开发一个定制的操作系统,并使用GRUB引导加载程序来加载我的内核。在我的开发过程中,我遇到了一个问题,我无法将显示模式从文本模式切换到图形模式。尽管将GRUB配置为在图形模式(1024 x768 x32)下启动,但系统在引导期间似乎仍处于文本模式。
下面提供了汇编 Bootstrap 和我尝试使用图形模式的内核部分:; bootloader.asm
[bits 32]
section .multiboot
align 4
dd 0x1BADB002 ; Multiboot magic number
dd 0x00 ; Flags
dd -(0x1BADB002 + 0x00) ; Checksum (must be such that all the dword sums to zero)
section .bootstrap_stack
align 16
stack_bottom:
times 16384 db 0 ; Declare a stack of 16KB
stack_top:
section .text
extern kmain ; This should be in your kernel code
global start
start:
mov esp, stack_top ; Set up the stack
call kmain ; Call the main function in the kernel
cli ; Disable interrupts
.hang:
hlt ; Halt the CPU
jmp .hang ; Infinite loop just in case
字符串
我的kernel.c文件看起来像://kernel.c
#define VIDEO_MEMORY 0xA0000
void print(char *str, int x, int y) {
volatile char *video = (volatile char*)(0xB8000 + 2*x + 160*y);
while (*str != 0) {
*video = *str;
video += 2;
str++;
}
}
#define VIDEO_MEMORY 0xA0000
void fill_screen(unsigned char color) {
unsigned char* video_memory = (unsigned char*)VIDEO_MEMORY;
int i;
for (i = 0; i < 320 * 200; i++)
video_memory[i] = color;
}
void draw_pixel(int x, int y, unsigned char color) {
unsigned char* video_memory = (unsigned char*)VIDEO_MEMORY;
int offset = y * 320 + x;
video_memory[offset] = color;
}
void fillRect(int x, int y, int width, int height, unsigned char color) {
unsigned char* video_memory = (unsigned char*)0xA0000;
int i, j;
for (i = y; i < y + height; i++) {
for (j = x; j < x + width; j++) {
draw_pixel(x+i,y+j, color);
}
}
}
void kmain() {
print("hello", 0, 0);
fill_screen(0x0F); // Fill the screen with white color (0x0F)
draw_pixel(160, 100, 0x0); // Draw a black pixel at (160, 100)
fillRect(5,10,20,20,0xFF);
uint8_t* framebuffer = (uint8_t*)0xA0000; // Replace with your framebuffer address
unsigned int bytes_per_pixel = 3; // Replace with your bytes per pixel
unsigned int bytes_per_scanline = 1920; // Replace with your bytes per scanline
unsigned int x = 10; // The x coordinate of the pixel
unsigned int y = 10; // The y coordinate of the pixel
uint8_t* pixel_address = framebuffer + y * bytes_per_scanline + x * bytes_per_pixel;
pixel_address[0] = 0xFF; // Red
pixel_address[1] = 0x00; // Green
pixel_address[2] = 0x00; // Blue
}
型
下面是我的grub.cfg文件中的配置:
set default=0
set timeout=0
menuentry "My OS" {
multiboot /boot/myos.bin
set gfxpayload=1024x768x32
insmod all_video
boot
}
型
在我的内核中,我实现了一个打印函数,它将文本打印到屏幕上。我的期望是,如果系统成功地切换到图形模式,这个函数将失败,因为它是为文本模式设计的。但是,打印功能的工作方式就好像系统仍处于文本模式,这表明系统从未切换到图形模式。
我已经在几个虚拟机和物理机上尝试了这个设置,我一直遇到同样的问题。我目前使用的是GRUB 2.06版本。
尽管在GRUB配置中进行了指定,但为什么没有切换到图形模式,这让我很困惑。任何建议或指针将不胜感激!
请记住将注解“更多绘图函数”和“更多绘图代码”替换为您正在使用的实际绘图函数和代码。这将帮助其他人更准确地诊断您的问题。
1条答案
按热度按时间gxwragnw1#
您可以使用Multiboot2标头中的framebuffer标记来更改分辨率,而不是grub.cfg中的gfxpayload。
为此,在checksum之后添加以下内容:
字符串
另外,不要忘记0xA0000的限制为64,000字节,并且您可以在32 BPP下绘制最大16,000像素。