我从头开始制作一个C内核,我实际上只是从网站上复制了这段代码,因为我的代码没有用,所以我很困惑。
void kmain(void)
{
const char *str = "my first kernel";
char *vidptr = (char*)0xb8000; //video mem begins here.
unsigned int i = 0;
unsigned int j = 0;
/* this loops clears the screen
* there are 25 lines each of 80 columns; each element takes 2 bytes */
while(j < 80 * 25 * 2) {
/* blank character */
vidptr[j] = ' ';
/* attribute-byte - light grey on black screen */
vidptr[j+1] = 0x07;
j = j + 2;
}
j = 0;
/* this loop writes the string to video memory */
while(str[j] != '\0') {
/* the character's ascii */
vidptr[i] = str[j];
/* attribute-byte: give character black bg and light grey fg */
vidptr[i+1] = 0x07;
++j;
i = i + 2;
}
return;
}
当我运行我的内核时,它会在屏幕上打印一个S而不是其他内容。我知道我的内核正在启动,因为如果我这样做了
vidptr[0] = 'h';
vidptr[2] = 'e';
vidptr[4] = 'l';
vidptr[6] = 'l';
vidptr[8] = 'o';
它按预期工作。发生了什么事?
编辑:我的代码可能会加载内核(可能没有设置一些寄存器)所以我只会查看grub和其他内容。答案 0 :(得分:0)
尝试将volatile关键字与变量
一起使用参考页面:http://wiki.osdev.org/Printing_To_Screen
// note this example will always write to the top
// line of the screen
void write_string( int colour, const char *string )
{
volatile char *video = (volatile char*)0xB8000;
while( *string != 0 )
{
*video++ = *string++;
*video++ = colour;
}
}
答案 1 :(得分:0)
出于某种原因,如果我使用char str[] = "blabla";
代替char *str = "blabla";
,则可以使用。
答案 2 :(得分:0)
首先,您是在跳转内核之前还是在运行函数之前设置了SP?如果还没有,请妥善设置。在你的启动函数中,你应该设置堆栈指针DS,SS;您可以在程序开头使用内联汇编。另外,char * p = "Something"
应使用char var [] = "Something"
或
char var[10];
var[1] = 'S';
var[2] = 'o';
或
char var[] = { 'S', 'o', 'm', 'e', ..., '\0' } ;
我的bootloader建立GDT并将switcthing转换为32位模式并跳转(jmp 0x8:0x8000
)这里0x8
是我在GDT中的代码段地址,0x10是DS,SS;所以它跳转到内核。在我没有设置SS之前,SP,DS和我无法打印,所以我写了这个小代码:
[bits 32]
MOV AX, 0x10 ; 0x10 points at the new data selector
MOV DS, eax
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
MOV eax, 0x200000
MOV esp, eax
并使用nasm
对其进行编译,并使用HEX编辑器程序手动添加到内核程序的开头。