无操作系统执行

9
如何将一个C程序编译成有效的ELF格式(或RAW格式),以便可以直接从RAM中执行,而无需任何操作系统(OS)?假设存在一个引导程序(bootloader),它能够将代码加载到RAM中的任何位置,并在该地址处开始执行。确切地说,需要哪些编译器(GCC)标志?是否需要映射文件?
欢迎提供一个helloworld应用程序示例:)
详细说明一下我的观点,让main()方法成为一个空的无限循环,以确保不使用任何OS特定或标准库调用。期望的输出是“hang”。使用通常的GCC选项,引导程序肯定无法加载可执行文件,告诉它这是无效的ELF格式。然而,通过向链接器传递-dN选项,将使其成为有效的ELF。还需要更多的编译器/链接器选项才能使其“hang”而不会崩溃!到底是哪些编译器选项呢?
file.c:
int main()
{
    while(1);
}

编译
使用gcc命令对file.c进行编译:gcc -c -nostdinc -fno-builtin file.c
使用ld命令将file.o链接为可执行文件:ld -dN -nostdlib file.o

引导加载器将a.out文件加载到RAM中并执行。

4个回答

6
首先,在引导加载程序完成其工作后,你能做的事情是有限的。这些限制是由以下原因造成的:(假设您的引导加载程序(例如:grub)将您带入了32位保护模式) 1. 没有启用分页。 您需要启用它。 2. 在此期间,您无法与设备交互,因为您必须为IRQ设置处理程序。
这是一个我用来学习裸机编程艺术的经典链接(http://geezer.osdevbrasil.net/osd/index.htm)。该页面上还有一个下载链接 (http://geezer.osdevbrasil.net/osd/code/osd.tgz)。tar文件中包含了不断增加复杂程度的演示内核。另外,您可以查看makefile(linux.mak)并获取gcc所需的必要标志。
我打开了一个随意的makefile,发现使用了以下标志: gcc : -nostdinc -fno-builtin ld: -nostdlib (因为进行了显式调用,所以ld也需要一个标志).
该标志的作用是告诉gcc不要与标准库进行链接。

谢谢...这些链接非常有用 :) - AIB

2

1

0

你是否意识到,如果你不加载操作系统,你必须编写设备驱动程序才能与任何设备配合使用。这意味着如果没有为特定的视频卡编写驱动程序,就不能将内容写入屏幕,没有为特定的硬盘控制器卡编写驱动程序,就不能从磁盘读取内容,也不能访问键盘等。

你可以考虑一下叫做显示器模式的东西。基本思路是操作系统运行,加载应用程序所需的一切,加载您的应用程序,然后您无法切换到其他应用程序。


不必编写设备驱动程序,您可以保持实模式并使用BIOS中断来访问所有这些内容。否则,视频(VESA),键盘(PS / 2仿真)等都是相当标准化的。 - Andy
首先,我试图创建一个系统挂起(请参见问题中的代码)。要产生挂起,您不需要任何驱动程序(除了可能是内存驱动程序,我认为引导加载程序将提供)。但是我遇到了崩溃。一旦我完成这个,我就可以获得驱动程序代码并进一步探索... - AIB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接