如何在16位單片機(jī)上移植linux
一直以來(lái),linux被認(rèn)為是個(gè)32位的“現(xiàn)代化”操作系統(tǒng),一般也沒(méi)有人在8位、16位單片機(jī)上面去移植linux。但是,從原理上來(lái)講,從任意位數(shù)的單片機(jī),都是可以運(yùn)行l(wèi)inux的——本質(zhì)上就是個(gè)操作系統(tǒng)么,既然ucos可以,為什么linux不行?
于是,我的畢業(yè)設(shè)計(jì)打算做這個(gè)選題。當(dāng)然,雖然從原理上來(lái)講是可行的,但是在實(shí)際中遇到了一個(gè)非常大的困難,那就是底層的代碼量改動(dòng)非常大。并且linux體系中涉及到很多32位的東西,比如MMU。
后來(lái)就萌發(fā)了另外一個(gè)思路:作為uclinux而言,本身是為了不支持MMU的單片機(jī)而設(shè)計(jì)的,可以考慮移植uclinux到16位單片機(jī)上面。同時(shí),linux的早期版本,對(duì)ram和flash的要求都比較小,因此考慮移植早期版本的uclinux。
二、新的思路及其價(jià)值
但是今天又在google上面搜索,突然見到了如下的文章:
http://dmitry.co/index.php?p=./04.Thoughts/07.%20Linux%20on%208bit
這篇文章是用8位單片機(jī)來(lái)啟動(dòng)ubuntu,并且發(fā)表時(shí)間也比較新(代碼最后修改是在3.22號(hào),最近的網(wǎng)站更新是在4.3號(hào))。其參考價(jià)值在于,作者并沒(méi)有采用傳統(tǒng)的“移植”的方法,來(lái)將linux的內(nèi)核直接搬到8位的單片機(jī)上面,而是通過(guò)加入了一個(gè)中間層的方法——首先,作者在8位單片機(jī)上面實(shí)現(xiàn)了一個(gè)ARM模擬器,模擬出來(lái)一個(gè)ARM環(huán)境;其次,將linux內(nèi)核在模擬的ARM環(huán)境中進(jìn)行了運(yùn)行。其巧妙之處在于,避開了復(fù)雜的移植過(guò)程(以及16位和32位的兼容性問(wèn)題),將工作主要集中在如何在8位單片機(jī)上模擬32位的單片機(jī)(并且模擬了諸如MMU、DMA等系統(tǒng)模塊,以及UART等外設(shè))。那么這樣的工作還有另外一個(gè)重要的價(jià)值:在要求不高的情況下,我們可以采用更廉價(jià)、更低端的單片機(jī)(16位單片機(jī)、廉價(jià)的32位單片機(jī))來(lái)模擬高端的單片機(jī)(ARM9系列等等)。
三、新思路的具體實(shí)現(xiàn)方案
實(shí)際上從原理上來(lái)講,這種思路的實(shí)現(xiàn)也很簡(jiǎn)單。不考慮外設(shè)(當(dāng)然部分外設(shè)也可以模擬,比如模擬IIC,模擬SPI)的情況下,實(shí)際上單片機(jī)內(nèi)部就是①指令集②寄存器。
首先來(lái)說(shuō)寄存器。實(shí)際上32位的單片機(jī),其寄存器都是32位的。同時(shí),每個(gè)單片機(jī)的核心寄存器就那么幾個(gè)(比如8086,就是AX BX CX DX,還有DS SS SP等等)。既然是寄存器,那么對(duì)于8位單片機(jī)來(lái)說(shuō),32位的寄存器不就是4個(gè)寄存器連接起來(lái)么?不就相當(dāng)于一個(gè)結(jié)構(gòu)體(或者是數(shù)組)么?因此,我們的模擬器可以考慮用一系列的結(jié)構(gòu)體來(lái)模擬32位單片機(jī)的內(nèi)部寄存器。
再來(lái)說(shuō)指令集。不同單片機(jī)之間的指令集是不同的,這個(gè)道理顯而易見(同時(shí),這個(gè)也是阻礙linux或者其他操作系統(tǒng)移植的最大的因素,因?yàn)橐浦瞝inux的話最難的部分就在于底層匯編的編寫)。但是,匯編語(yǔ)言的本質(zhì)是什么?實(shí)際上就是機(jī)器語(yǔ)言的一種表現(xiàn)形式。那么機(jī)器語(yǔ)言是什么?不就是0和1么。話又說(shuō)回來(lái),所有的C語(yǔ)言的程序,最終都需要轉(zhuǎn)化成機(jī)器語(yǔ)言才能夠執(zhí)行——也就是說(shuō),C語(yǔ)言和機(jī)器語(yǔ)言是對(duì)應(yīng)的。那么,如果我手頭有一個(gè)ARM編譯出來(lái)的程序,那么肯定全部是機(jī)器語(yǔ)言,由0和1組成。如果我知道ARM系列每個(gè)機(jī)器語(yǔ)言的含義,并且對(duì)這個(gè)編譯出來(lái)的程序進(jìn)行解碼,那么就能得到對(duì)應(yīng)的每一句的匯編語(yǔ)言(這也就是所謂的反編譯)。那么,如果我們?cè)?位單片機(jī)的程序中,首先讀出ARM編譯出來(lái)的程序中每一句機(jī)器指令,然后加以解析,并且將這個(gè)機(jī)器指令對(duì)應(yīng)的操作進(jìn)行實(shí)現(xiàn)——那么我們不就通過(guò)程序,來(lái)完成了ARM單片機(jī)中CPU的功能么?那么,這樣我們實(shí)際上就通過(guò)8位單片機(jī)上面的程序,完成了32位命令的解析,也就完成了一個(gè)ARM模擬器的工作的大部分。
當(dāng)然,除了上述兩項(xiàng),還有就是linux運(yùn)行畢竟還是需要一定量的RAM和外設(shè),因此我們還要再加入一些外部RAM和FLASH,這些方案沒(méi)有什么難度,就只是工作量的問(wèn)題啦。
四、一點(diǎn)展望
剛才那篇文檔的作者,已經(jīng)實(shí)現(xiàn)了ARMv5TE指令集的模擬,也就是ARM9單片機(jī)的內(nèi)核,但是他是啟動(dòng)的ubuntu系統(tǒng),比較復(fù)雜,而且內(nèi)核啟動(dòng)也比較麻煩(模塊較多)。事實(shí)上,我們完全可以通過(guò)這樣一個(gè)系統(tǒng)來(lái)啟動(dòng)我們嵌入式的內(nèi)核,大小在幾M級(jí)別而已,如果精簡(jiǎn)一下的話,啟動(dòng)會(huì)更迅速,也會(huì)更具有實(shí)用價(jià)值。
評(píng)論