OS开发爱好者福利:树莓派上编译C语言,顺便掌握一波硬件知识

近日,有人在GitHub上开源了一个关于树莓派的教程。不同于以往的树莓派开发,这篇教程的核心内容是讨论如何在树莓派上进行裸机编程。

教程地址:

在树莓派3上进行裸机编程

该系列教程面向那些想要编译自己的树莓派裸机应用程序的人,具体目标受众是那些对树莓派硬件不熟悉,但在业余时间又爱好OS的开发人员。在这篇教程里,作者给出了一些示例来完成基本的操作,比如:将代码写入串行控制台、从串行控制台中读取按键、设置屏幕分辨率并绘制到线性帧缓冲区。此外,作者还展示了如何获取硬件的序列号、硬件支持的随机数,以及如何从启动分区读取文件。

需要注意的是:这篇教程没有涉及编写OS。诸如内存管理、虚拟文件系统、实现多任务处理之类的主题也不会介绍。该教程将重点介绍与硬件的接口,而不是关于OS的理论。此外,该教程假设你具有一定的GNU/Linux知识,对编译程序、创建磁盘和文件系统镜像有一定的了解。

对于为何选择树莓派3,作者给出了解释:首先,它既便宜又容易买到。第二,它是64位的,拥有非常大的地址空间。第三,它只使用MMIO,这使得编程更容易。

该教程使用C语言进行开发,因为C语言能够直接对硬件进行开发。

预备知识

在开始前,你将需要在FAT文件系统上使用交叉编译器(有关详细信息,请参见00_crosscompiler目录)和带有固件文件的MicroSD卡。

每个目录都有一个以及。确保Makefile符号链接根据你自己选择的交叉编译器指向版本。

作者给出的建议是买一个MicroSD卡USB适配器(许多制造商都会提供这种适配器的SD卡),这样就可以像USB一样将该卡连接到任何台式计算机上,而不需要特殊的读卡器接口(尽管现在很多笔记本电脑都有这种接口)。如果你不喜欢dd命令,你也可以选择USBImager,这是一个简单的GUI应用程序,具有可移植的可执行文件,可用于Windows、MacOSX和Linux操作系统。

Micro-SD卡USB适配器。

在带有LBAFAT32(类型0x0C)分区的SD卡上创建MBR分区方案,并对其格式化,然后将、以及复制到其中。或者,你可以下载一个raspbian镜像,dd命令烧写到SD卡,mount挂载并删除不必要的.img文件。不管你喜欢哪种方法,重点是你将使用这些教程创建,而且必须复制到SD卡的根目录中,后者不应该存在其他.img文件。

建议使用USB串行调试电缆。把它连接到GPIO引脚14/15,然后在电脑上按如下方式运行minicom:

USB串行调试电缆

仿真

不幸的是,官方的qemu二进制文件还不支持树莓派3。但作者已经实现了,并将很快发布(更新:在中提供)()。在此之前,你必须从最新的源代码编译qemu。编译后,可进行如下操作:

或者:

-Mraspi3:让qemu仿真树莓派3硬件。

-:告知要使用的内核文件名。

-drivefile=$(yourimagefile),if=sd,format=raw:在第二种情况下,该参数为SD卡镜像,它也可以是标准的rasbian镜像。

-serialstdio

-serialnull-serialstdio:将模拟的UART0重定向到运行qemu的终端的标准输入/输出,以便显示发送到串行线路的所有内容,并且vm会接收终端中键入的每个键。该操作仅适用于教程05及更高版本,因为默认情况下不会重定向UART1。为此,必须添加一些类似于-chardevsocket,host=localhost,port=1111,id=aux-serialchardev:aux的参数,或者简单地使用两个-serial参数。

硬件资源

下面简单介绍一下所需硬件资源,BCM2837SoC芯片。包括:

VideoCoreGPU;

ARM-Cortex-A53CPU(ARMv8);

MMIO映射外部设备。

有趣的是,CPU不是主板上的主处理器。当它通电后,第一个GPU运行。当初始化完成时,通过执行,它将加载并执行。这不是一个ARM可执行文件,而是专门为GPU编译的。比较有意思的是,寻找不同的ARM可执行文件,都以kernel开头,以.img结尾。由于要在AArch64模式下对CPU进行编程,因此只需要,这也是最后一个要查找的。加载后,GPU触发ARM处理器上的复位线,开始在地址0x80000(或更准确地说是0)处执行代码。

RAM(1GRaspberryPi3)在CPU和GPU之间共享,这意味着一个可以读取另一个写入内存的内容。为了避免混淆,需要定义好mailbox接口。CPU将消息写入mailbox,并通知GPU读取它。GPU(知道消息完全在内存中)解释它,并将响应消息放在同一个地址。CPU必须循环访问内存以知道GPU何时完成,然后它才能读取响应。

相似的,所有外部设备都在内存中与CPU通信。每个设备都有从0x3F000000开始的专用内存地址,但是它不在真实的RAM中(称为内存映射IO)。现在没有用于外围设备的mailbox,而是每个设备都有其自己的协议。这些设备的共同点是:必须以32位为单位在4个字节对齐的地址(所谓的字)上读取和写入其内存,并且每个设备都有控制/状态和数据字(datawords)。不幸的是,Broadcom(SoC芯片的制造商)在记录产品方面很差。现在所拥有的最好的是BCM2835文档,这个文档就足够了。

CPU中还有一个内存管理单元,允许创建虚拟地址空间。这可以通过特定的CPU寄存器进行编程,并且在将这些MMIO地址映射到虚拟地址空间时必须小心。

一些更有趣的MMIO地址是:

更多信息,请参见:

发布于 2025-01-21
97
目录

    推荐阅读