樹莓派4裸機(jī)基礎(chǔ)教程:芯片啟動(dòng)到代碼執(zhí)行
掃描二維碼
隨時(shí)隨地手機(jī)看文章
樹莓派4裸機(jī)基礎(chǔ)教程:芯片啟動(dòng)到代碼執(zhí)行
-
1.說明
-
2.樹莓派的sd卡
-
3.config.txt的配置信息
-
4.小結(jié)
1.說明
在做嵌入式開發(fā)的時(shí)候,每個(gè)芯片都有自己的啟動(dòng)方式。在做底層優(yōu)化的時(shí)候,往往也需要關(guān)注芯片的啟動(dòng)方式,涉及到啟動(dòng)時(shí)間,啟動(dòng)的穩(wěn)定性問題。所以關(guān)注芯片的啟動(dòng)方式非常的重要。在使用電腦的時(shí)候,電腦上電后首先會(huì)執(zhí)行BIOS,這個(gè)是廠家固化到ROM里面的代碼,一般從電腦生產(chǎn)出來到電腦的壽命結(jié)束,其中的內(nèi)容都是不會(huì)變的。而系統(tǒng)卻可以經(jīng)常更換,我們可以裝Linux系統(tǒng),也可以裝windows系統(tǒng)。這個(gè)就是電腦的啟動(dòng)過程。
類比芯片的啟動(dòng)過程,大多數(shù)也是如此,比如我們一般描述嵌入式Linux在某些芯片的上的啟動(dòng)流程,首先芯片上電后會(huì)執(zhí)行芯片內(nèi)部rom的一段固化代碼,這段代碼會(huì)根據(jù)撥碼開關(guān)選擇從不同的存儲(chǔ)介質(zhì)中去讀取一小段可以執(zhí)行的代碼放到sram中執(zhí)行。這些存儲(chǔ)介質(zhì)可以是SPI Flash,可以是nand或者nor flash,或者sd卡等等。由于芯片的sram不可能做到非常大,所以第一階段的代碼往往會(huì)有限制,比如只允許使用4K內(nèi)存等等。這段小的代碼負(fù)責(zé)初始化sdram,然后跳轉(zhuǎn)到sdram中去執(zhí)行代碼。由于sdram的成本比sram小許多,所以sdram往往非常的大,接著就是執(zhí)行正常的程序了。
這些啟動(dòng)方式的選擇,都是芯片設(shè)計(jì)者需要考慮的問題,一方面是成本另一方面是啟動(dòng)的效率問題。在使用芯片的時(shí)候,具體看設(shè)計(jì)者的思路即可。下面來分析一下樹莓派4芯片的啟動(dòng)過程。
2.樹莓派的sd卡
一般我們使用開發(fā)板的時(shí)候,很少會(huì)見到需要插上sd卡才能啟動(dòng)的,唯有樹莓派有這個(gè)特殊的操作。那么樹莓派的sd卡里面的文件究竟有什么作用呢?
樹莓派在設(shè)計(jì)的時(shí)候,為了節(jié)省成本,沒有使用掉電非易失性存儲(chǔ)介質(zhì),也就在板子上不能找到相關(guān)的flash。這樣芯片啟動(dòng)的程序只能放在sd卡里面了。本來U盤啟動(dòng)也是一種方式,但是樹莓派4代之前的設(shè)計(jì)并不是很好,導(dǎo)致這種啟動(dòng)方式不可以使用。樹莓派4也有一些嘗試,但是目前樹莓派4最主流的方式還是使用SD卡啟動(dòng)。
Raspberry Pi 4具有一個(gè)SPI連接的EEPROM(4MBits / 512KB)。其中包含用于啟動(dòng)系統(tǒng)的代碼,并替換了先前在SD卡的啟動(dòng)分區(qū)中找到的bootcode.bin。請(qǐng)注意,如果Pi 4的SD卡的啟動(dòng)分區(qū)中存在bootcode.bin,則將其忽略。也就是說在樹莓派4的啟動(dòng)方式上,更加的靈活,甚至可以直接去掉SD卡,從網(wǎng)絡(luò)方式啟動(dòng)應(yīng)用程序。具體可以看之前的文章
下面來分析一下從sd卡啟動(dòng)系統(tǒng)需要的必要的文件內(nèi)容。在裸機(jī)實(shí)驗(yàn)中,一般只需要如下的文件就可以啟動(dòng)了。
啟動(dòng)過程可以描述如下:
首先芯片上電后執(zhí)行first-stage bootloader,這是芯片固化在內(nèi)部的代碼,這個(gè)代碼的功能是加載sd卡中的bootcode.bin文件。在樹莓派4之前的版本都是需要這個(gè)文件的,但是在樹莓派4上,由于有了SPI的EEPROM,所以SD卡中可以不用存在這個(gè)文件。并且啟動(dòng)了GPU。然后將bootcode.bin讀取到了128K大小的二級(jí)緩存(L2 Cache)中。此時(shí)開始執(zhí)行bootcode.bin代碼。該功能用于初始化ram,并且把start4.elf加載到內(nèi)存中,并且去讀取config.txt中的配置信息,設(shè)置這些配置信息。上述已經(jīng)描述了這幾個(gè)文件的作用,但是經(jīng)過實(shí)際測(cè)試發(fā)現(xiàn),這個(gè)設(shè)備樹文件bcm2711-rpi-4-b.dtb文件也是需要的,如果不存在也會(huì)影響串口的輸出,也就是只會(huì)有亂碼輸出。所以推測(cè)start4.elf文件也會(huì)去讀取設(shè)備樹文件,然后設(shè)置一些基本的參數(shù)。畢竟這個(gè)文件的大小也可以說明其功能的豐富。
3.config.txt的配置信息
前面說到,start4.elf會(huì)讀取config.txt中的配置信息,然后去設(shè)置相關(guān)的配置。先看看最簡(jiǎn)單的裸機(jī)代碼啟動(dòng)里設(shè)置了哪些配置:
enable_uart=1 arm_64bit=0 core_freq=250 kernel=kernel7.img kernel_address=0x8000
首先enable_uart=1表示使用的是miniUART,樹莓派4中,UART控制器有兩種,PL011或者mini UART。
Name | Type |
---|---|
UART0 | PL011 |
UART1 | mini UART |
UART2 | PL011 |
UART3 | PL011 |
UART4 | PL011 |
UART5 | PL011 |
這里設(shè)置使能UART1作為輸出信息,接著需要設(shè)置arm的頻率core_freq=250。因?yàn)榇诳刂破魇切枰l率進(jìn)行使能的。
arm_64bit=0告訴arm要啟動(dòng)的程序是32位的,由于樹莓派4上的芯片是cortex-a72,是aarch64架構(gòu)的,但是也支持向下兼容的32位指令。所以需要告知當(dāng)前的裸機(jī)程序是32位指令集架構(gòu)。
kernel=kernel7.img表示從start4.elf執(zhí)行的程序是哪一個(gè),另外kernel_address=0x8000表示需要執(zhí)行的內(nèi)存地址。這個(gè)地址就是裸機(jī)程序在鏈接時(shí)的入口地址。
以上的信息就是我們最小的裸機(jī)程序需要的環(huán)境配置。其他的更多的信息可以看官網(wǎng)上的描述來進(jìn)行一一的設(shè)置:
https://www.raspberrypi.org/documentation/configuration/config-txt/README.md
4.小結(jié)
本文主要描述了一個(gè)樹莓派裸機(jī)代碼之前所做的事情,這些啟動(dòng)流程是非常值得思考的,每一個(gè)步驟都有其設(shè)定的含義。剩下的config.txt文件中的配置其實(shí)還是有很多可以嘗試的,比如修改啟動(dòng)地址,或者去使能某些外設(shè)等等。由于目前研究的是最簡(jiǎn)單的裸機(jī)代碼,所以這些配置會(huì)在以后更高級(jí)的功能中慢慢說到。比如比較重要的安全可信技術(shù),也需要修改配置文件。前期理解芯片的啟動(dòng)過程有助于對(duì)后面編寫裸機(jī)代碼的分析。
- END -