当前位置: 首页 > 科技观察

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

时间:2023-03-15 00:50:47 科技观察

OS开发爱好者福利:在树莓派上编译C语言,顺便掌握一波硬件知识,显示器,键鼠等设备。它还可以处理文本、电子表格、媒体甚至游戏。那么这台神奇的小电脑是如何用来编程的呢?下面介绍一个使用树莓派进行裸机编程的教程,顺便学习一下接口、硬件等知识。最近有人在GitHub上开源了一个关于树莓派的教程。不同于以往的树莓派开发,本教程的核心内容是讨论如何在树莓派上进行裸机编程。教程地址:https://github.com/bztsrc/raspi3-tutorialRaspberryPi3裸机编程本系列教程针对那些想编写自己的RaspberryPi裸机应用程序的人。不熟悉RaspberryPi硬件但在业余时间喜欢OS的开发人员。在本教程中,作者给出了一些示例来完成基本操作,例如:将代码写入串口控制台、从串口控制台读取击键、设置屏幕分辨率和绘制到线性帧缓冲区。此外,作者还展示了如何获取硬件的序列号、硬件支持的随机数,以及如何从引导分区读取文件。注意:本教程不包括编写操作系统。内存管理、虚拟文件系统和实现多任务处理等主题也不包括在内。本教程将重点介绍与硬件的接口,而不是有关操作系统的理论。此外,本教程假定您具有一些GNU/Linux知识、一些编译程序以及创建磁盘和文件系统映像的知识。笔者对于选择树莓派3的原因给出了解释:第一,便宜好买。其次,它是64位的,地址空间非常大。第三,它只使用MMIO,这使得编程更容易。本教程使用C语言进行开发,因为C语言可以直接对硬件进行开发。在开始之前,您需要一个FAT文件系统上的交叉编译器(有关详细信息,请参阅00_crosscompiler目录)和一个带有固件文件的MicroSD卡。每个目录都有一个Makefile.gcc和一个Makefile.clang。确保Makefile符号链接指向根据您自己选择的交叉编译器的版本。笔者的建议是买一个MicroSD卡USB转接头(很多厂商都会提供SD卡带这个转接头),这样卡就可以像USB一样连接到任何台式电脑上,而不需要专门的读卡器接口(虽然现在很多笔记本电脑都有这个)。如果您不喜欢dd命令,您也可以选择USBImager,这是一个简单的GUI应用程序,具有适用于Windows、MacOSX和Linux操作系统的可移植可执行文件。微型SD卡USB适配器。在LBAFAT32(type0x0C)分区的SD卡上创建并格式化MBR分区方案,将bootcode.bin、start.elf和fixup.dat复制到其中。或者,您可以下载一个raspbian映像,dd以闪存到SD卡,mount以删除不需要的.img文件。无论您喜欢哪种方法,关键是您将使用这些教程创建kernel8.img,并且必须将其复制到SD卡的根目录,该目录不应存在其他.img文件。建议使用USB串行调试电缆。将它连接到GPIO引脚14/15,然后在您的计算机上运行minicom,如下所示:USBSerialDebugCableEmulation不幸的是,官方qemu二进制文件尚不支持RaspberryPi3。不过作者已经实现了,很快就会发布(更新:qemu2.12可用)(https://wiki.qemu.org/ChangeLog/2.12#ARM)。在此之前,您必须从最新的源代码编译qemu。编译后,您可以执行以下操作:或:-Mraspi3:让qemu模拟RaspberryPi3硬件。-kernelkernel8.img:告知要使用的内核文件名。-drivefile=$(yourimagefile),if=sd,format=raw:第二种情况,这个参数是SD卡镜像,也可以是标准的rasbian镜像。-serialstdio-serialnull-serialstdio:将模拟的UART0重定向到运行qemu的终端的标准输入,以便显示发送到串行线路的所有内容,并且vm接收终端中键入的每个键。这仅适用于Tutorial05及更高版本,因为默认情况下UART1不重定向。为此,必须添加一些参数,如-chardevsocket,host=localhost,port=1111,id=aux-serialchardev:aux或简单地使用两个-serial参数。硬件资源下面简单介绍一下所需的硬件资源,BCM2837SoC芯片。包括:VideoCoreGPU;ARM-Cortex-A53CPU(ARMv8);MMIO映射外设。有趣的是,CPU并不是主板上的主处理器。当它上电时,第一个GPU运行。当初始化完成后,通过执行bootcode.bin,会加载并执行start.elf。这不是ARM可执行文件,而是专门为GPU编译的。更有趣的是,start.elf寻找不同的ARM可执行文件,所有这些文件都以kernel开头,以.img结尾。由于CPU正在以AArch64模式编程,因此只需要kernel8.img,这是最后一个要查找的。加载后,GPU触发ARM处理器上的复位线并开始执行地址0x80000(或更准确地说是0)处的代码。RAM(1GRaspberryPi3)在CPU和GPU之间共享,这意味着一个可以读取另一个写入内存的内容。为了避免混淆,需要定义邮箱接口。CPU将消息写入邮箱,通知GPU读取。GPU(知道消息完全在内存中)对其进行解释并将响应消息放在同一地址。CPU必须循环遍历内存才能知道GPU何时完成,然后才能读取响应。同样,所有外设都在内存中与CPU通信。每个设备都有一个从0x3F000000开始的专用内存地址,但它不在真正的RAM中(称为内存映射IO)。现在没有外围设备的邮箱,而是每个设备都有自己的协议。这些设备的共同点是它们的内存必须以4字节对齐的地址(所谓的字)以32位为单位进行读写,并且每个设备都有控制/状态字和数据字(datawords)。不幸的是,Broadcom(SoC芯片的制造商)在记录他们的产品方面非常糟糕。您现在拥有的最好的是BCM2835文档,应该足够了。CPU中还有一个内存管理单元,允许创建虚拟地址空间。这可以通过特定的CPU寄存器进行编程,并且在将这些MMIO地址映射到虚拟地址空间时必须小心。一些更有趣的MMIO地址是:https://github.com/raspberrypi了解更多信息