Kernel 我的操作系统内核在D中:一些嵌入式字符串不';行不通

Kernel 我的操作系统内核在D中:一些嵌入式字符串不';行不通,kernel,d,boot,bootloader,portable-executable,Kernel,D,Boot,Bootloader,Portable Executable,我知道这是一个很难回答的问题,主要是因为有太多的事情可能是错误的,很难把事情弄清楚。但我会尽可能多地提供信息;希望这会有帮助 我开始使用D语言和数字Mars D编译器编写自己的内核,在花了很多时间研究如何生成可重新定位的平面二进制文件后,我终于想到为地址0xc000000生成一个普通PE文件,并用字节0x90(NOP操作码)替换其所有头。这工作得非常好,我能够在屏幕上写东西,设置分页,进入保护模式,等等。当然,在基于16位程序集的引导加载程序的帮助下,我做得非常好 一切都很好,也就是说,我决定移

我知道这是一个很难回答的问题,主要是因为有太多的事情可能是错误的,很难把事情弄清楚。但我会尽可能多地提供信息;希望这会有帮助

我开始使用D语言和数字Mars D编译器编写自己的内核,在花了很多时间研究如何生成可重新定位的平面二进制文件后,我终于想到为地址
0xc000000
生成一个普通PE文件,并用字节
0x90
(NOP操作码)替换其所有头。这工作得非常好,我能够在屏幕上写东西,设置分页,进入保护模式,等等。当然,在基于16位程序集的引导加载程序的帮助下,我做得非常好

一切都很好,也就是说,我决定移植D运行时库以在我的内核中使用。我设法提取了库的一个子集,并对其进行了修改,以便将其编译到我的应用程序中。然后我运行我的程序。(注意:我根本没有使用库;我的代码是启动后执行的第一个代码——发生的第一件事是将
“内核”
打印到屏幕上,在此之前没有调用任何运行时代码。)

D数组(因此是字符串,因为字符串只是一个
char[]
)不过是一个带有指针和大小成员的结构,因此在32位系统中,它将是8字节大。有趣的是,当我运行我的程序时,结构的成员显示为零——也就是说,指针和大小都为零。(我通过在屏幕上打印指针的值以及长度成员来验证这一点——两者都是零。)我一删除运行时的源代码(无论如何都没有执行过),它们就工作得很好

我将其缩小为两种可能性:

  • 堆栈设置不正确:我排除了这一点,因为在没有运行库的情况下一切正常,并且我通过分解文件确认在我的代码之前没有执行任何其他代码

  • PE文件部分有一点很有趣:我检查了一下,发现运行时版本中有两个TLS(线程本地)变量。果然,当我让它们共享(而不是线程本地)时,我的代码工作了!然而,当我调用我在不同文件中编写的代码时,我的代码仍然显示出相同的问题——只有
    kernel.d
    ,它是启动文件,正确地使用字符串;在其他文件中,数组再次为零

  • 现在,有人能猜到为什么会发生这种情况吗

    如果需要更多的信息,我很乐意发布


    谢谢大家!

    首先,免责声明:我对D一无所知

    第二,另一个免责声明:基于“PE文件”一词的使用,我猜你在使用Windows。我将给出一个GNU工具链的建议

    但是。。。假设D编译器像其他编译器一样生成对象文件。。。为什么不做以下事情(这是我在C中开发业余操作系统时做的,当时我有时间做这些事情):

    • 为内核生成ELF二进制文件。。。为此,请按正常方式构建所有对象文件。在链接步骤中,将链接器脚本馈送到
      ld
      ,该脚本将定义诸如开始地址、二进制文件的节顺序(文本、数据、rodata等)之类的内容
    • 用GRUB启动它(相当容易做到…你需要在二进制文件的开头放一些神奇的字。你可以用.asm文件中的
      db
      dw
      类型语句来实现这一点,前提是相应的obj最终链接到内核的开头。签出)
    这样,您可以专注于比破解PE头或编写引导加载程序更有趣的事情

    当然。。。这听起来完全可能是代码本身有问题,而不是链接的方式。在可以让您逐步完成程序集输出的内容中运行它可能会提供一些信息。x86 PC emulator
    qemu
    具有一些调试选项,这些选项将输出程序集并将状态注册到日志中。我曾经用过它。

    一年后。。。 解决了!:D
    (>)>(^'.^)(v'.'v)+1表示良好的响应;谢谢你花时间写这篇文章!然而,这个解决方案并不特别有效,因为它的本质:(1)我正是为了学习而避免GRUB(我想从头开始使用我自己的引导加载程序),和(2)我正试图避免ELF二进制文件,因为我特别尝试使用
    D
    ,而这不会编译成ELF格式(无论如何通常都不会)。不过,建议我跨过这一步是一个有趣的想法——我从未想过要这么做。如果有效的话,我会把这个标记为答案;非常感谢。DMD for Linux生成ELF文件,没有任何异常。GDC编译并在Windows上运行。是的,但它只是D1,我需要D2。@bbqchickenrobot:我不久前发布了它。。。见附件。