C 字符数组始终为空。内核开发

C char array always empty. Kernel development

我正在编写 32/64 位内核。我遇到一个奇怪的问题,当我尝试将 const char*char *char [] 传递给函数时,数组始终为空。

例如,

我有一个 kmain 可以执行 gdt、idt、isrs、irq、视频和定时器初始化,然后当我写的时候:

 test_func("test");

test_func(char * string)调试代码:

void test_func(char * string)
{
    if(string[0] == '[=11=]'){
        putch('n');
    }else{
        putch('o');
    }
}

我总是在屏幕上显示 'n'。

如果我测试:

 if (string == NULL){
       putch('n');
 }else{
       putch('o');
       putch(string[0]);
 }

我得到的 o 没有字符串

的第一个字符

为了链接和编译,我使用

ld -m i386linux -T linker/link.ld  -nostdlib  -o kern.my ../obj/start.o \
                      ../obj/main.o \
                      ../obj/scrn.o \
                       ../obj/gdt.o \
                       ../obj/idt.o \
                      ../obj/isrs.o \
                       ../obj/irq.o \
                     ../obj/timer.o \
                        ../obj/io.o \
                     ../obj/yshell.o \
                        ../obj/kb.o

我正在使用 Qemu i386

测试 kern.my

[链接描述文件]

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

我将 Qemu 与 GDB 一起使用,我的信息注册:

eax            0x1  1
ecx            0x0  0
edx            0x3d5    981
ebx            0x9500   38144
esp            0x104fe0 0x104fe0
ebp            0x0  0x0
esi            0x0  0
edi            0x108000 1081344
eip            0x100356 0x100356
eflags         0x6  [ PF ]
cs             0x8  8
ss             0x10 16
ds             0x10 16
es             0x10 16
fs             0x10 16
gs             0x10 16

它是 != NULL 的事实让我觉得你在某处访问内存很糟糕 - 可能有一个变量接近正在传递的字符串的 mallocing。

我不记得常量字符串是如何存储在机器代码中的 - 但我认为它的完成方式类似,只是使用动态的 C 管理的内存管理。

因此请检查以确保您的数组永远不会写出它们的边界等。 当您 运行 单独文件中的代码时,还要验证您是否获得 -expected- 输出?

你还可以 post 测试[-1]和测试[1] is/evaluates,它们是否一致 运行?

问题出在我的链接描述文件上。

我正在使用 (.rodata) ,将其更改为 (.rodata*) 修复问题

rodata 是 ELF 文件中存储可显示字符串的部分,链接器假定它应该转到偏移量 0,而整个内核链接在 0x100000

GCC places global variables marked as const in a separate section, called .rodata. The .rodata is also used for storing string constants.

Since contents of .rodata section will not be modified, they can be placed in Flash. The linker script has to modified to accomodate this.