为什么要在M1芯片上折腾ucore?
M1芯片是2020年之后推出的全新适配于Macbook的Arm64芯片。因为底层的指令集与x86_64不同,因而面临着很多兼容性的问题。截止开始写博文的时候,M1芯片曾经经验了靠近2年的磨合期,日趋完善。
ucore是清华大学为计算机专业本科生提供的微型操作系统内核,代码是基于x86架构编写的。麻雀虽小五脏俱全,笼罩了内核的次要机制。通过改写ucore,堪称学习操作系统原理的不二法门。
之所以要在M1芯片上进行ucore的开发,调试,次要因为Macbook因为其良好的工作体验曾经成为很多程序员离不开的工作机器,而M1芯片目前并不反对虚拟机产品运行x86零碎(当然qemu目前曾经反对,但基于软件实现,效率非常低)。因而如果想用M1来开发调试ucore,肯定会波及到穿插编译的问题。
因而作者花了一下午的工夫,终于搞定了在基于M1芯片的Macbook上进行ucore的编译,运行和调试。写下这篇文章分享给大家我的计划。
筹备相干工具
qemu
qemu是十分成熟的虚拟化解决方案,通过软件的形式逐条将指标文件的二进制指令翻译成指标架构反对的二进制指令,尽管效率不高,然而使用方便,对M1芯片反对非常欠缺,足够用来调试ucore了。
# 装置homebrew/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"# 装置qemubrew install qemu
穿插编译工具gcc
穿插编译意味着咱们在某一架构上编译另一架构的指标文件(能够使lib,也能够是可执行文件)。因为最终编译的指令集不同,尽管能够依据高级语言和汇编语言编译相应的指标文件,然而并不能在开发者应用的架构上运行指标文件。
在编译ucore中,咱们所在的架构师Arm64架构,指标架构是i386架构。按理来说应该用i386架构下的gcc进行编译,然而M1芯片曾经不反对32位的编译器,所以只能装置能够将源码编译为x86_64指令的编译工具(x86_64兼容i386)。
在MacOS中能够应用homebrew装置x86_64-elf-gcc进行编译brew install x86_64-elf-gcc
。
调试工具
和gcc一样,也要装置x86_64的调试程序x86_64-elf-gdb,同样也是应用homebrew。我不是没有试过原装的lldb,然而在连贯qemu的时候会呈现error: failed to get reply to handshake packet
的报错。如果有趣味的同学能够钻研一下,我就不搞了。
编译
筹备好所有的工具,就能够开始编译ucore了,进入labcodes/lab1目录下。
首先须要批改Makefile文件,尽管HOSTCFLAGS中设置了-g的标记,然而同样也指定了代码优化等级为-O2,集体认为改为-O0比拟适合。
执行上面的指令make GCCPREFIX=x86_64-elf-
,次要是指定穿插编译工具。因为代码比较简单,很快就能够编译胜利,也不会有什么坑。
运行和调试
切换到labcodes/lab1,在bin目录下,会呈现4个文件,其中kernel中蕴含了可执行文件的符号表,用来调试用的。而.img文件是零碎镜像。
因为ucore是一个基于i386编写的内核,因而必须要用qemu-system-i386能力正确运行。
qemu-system-i386 -S -s -hda bin/ucore.img -monitor stdio
因为-S -s
的标记,零碎并没有启动,须要用gdb来启动零碎。依照上面的流程逐个执行,就能够看到零碎停留在断点memset处,执行continue,操作系统将会启动,并在qemu窗口一直打印100 ticks
。
$ x86_64-elf-gdbGNU gdb (GDB) 12.1(gdb) file bin/kernel Reading symbols from bin/kernel...(gdb) target remote :1234Remote debugging using :12340x0000fff0 in ?? ()(gdb) b memsetBreakpoint 1 at 0x1032c2: file libs/string.c, line 271.(gdb) cContinuing.Breakpoint 1, memset (s=0x10fa16, c=0 '\000', n=4850) at libs/string.c:271271 memset(void *s, char c, size_t n) {(gdb) cContinuing.
总结
本文介绍了如何应用穿插编译的形式在应用M1芯片的Macbook上进行ucore的编译,运行和调试。过程中须要踩几个穿插编译和跨平台调试的坑。借助qemu虚拟化,在Arm64芯片上运行x86_64架构的零碎内核。