C内核打印字符串不起作用

时间:2015-05-30 22:56:52

标签: c kernel

我从头开始制作一个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和其他内容。

3 个答案:

答案 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编辑器程序手动添加到内核程序的开头。