How to compile a Rust kernel with an Assembly (NASM) bootloader
我有一个用NASM编写的简单的2阶段引导程序,我想使用Rust继续OS内核。
因此,我使用Cargo创建了一个每晚的Rust项目,并在src / main.rs文件中禁用了std。 现在,我尝试将Assembly文件与Cargo项目链接,但没有成功。
如何编译NASM引导加载程序并将其与Rust内核链接?
-
不要将它们链接在一起。将rust对象的链接输出到二进制文件(我不使用rust,但是您可以使用objcopy将elf可执行文件(由rust生成)转换为二进制文件。将二进制文件放在引导加载程序将要读取的磁盘上您可以使用dd进行操作。
-
似乎有一个bootimage Rust项目用于创建包含Rust ELF可执行文件的可引导磁盘映像。
-
糟糕,指向bootimage项目的链接在这里:github.com/rust-osdev/bootimage
-
据我所知,bootimage Rust项目仅用于使用现有的Bootloader编译内核。我有自己的引导加载程序,因此我不认为这是解决方案。
-
然后,您将不得不使用我在第一篇文章中建议的内容。您的项目可能正在生成ELF可执行文件。使用objcopy将ELF可执行文件转换为二进制文件。用objcopy -O binary myos.elf myos.bin进行转换,然后可以使用dd将引导程序放在第一个扇区中,然后将myos.bin(或您希望使用的任何名称)放在后面的扇区中。如果希望从引导加载程序之后立即从磁盘加载操作系统,并假设boot.bin正好是512字节,则类似。
-
如果您在那里还有另一个阶段,则也必须在其中添加它。我通常使用DD来构建磁盘映像。很容易将事物放在图像中您需要的地方。首先是将生成的rust ELF可执行文件转换为二进制形式(除非您将ELF加载程序编码为较早的阶段之一。可能您没有这样做,因此在加载时使用二进制映像更容易。
-
Rust中的技巧是确保内核的入口点位于二进制文件的开头(然后,您只需将第二级跳转到内核加载到内存中的第一个地址)即可。我不知道如何在Rust环境中执行此操作,但是通常需要创建一个链接描述文件,以将起始代码放在内核中所有其他代码和数据之前。
-
我已经找到了如何使用Rust来" bootimage"项目编译bootloader的方法,这与您所建议的类似。我查看了如何将Rust编译为ELF可执行文件,但没有找到答案。您可以编写将Rust编译为ELF可执行文件的命令吗?
-
您已经从当前项目中生成了内核可执行文件吗?
-
我创建了一个.o文件和一个普通的Linux可执行文件。我没有找到正确的标志来编译内核,因此无法启动它。
-
您可能会在OSDev.org上找到使用Rust的人,他们可能知道forum.osdev.org。或者,您可以在这里等到具有Rust经验的人在SO上看到这一点。大概在两个地方问都不会受伤。 OSDev通常是C / C ++ OS开发人员,但我也看到一些人有时也讨论Rust。您也可以在reddit.com/r/osdev上询问
几个小时后,我编译了代码。
解决方案是(如Michael Petch建议的那样),将汇编代码编译为静态.o文件,然后使用xargo和自定义目标编译rust代码。 我将Rust代码编译为静态库,而不是二进制库,因此输出是.a目标文件,而不是可执行文件。
然后,我将gcc与链接描述文件一起使用来将目标文件链接在一起,并将结果输出为ELF文件。 之后,我使用objcopy和-O binary标志将ELF文件复制到.bin文件。 最后,我使用dd创建了一个映像文件,可以从中启动。