Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在mac上编写自定义内核?_C_Macos_Assembly_Kernel_Nasm - Fatal编程技术网

如何在mac上编写自定义内核?

如何在mac上编写自定义内核?,c,macos,assembly,kernel,nasm,C,Macos,Assembly,Kernel,Nasm,我一直在遵循这个方法来制作我自己的内核,我让它工作起来了。但是,后来我查阅了互联网上的许多指南,在NASM中创建引导扇区,从编译的C对象加载main函数。我尝试过编译和链接各种GCC安装: x86_64-pc-linux- arm-uclinux-elf- arm-agb-elf- arm-elf- arm-apple-darwin10- powerpc-apple-darwin10- i686-apple-darwin10- i586-pc-linux- i386-elf- 当我把它们放在软

我一直在遵循这个方法来制作我自己的内核,我让它工作起来了。但是,后来我查阅了互联网上的许多指南,在
NASM
中创建引导扇区,从编译的
C
对象加载
main
函数。我尝试过编译和链接各种GCC安装:

x86_64-pc-linux-
arm-uclinux-elf-
arm-agb-elf-
arm-elf-
arm-apple-darwin10-
powerpc-apple-darwin10-
i686-apple-darwin10-
i586-pc-linux-
i386-elf-
当我把它们放在软盘上时,它们都失败了,就像我用
MikeOS
bootstrap做的一样。我尝试过各种教程,比如一个,我也尝试过,但在Mac上编译时都不起作用,但在实际的Linux机器上我还没有厌倦。但我想知道如何在程序集调用
C
函数时获得引导,并将它们组合到一个工作内核文件中,然后将加载到软盘文件中,然后加载到ISO上,就像
MikeOS
教程中那样。或者我应该制作
kernel.bin
并用
syslinux
加载它吗?有谁能告诉我如何在Mac开发环境中实现这一切?我通过macports和自制软件收费,这很有帮助。有人这样做吗

编辑 到目前为止,我的工作还很忙


我只想知道如何从
C
跳转到
extern
函数并将其链接。

这有一些问题。首先,您提到的所有编译器都输出32位或64位代码。这很好,但当启动扇区启动时,它将以16位实模式运行。如果希望能够运行32位或64位代码,则需要首先切换到适当的模式(32位保护模式用于32位,长模式用于64位)

然后,一旦你切换到合适的模式,你甚至没有那么多的空间来编写代码:引导扇区是512字节;为可引导签名保留了两个字节,您需要一些字节用于切换到适当模式的代码。如果您希望能够使用该磁盘上的分区或FAT文件系统,请删除更多可用字节。除了最琐碎的程序外,您根本没有足够的空间容纳所有程序

那么,真正的操作系统是如何处理这个问题的呢?真正的操作系统倾向于使用引导扇区从磁盘加载更大的引导加载程序。然后,较大的引导加载程序可以加载实际的内核并切换到适当的模式(尽管这可能是加载的内核的责任-这取决于)

编写一个引导加载程序可能需要大量的工作,因此与其自己运行,您可能希望使用GRUB并使您的内核符合多重引导标准。GRUB是一个引导加载程序,它能够从磁盘(可能是ELF格式)加载内核,并以32位保护模式跳转到入口点。有帮助,对吗

这并不能让您从学习汇编中解脱出来,但是:内核的入口点必须是汇编。通常,它所做的只是建立一个小堆栈,并将适当的寄存器传递给具有正确调用约定的C函数

你可能认为你可以复制它而不是自己写,你是对的,但它并没有就此结束。您还需要组装(至少):

  • 正在加载新的全局描述符表
  • 处理中断
  • 使用非内存映射的I/O端口
…等等,更不用说如果你必须调试,你可能没有一个好的调试器;相反,您必须查看分解、寄存器值和内存转储。即使您的代码是从C编译的,您也必须知道底层程序集的功能,否则您将无法调试它


总之,您的主要问题是不了解汇编。如前所述,汇编对于操作系统开发至关重要。一旦您完全了解程序集,就可以开始编写操作系统。

引导扇区开始以16位实模式执行。您尝试编译为32位代码的所有C编译器。如果您想运行这些编译器的代码输出,您的引导扇区首先必须转换到32位保护模式。一旦这样做了,您只有510个字节,减去切换到保护模式所需的字节数。你可能会想写更多的代码,而不是在这个空间里。是的,非常正确,如果我把32位放在第开始,而不是16位,那么NASM将输出32位代码,CPU将解释为16位代码,这绝对不是你想要的。明白,所以操作系统使用了引导从16位到32位或64位的空间,我不想要16位操作系统,所以我需要让引导传递到32位代码?而不是直接的外部调用?即使在使用了C内核之后,也需要处理汇编。例如,您需要程序集来加载全局描述符表。您需要编写程序集来处理中断。你需要组装很多东西,没有组装就勉强度日根本不是个好主意。