简单的C内核char指针不起作用 [英] Simple C Kernel char Pointers Aren't Working
问题描述
我正在尝试使用C创建一个简单的内核.所有内容都可以加载并正常工作,并且我可以访问视频内存并显示字符,但是当我出于某种原因尝试实现简单的puts函数时,则无法正常工作.我已经尝试了自己的代码和其他代码.另外,当我尝试使用在函数外部声明的变量时,它似乎不起作用.这是我自己的代码:
I am trying to make a simple kernel using C. Everything loads and works fine, and I can access the video memory and display characters, but when i try to implement a simple puts function for some reason it doesn't work. I've tried my own code and other's. Also, when I try to use a variable which is declared outside a function it doesn't seem to work. This is my own code:
#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;
}
spos
(起始位置)的原因是因为我无法创建全局位置变量. putc
正常工作,但puts
无效.我也尝试过这个:
The spos
(starting position) stuff is because I can't make a global position variable. putc
works fine, but puts
doesn't. I also tried this:
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;
}
为什么这行不通?我尝试将puts实现与本机GCC一起使用(没有颜色和spos数据,并使用printf("%c")
),效果很好.
Why doesn't this work? I tried using my puts implementation with my native GCC (without the color and spos data and using printf("%c")
) and it worked fine.
推荐答案
由于一般来说全局变量存在问题,因此问题很可能与链接器放置"Hello World"字符串的位置有关字面量在内存中.这是由于以下事实:链接器通常将字符串文字存储在全局内存的只读部分中....您尚未详细说明如何编译和链接内核,因此我将尝试以下操作和看看是否可行:
Since you're having an issue with global variables in general, the problem most likely has to-do with where the linker is placing your "Hello World" string literal in memory. This is due to the fact that string literals are typically stored in a read-only portion of global memory by the linker ... You have not detailed exactly how you are compiling and linking your kernel, so I would attempt something like the following and see if that works:
int kmain(void)
{
char array[] = "Hello World\n";
int pos = 0;
puts(array, 0, pos);
return 0;
}
这将在堆栈而不是全局内存上分配字符数组,并避免链接程序决定放置全局变量的任何问题.
This will allocate the character array on the stack rather than global memory, and avoid any issues with where the linker decides to place global variables.
通常,当创建一个简单的内核时,您希望将其编译为一个平面二进制文件并将其链接,而不依赖于外部OS库.如果您使用的是兼容GRUB的多引导兼容引导加载程序,则可能需要查看
In general, when creating a simple kernel, you want to compile and link it as a flat binary with no dependencies on external OS libraries. If you're working with a multiboot compliant boot-loader like GRUB, you may want to look at the bare-bones sample code from the multiboot specification pages.
这篇关于简单的C内核char指针不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!