简单的C内核char指针不起作用 [英] Simple C Kernel char Pointers Aren't Working

查看:97
本文介绍了简单的C内核char指针不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆