Hop*_*Abc 4 c x86 pointers kernel osdev
我正在尝试使用C创建一个简单的内核.一切都加载并正常工作,我可以访问视频内存并显示字符,但是当我尝试实现一个简单的put函数由于某种原因它不起作用.我已经尝试了自己的代码和其他代码.此外,当我尝试使用在函数外声明的变量时,它似乎不起作用.这是我自己的代码:
#define PUTCH(C, X) pos = putc(C, X, pos)
#define PUTSTR(C, X) pos = puts(C, X, pos)
int putc(char c, char color, int spos) {
volatile char *vidmem = (volatile char*)(0xB8000);
if (c == '\n') {
spos += (160-(spos % 160));
} else {
vidmem[spos] = c;
vidmem[spos+1] = color;
spos += 2;
}
return spos;
}
int puts(char* str, char color, int spos) {
while (*str != '\0') {
spos = putc(*str, color, spos);
str++;
}
return spos;
}
int kmain(void) {
int pos = 0;
PUTSTR("Hello, world!", 6);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该spos(起始位置)的东西,因为我不能让全球定位变量.putc工作正常,但puts没有.我也试过这个:
unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
{
char *vidmem = (char *) 0xb8000;
unsigned int i=0;
i=(line*80*2);
while(*message!=0)
{
if(*message=='\n') // check for a new line
{
line++;
i=(line*80*2);
*message++;
} else {
vidmem[i]=*message;
*message++;
i++;
vidmem[i]=7;
i++;
};
};
return(1);
};
int kmain(void) {
k_printf("Hello, world!", 0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?我尝试将put实现与我的原生GCC(没有颜色和spos数据和使用printf("%c"))一起使用,并且它工作正常.
由于您通常遇到全局变量问题,因此问题很可能与链接器将"Hello World"字符串文字放在内存中的位置有关.这是因为字符串文字通常由链接器存储在全局内存的只读部分中......您还没有详细说明如何编译和链接内核,所以我会尝试类似下面的内容看看是否有效:
int kmain(void)
{
char array[] = "Hello World\n";
int pos = 0;
puts(array, 0, pos);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将在堆栈上分配字符数组而不是全局内存,并避免链接器决定放置全局变量的任何问题.
通常,在创建简单内核时,您希望将其编译并链接为平面二进制文件,而不依赖于外部OS库.如果您正在使用像GRUB这样的多引导兼容引导加载程序,您可能需要查看多引导规范页面中的简单示例代码.