第三十七章Linux內核移植
前兩章我們簡單了解了一下Linux內核頂層Makefile和Linux內核的啟動流程,本章我們就來學習一下如何將NXP官方提供的Linux內核移植到正點原子的I.MX6U-ALPHA開發板上。通過本章的學習,我們將掌握如何將半導體廠商提供的Linux BSP包移植到我們自己的平臺上。
37.1 創建VSCode工程
這裡我們使用NXP官方提供的Linux源碼,將其移植到正點原子I.MX6U-ALPHA開發板上。NXP官方原版Linux源碼已經放到了開發板光碟中,路徑為:1、例程源碼->4、NXP官方原版Uboot和Linux->linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。使用FileZilla將其發送到Ubuntu中並解壓,得到名為linux-imx-rel_imx_4.1.15_2.1.0_ga的目錄,為了和NXP官方的名字區分,可以使用「mv」命令對其重命名,我這裡將其重命名為「linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek」,命令如下:
mv linux-imx-rel_imx_4.1.15_2.1.0_ga linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
完成以後創建VSCode工程,步驟和Windows下一樣,重點是.vscode/settings.json這個文件。
37.2 NXP官方開發板Linux內核編譯
NXP提供的Linux源碼肯定是可以在自己的I.MX6ULL EVK開發板上運行下去的,所以我們肯定是以I.MX6ULL EVK開發板為參考,然後將Linux內核移植到I.MX6U-ALPHA開發板上的。
37.2.1修改頂層Makefile
修改頂層Makefile,直接在頂層Makefile文件裡面定義ARCH和CROSS_COMPILE這兩個的變量值為arm和arm-linux-gnueabihf-,結果如圖37.2.1所示:
圖37.2.1 修改頂層Makefile
圖37.2.1中第252和253行分別設置了ARCH和CROSS_COMPILE這兩個變量的值,這樣在編譯的時候就不用輸入很長的命令了。
37.2.2 配置並編譯Linux內核
和uboot一樣,在編譯Linux內核之前要先配置Linux內核。每個板子都有其對應的默認配置文件,這些默認配置文件保存在arch/arm/configs目錄中。imx_v7_defconfig和imx_v7_mfg_defconfig都可作為I.MX6ULL EVK開發板所使用的默認配置文件。但是這裡建議使用imx_v7_mfg_defconfig這個默認配置文件,首先此配置文件默認支持I.MX6UL這款晶片,而且重要的一點就是此文件編譯出來的zImage可以通過NXP官方提供的MfgTool工具燒寫!!imx_v7_mfg_defconfig中的「mfg」的意思就是MfgTool。
進入到Ubuntu中的Linux源碼根目錄下,執行如下命令配置Linux內核:
make clean //第一次編譯Linux內核之前先清理一下
make imx_v7_mfg_defconfig //配置Linux內核
配置完成以後如圖37.2.2.1所示:
圖37.2.2.1 配置Linux內核
配置完成以後就可以編譯了,使用如下命令編譯Linux內核:
make-j16 //編譯Linux內核
等待編譯完成,結果如圖37.2.2.2所示:
圖37.2.2.2 Linux編譯完成
Linux內核編譯完成以後會在arch/arm/boot目錄下生成zImage鏡像文件,如果使用設備樹的話還會在arch/arm/boot/dts目錄下開發板對應的.dtb(設備樹)文件,比如imx6ull-14x14-evk.dtb就是NXP官方的I.MX6ULL EVK開發板對應的設備樹文件。至此我們得到兩個文件:
①、Linux內核鏡像文件:zImage。
②、NXP官方I.MX6ULL EVK開發板對應的設備樹文件:imx6ull-14x14-evk.dtb。
37.2.3 Linux內核啟動測試
在上一小節我們已經得到了NXP官方I.MX6ULL EVK開發板對應的zImage和imx6ull-14x14-evk.dtb這兩個文件。這兩個文件能不能在正點原子的I.MX6U-ALPHA EMMC版開發板上啟動呢?測試一下不就知道了,在測試之前確保uboot中的環境變量bootargs內容如下:
console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw
將上一小節編譯出來的zImage和imx6ull-14x14-evk.dtb複製到Ubuntu中的tftp目錄下,因為我們要在uboot中使用tftp命令將其下載到開發板中,拷貝命令如下:
cp arch/arm/boot/zImage /home/zuozhongkai/linux/tftpboot/ -f
cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb /home/zuozhongkai/linux/tftpboot/ -f
拷貝完成以後就可以測試了,啟動開發板,進入uboot命令行模式,然後輸入如下命令將zImage和imx6ull-14x14-evk.dtb下載到開發板中並啟動:
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 – 83000000
結果圖37.2.3.1所示:
圖37.2.3.1 啟動Linux內核
從圖37.2.3.1可以看出,此時Linux內核已經啟動了,如果EMMC中的根文件系統存在,我們就可以進入到Linux系統裡面使用命令進行操作如圖37.2.3.2所示:
圖37.2.3.2 進入Linux根文件系統
37.2.4 根文件系統缺失錯誤
Linux內核啟動以後是需要根文件系統的,根文件系統存在哪裡是由uboot的bootargs環境變量指定,bootargs會傳遞給Linux內核作為命令行參數。比如上一小節設置root=/dev/mmcblk1p2,也就是說根文件系統存儲在/dev/mmcblk1p2中,也就是EMMC的分區2中。這是因為正點原子的EMMC版本開發板出廠的時候已經EMMC的分區2中燒寫好了根文件系統,所以設置root=/dev/mmcblk1p2。如果我們不設置根文件系統路徑,或者說根文件系統路徑設置錯誤的話會出現什麼問題?這個問題是很常見的,我們在實際的工作中開發一個產品,這個產品的第一版硬體出來以後我們是沒有對應的根文件系統可用的,必須要自己做根文件系統。在構建出對應的根文件系統之前Linux內核是沒有根文件系統可用的,此時Linux內核啟動以後會出現什麼問題呢?帶著這個問題,我們將uboot中的bootargs環境變量改為「console=ttymxc0,115200」,也就是不填寫root的內容了,命令如下:
setenv bootargs 'console=ttymxc0,115200'
修改完成以後重新從網絡啟動,啟動以後會有如圖37.2.4.1所示錯誤:
圖37.2.4.1 根文件系統缺失錯誤
在圖37.2.4.1中最後會有下面這一行:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
也就是提示內核崩潰,因為VFS(虛擬文件系統)不能掛載根文件系統,因為根文件系統目錄不存在。即使根文件系統目錄存在,如果根文件系統目錄裡面是空的依舊會提示內核崩潰。這個就是根文件系統缺失導致的內核崩潰,但是內核是啟動了的,只是根文件系統不存在而已。
37.3 在Linux中添加自己的開發板
在37.2小節中我們通過編譯NXP官方I.MX6ULL EVK開發板對應的Linux內核,發現其可以在正點原子的EMMC版本開發板啟動,所以我們就參考I.MX6ULL EVK開發板的設置,在Linux內核中添加正點原子的I.MX6U-ALPHA開發板。
37.3.1 添加開發板默認配置文件
將arch/arm/configs目錄下的imx_v7_mfg_defconfig重新複製一份,命名為imx_alientek_emmc_defconfig,命令如下:
cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig
以後imx_alientek_emmc_defconfig就是正點原子的EMMC版開發板默認配置文件了。完成以後如圖37.3.1.1所示:
圖37.3.1.1 新添加的默認配置文件
以後就可以使用如下命令來配置正點原子EMMC版開發板對應的Linux內核了:
makeimx_alientek_emmc_defconfig
37.3.2 添加開發板對應的設備樹文件
添加適合正點原子EMMC版開發板的設備樹文件,進入目錄arch/arm/boot/dts中,複製一份imx6ull-14x14-evk.dts,然後將其重命名為imx6ull-alientek-emmc.dts,命令如下:
cdarch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts
.dts是設備樹源碼文件,編譯Linux的時候會將其編譯為.dtb文件。imx6ull-alientek-emmc.dts創建好以後我們還需要修改文件arch/arm/boot/dts/Makefile,找到「dtb-$(CONFIG_SOC_IMX6ULL)」配置項,在此配置項中加入「imx6ull-alientek-emmc.dtb」,如下所示:
示例代碼37.3.2.1 arch/arm/boot/dts/Makefile代碼段
400 dtb-$(CONFIG_SOC_IMX6ULL)+=\
401 imx6ull-14x14-ddr3-arm2.dtb \
402 imx6ull-14x14-ddr3-arm2-adc.dtb \
403 imx6ull-14x14-ddr3-arm2-cs42888.dtb \
404 imx6ull-14x14-ddr3-arm2-ecspi.dtb \
405 imx6ull-14x14-ddr3-arm2-emmc.dtb \
406 imx6ull-14x14-ddr3-arm2-epdc.dtb \
407 imx6ull-14x14-ddr3-arm2-flexcan2.dtb \
408 imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb \
409 imx6ull-14x14-ddr3-arm2-lcdif.dtb \
410 imx6ull-14x14-ddr3-arm2-ldo.dtb \
411 imx6ull-14x14-ddr3-arm2-qspi.dtb \
412 imx6ull-14x14-ddr3-arm2-qspi-all.dtb \
413 imx6ull-14x14-ddr3-arm2-tsc.dtb \
414 imx6ull-14x14-ddr3-arm2-uart2.dtb \
415 imx6ull-14x14-ddr3-arm2-usb.dtb \
416 imx6ull-14x14-ddr3-arm2-wm8958.dtb \
417 imx6ull-14x14-evk.dtb \
418 imx6ull-14x14-evk-btwifi.dtb \
419 imx6ull-14x14-evk-emmc.dtb \
420 imx6ull-14x14-evk-gpmi-weim.dtb \
421 imx6ull-14x14-evk-usb-certi.dtb \
422 imx6ull-alientek-emmc.dtb \
423 imx6ull-9x9-evk.dtb \
424 imx6ull-9x9-evk-btwifi.dtb \
425 imx6ull-9x9-evk-ldo.dtb
第422行為「imx6ull-alientek-emmc.dtb」,這樣編譯Linux的時候就可以從imx6ull-alientek-emmc.dts編譯出imx6ull-alientek-emmc.dtb文件了。
37.3.3 編譯測試
經過37.3.1和37.3.2兩個小節,Linux內核裡面已經添加了正點原子I.MX6UL-ALIPHA EMMC版開發板了,接下接編譯測試一下,我們可以創建一個編譯腳本,imx6ull_alientek_emmc.sh,腳本內容如下:
示例代碼37.3.2.1 imx6ull_alientek_emmc.sh編譯腳本
1 #!/bin/sh
2 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-distclean
3 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-imx_alientek_emmc_defconfig
4 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-menuconfig
5 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-all -j16
第2行,清理工程。
第3行,使用默認配置文件imx_alientek_emmc_defconfig來配置Linux內核。
第4行,打開Linux的圖形配置界面,如果不需要每次都打開圖形配置界面可以刪除此行。
第5行,編譯Linux。
執行shell腳本imx6ull_alientek_emmc.sh編譯Linux內核,編譯完成以後就會在目錄arch/arm/boot下生成zImage鏡像文件。在arch/arm/boot/dts目錄下生成imx6ull-alientek-emmc.dtb文件。將這兩個文件拷貝到tftp目錄下,然後重啟開發板,在uboot命令模式中使用tftp命令下載這兩個文件並啟動,命令如下:
tftp 80800000 zImage
tftp 83000000 imx6ull-alientek-emmc.dtb
bootz 80800000 – 83000000
只要出現如圖37.3.3.1所示內容就表示Linux內核啟動成功:
圖37.3.3.1 Linux內核啟動
Linux內核啟動成功,說明我們已經在NXP提供的Linux內核源碼中添加了正點原子I.MX6UL-ALPHA開發板。
37.4 CPU主頻和網絡驅動修改
37.4.1 CPU主頻修改
1、設置I.MX6U-ALPHA開發板工作在528MHz
確保EMMC中的根文件系統可用!然後重新啟動開發板,進入終端(可以輸入命令),如圖37.4.1.1所示:
圖37.4.1.1 進入命令行
進入圖37.4.1所示的命令行以後輸入如下命令查看cpu信息:
cat /proc/cpuinfo
結果如圖37.4.2所示:
圖37.4.1.2 cpu信息
在圖37.4.2.1中有BogoMIPS這一條,此時BogoMIIS為3.00,BogoMIPS是Linux系統中衡量處理器運行速度的一個「尺子」,處理器性能越強,主頻越高,BogoMIPS值就越大。BogoMIPS只是粗略的計算CPU性能,並不十分準確。但是我們可以通過BogoMIPS值來大致的判斷當前處理器的性能。在圖37.4.1.2中並沒有看到當前CPU的工作頻率,那我們就轉變另一種方法查看當前CPU的工作頻率。進入到目錄/sys/bus/cpu/devices/cpu0/cpufreq中,此目錄下會有很多文件,如圖37.4.1.3所示:
圖37.4.1.3 cpufreq目錄
此目錄中記錄了CPU頻率等信息,這些文件的含義如下:
cpuinfo_cur_freq:當前cpu工作頻率,從CPU寄存器讀取到的工作頻率。
cpuinfo_max_freq:處理器所能運行的最高工作頻率(單位: KHz)。
cpuinfo_min_freq:處理器所能運行的最低工作頻率(單位: KHz)。
cpuinfo_transition_latency:處理器切換頻率所需要的時間(單位:ns)。
scaling_available_frequencies:處理器支持的主頻率列表(單位: KHz)。
scaling_available_governors:當前內核中支持的所有governor(調頻)類型。
scaling_cur_freq:保存著cpufreq模塊緩存的當前CPU頻率,不會對CPU硬體寄存器進行檢查。
scaling_driver:該文件保存當前CPU所使用的調頻驅動。
scaling_governor:governor(調頻)策略,Linux內核一共有5中調頻策略,
①、Performance,最高性能,直接用最高頻率,不考慮耗電。
②、Interactive,一開始直接用最高頻率,然後根據CPU負載慢慢降低。
③、Powersave,省電模式,通常以最低頻率運行,系統性能會受影響,一般不會用這個!
④、Userspace,可以在用戶空間手動調節頻率。
⑤、Ondemand,定時檢查負載,然後根據負載來調節頻率。負載低的時候降低CPU頻率,這樣省電,負載高的時候提高CPU頻率,增加性能。
scaling_max_freq:governor(調頻)可以調節的最高頻率。
cpuinfo_min_freq:governor(調頻)可以調節的最低頻率。
stats目錄下給出了CPU各種運行頻率的統計情況,比如CPU在各頻率下的運行時間以及變頻次數。
使用如下命令查看當前CPU頻率:
cat cpuinfo_cur_freq
結果如圖37.4.1.4所示:
圖37.4.1.4 當前CPU頻率
從圖37.4.1.4可以看出,當前CPU頻率為198MHz,工作頻率很低!其他的值如下:
cpuinfo_cur_freq = 198000
cpuinfo_max_freq = 528000
cpuinfo_min_freq = 198000
scaling_cur_freq = 198000
scaling_max_freq = 528000
cat scaling_min_freq = 198000
scaling_available_frequencies = 198000 396000 528000
cat scaling_governor = ondemand
可以看出,當前CPU支持198MHz、396MHz和528Mhz三種頻率切換,其中調頻策略為ondemand,也就是定期檢查負載,然後根據負載情況調節CPU頻率。因為當前我們開發板並沒有做什麼工作,因此CPU頻率降低為198MHz以省電。如果開發板做一些高負載的工作,比如播放視頻、播放視頻等操作那麼CPU頻率就會提升上去。查看stats目錄下的time_in_state文件可以看到CPU在各頻率下的工作時間,命令如下:
cat /sys/bus/cpu/devices/cpu0/cpufreq/stats/time_in_state
結果如圖37.4.1.5所示:
圖37.4.1.5 CPU運行頻率統計
從圖37.4.1.5中可以看出,CPU在198MHz、396MHz和528MHz都工作過,其中198MHz的工作時間最長!假如我們想讓CPU一直工作在528MHz那該怎麼辦?很簡單,配置Linux內核,將調頻策略選擇為performance。或者修改imx_alientek_emmc_defconfig文件,此文件中有下面幾行:
示例代碼37.4.1.1 調頻策略
41 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
42 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
43 CONFIG_CPU_FREQ_GOV_USERSPACE=y
44 CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
第41行,配置ondemand為默認調頻策略。
第42行,使能powersave策略。
第43行,使能userspace策略。
第44行,使能interactive策略。
將示例代碼37.4.1.1中的第41行屏蔽掉,然後在44行後面添加:
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
結果下所示:
示例代碼37.4.1.2 修改調頻策略
41 #CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
42 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
43 CONFIG_CPU_FREQ_GOV_USERSPACE=y
44 CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
45 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
修改完成以後重新編譯Linux內核,編譯之前先清理一下工程!因為我們重新修改過默認配置文件了,編譯完成以後使用新的zImage鏡像文件重新啟動Linux。再次查看/sys/devices/system/cpu/cpu0/cpufreq/ cpuinfo_cur_freq文件的值,如圖37.4.1.6所示:
圖37.4.1.6 當前CPU頻率
從圖37.4.1.6可以看出,當前CPU頻率為528MHz了。查看scaling_governor文件看一下當前的調頻策略,如圖37.4.1.7所示:
圖37.4.1.7 調頻策略
從圖37.4.1.7可以看出當前的CPU調頻策略為preformance,也就是高性能模式,一直以最高主頻運行。
我們再來看一下如何通過圖形化界面配置Linux內核的CPU調頻策略,輸入「makemenuconfig」打開Linux內核的圖形化配置界面,如圖37.4.1.8所示:
圖37.4.1.8 Linux內核圖形化配置界面
進入如下路徑:
CPU Power Management
-> CPU Frequency scaling
-> CPU Frequency scaling
-> Default CPUFreq governor
打開默認調頻策略選擇界面,選擇「performance」,如圖37.1.4.9所示:
圖37.1.4.9 默認調頻策略選擇
在圖37.1.4.9中選擇「performance」即可,選擇以後退出圖形化配置界面,然後編譯Linux內核,一定不要清理工程!否則的話我們剛剛的設置就會被清理掉。編譯完成以後使用新的zImage重啟Linux,查看當前CPU的工作頻率和調頻策略。
我們學習的時候為了高性能,大家可以使用performance模式。但是在以後的實際產品開發中,從省電的角度考慮,建議大家使用ondemand模式,一來可以省電,二來可以減少發熱。
2、超頻至700MHz
I.MX6ULL有多種型號,按照工作頻率可以分為528MHz、700Mhz(實際696MHz),800MHz(實際792MHz)和900MHz(實際頻率未知,應該在900MHz左右)。其中900MHz的不支持RGB屏幕,所以正點原子Linux團隊沒有選擇,而700MHz的沒有工業級(工作溫度-40~85°C以上),因此也沒有選擇700MHz的型號。最後就剩下了528MHz和800MHz的,目前正點原子只提供了528MHz的版本(型號為MCIMX6Y2CVM08AB),至於800MHz版本(型號為MCIMX6Y2CVM08AB)的核心板後續就看客戶的需求,如果有需求就會加上,但是800MHz版本的I.MX6ULL晶片會貴一些,成本會上漲。
雖然正點原子的I.MX6U-ALPHA開發板所選擇的I.MX6ULL標稱最高只能工作在528MHz,但是其是可以超頻的700MHz的(這裡的700MHz實際上只有696MHz,但是NXP官方宣傳其為700MHz,所以我們就統一稱為700MHz吧)。
聲明:
對於想體驗一下高性能的朋友體驗一下超頻,雖然筆者一直在用700MHz來測試,而且正點原子的I.MX6U-ALPHA開發板目前還沒有出現過超頻不穩定的現象發生,但是!畢竟是超頻了的,肯定沒有工作在528MHz穩定。
如果因為超頻帶來任何損壞,正點原子不負任何責任!
如果因為超頻帶來任何損壞,正點原子不負任何責任!
如果因為超頻帶來任何損壞,正點原子不負任何責任!
在實際的產品中,禁止任何超頻!務必嚴格按照I.MX6ULL手冊上給出的標準工作頻率來運行!!如果想要更高的性能,請購買相應型號的處理器!
看到這裡,如果您還是執意要超頻,那麼就接著往下看,如果要放棄超頻,那就跳過本小節,看下一小節。
超頻設置其實很簡單,修改一下設備樹文件imx6ull.dtsi即可,打開imx6ull.dtsi,找到下面代碼:
示例代碼37.4.1.3 imx6ull.dtsi文件代碼段
54 cpu0:cpu@0 {
55 compatible ="arm,cortex-a7";
56 device_type ="cpu";
57 reg =<0>;
58 clock-latency =<61036>;/* two CLK32 periods */
59 operating-points =<
60/* kHz uV */
619960001275000
627920001225000
635280001175000
643960001025000
65198000950000
66>;
67 fsl,soc-operating-points =<
68 /* KHz uV */
69 9960001175000
70 7920001175000
71 5280001175000
72 3960001175000
73 1980001175000
74 >;
示例代碼37.4.1.3就是設置CPU頻率的,第61~65行和第69~73行就是I.MX6ULL所支持的頻率,單位為KHz,可以看出I.MX6ULL(視具體型號而定)支持996MHz、792MHz、528MHz、396MHz和198MHz。在上一小節中,我們知道Linux內核默認支持198MHz、396MHz和528MHz,並不能支持到792MHz,說明MCIMX6Y2CVM05AB這顆晶片不能跑到792MHz。我們在示例代碼37.4.2.1中加入針對696MHz的支持,修改以後代碼如下:
示例代碼37.4.1.4 增加696MHz的支持
54 cpu0:cpu@0 {
55 compatible ="arm,cortex-a7";
56 device_type ="cpu";
57 reg =<0>;
58 clock-latency =<61036>;/* two CLK32 periods */
59 operating-points =<
60/* kHz uV */
619960001275000
627920001225000
636960001225000
645280001175000
653960001025000
66198000950000
67>;
68 fsl,soc-operating-points =<
69 /* KHz uV */
70 9960001175000
71 7920001175000
72 6960001175000
73 5280001175000
74 3960001175000
75 1980001175000
76 >;
第63行,加入了「696000 1225000」,這個就是696MHz的支持。
第72行,加入了「696000 1175000」,也是對696MHz的支持。
修改好以後保存,並且編譯設備樹,在Linux內核源碼根目錄下輸入如下命令編譯設備樹:
makedtbs
命令「makedtbs」只編譯設備樹文件,也就是將.dts編譯為.dtb,編譯完成以後使用新的設備樹文件imx6ull-alientek_emmc.dtb啟動Linux。重啟以後查看文件/sys/devices/system/cpu/cpu0/cpufreq/ scaling_available_frequencies的內容,如圖37.4.1.10所示:
圖37.4.1.10文件scaling_available_frequencies內容
從圖37.4.1.11可以看出,此時支持了696MHz。如果設置調頻策略為performance,那麼處理器就會一直工作在696MHz。可以對比一下工作在528MHz和696MHz下的BogoMIPS的值,528MHz主頻下的BogoMIPS值如圖37.4.1.12所示:
圖37.4.1.12528MHz主頻下的BogoMIPS
696MHz主頻下的BogoMIPS值如圖37.4.1.13所示:
圖37.4.1.13696MHz主頻下的BogoMIPS
從圖37.4.1.12和圖37.2.1.13中可以看到,528MHz和696MHz下的BogoMIPS值分別為8.00和10.54,相當於性能提升了(10.54/8)-1=31.75%。
37.4.2使能8線EMMC驅動
正點原子EMMC版本核心板上的EMMC採用的8位數據線,原理圖如圖37.4.2.1所示:
圖37.4.2.1 EMMC原理圖
Linux內核驅動裡面EMMC默認是4線模式的,4線模式肯定沒有8線模式的速度快,所以本節我們將EMMC的驅動修改為8線模式。修改方法很簡單,直接修改設備樹即可,打開文件imx6ull-alientek-emmc.dts,找到如下所示內容:
示例代碼37.4.2.1 imx6ull-alientek-emmc.dts代碼段
734&usdhc2 {
735 pinctrl-names ="default";
736 pinctrl-0=<&pinctrl_usdhc2>;
737 non-removable;
738 status ="okay";
739};
關於設備樹的原理以及內容我們後面會有專門的章節講解,示例代碼37.4.2.1中的代碼含義我們現在不去糾結,只需要將其改為如下代碼即可:
示例代碼37.4.2.1 imx6ull-alientek-emmc.dts代碼段
734&usdhc2 {
735 pinctrl-names ="default","state_100mhz","state_200mhz";
736 pinctrl-0=<&pinctrl_usdhc2_8bit>;
737 pinctrl-1=<&pinctrl_usdhc2_8bit_100mhz>;
738 pinctrl-2=<&pinctrl_usdhc2_8bit_200mhz>;
739 bus-width =<8>;
740 non-removable;
741 status ="okay";
742};
修改完成以後保存一下imx6ull-alientek-emmc.dts,然後使用命令「makedtbs」重新編譯一下設備樹,編譯完成以後使用新的設備樹重啟Linux系統即可。
37.4.3 修改網絡驅動
因為在後面學習Linux驅動開發的時候要用到網絡調試驅動,所以必須要把網絡驅動調試好。在講解uboot移植的時候就已經說過了,正點原子開發板的網絡和NXP官方的網絡硬體上不同,網絡PHY晶片由KSZ8081換為了LAN8720A,兩個網絡PHY晶片的復位IO也不同。所以Linux內核自帶的網絡驅動是驅動不起來I.MX6U-ALPHA開發板上的網絡的,需要做修改。
1、修改LAN8720的復位引腳驅動
ENET1復位引腳ENET1_RST連接在I.M6ULL的SNVS_TAMPER7這個引腳上。ENET2的復位引腳ENET2_RST連接在I.MX6ULL的SNVS_TAMPER8上。打開設備樹文件imx6ull-alientek-emmc.dts,找到如下代碼:
示例代碼37.4.3.1 imx6ull-alientek-emmc.dts代碼段
584 pinctrl_spi4:spi4grp {
585 fsl,pins =<
586 MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
587 MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
588 MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
589 MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
590>;
591};
示例代碼37.4.3.1中第588和589行就是初始化SNVS_TAMPER7和SNVS_TAMPER8這兩個引腳的,不過看樣子好像是作為了SPI4的IO,這不是我們想要的,所以將588和589這兩行刪除掉!刪除掉以後繼續在imx6ull-alientek-emmc.dts中找到如下所示代碼:
示例代碼37.4.3.2 imx6ull-alientek-emmc.dts代碼段
125 spi4 {
126 compatible ="spi-gpio";
127 pinctrl-names ="default";
128 pinctrl-0=<&pinctrl_spi4>;
129 pinctrl-assert-gpios =<&gpio5 8 GPIO_ACTIVE_LOW>;
......
133 cs-gpios =<&gpio5 70>;
第129行,設置GPIO5_IO08為SPI4的一個功能引腳(我也不清楚具體作為什麼功能用),而GPIO5_IO08就是SNVS_TAMPER8的GPIO功能引腳。
第133行,設置GPIO5_IO07作為SPI4的片選引腳,而GPIO5_IO07就是SNVS_TAMPER7的GPIO功能引腳。
現在我們需要GPIO5_IO07和GPIO5_IO08分別作為ENET1和ENET2的復位引腳,而不是SPI4的什麼功能引腳,因此將示例代碼37.4.3.2中的第129行和第133行處的代碼刪除掉!!否則會干擾到網絡復位引腳!
繼續在imx6ull-alientek-emmc.dts中找到如下所示代碼:
示例代碼37.4.3.3 imx6ull-alientek-emmc.dts代碼段
309 pinctrl_enet1:enet1grp {
310 fsl,pins =<
311 MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
312 MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
313 MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
314 MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
315 MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
316 MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
317 MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
318 MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
319>;
320};
321
322 pinctrl_enet2:enet2grp {
323 fsl,pins =<
324 MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
325 MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
326 MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
327 MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
328 MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
329 MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
330 MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
331 MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
332 MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
333 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
334>;
335};
第309~320行,pinctrl_enet1是ENET1的IO初始化配置。
第322~335行,pinctrl_enet2是ENET2的IO初始化配置。
根據示例代碼37.4.3.3,我們需要將ENET1的復位IO初始化配置添加到pinctrl_enet1中,將ENET2的復位IO初始化配置添加到pinctrl_enet2中,添加完成以後的代碼如下所示:
示例代碼37.4.3.4 imx6ull-alientek-emmc.dts代碼段
309 pinctrl_enet1:enet1grp {
310 fsl,pins =<
311 MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
312 MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
...
318 MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
319 MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0/* ENET1 RESET */
320>;
321};
322
323 pinctrl_enet2:enet2grp {
324 fsl,pins =<
325 MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
326 MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
...
334 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
335 MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0/* ENET2 RESET */
336>;
337};
第319行,ENET1復位引腳SNVS_TAMPER7的配置代碼。
第335行,ENET2復位引腳SNVS_TAMPER8的配置代碼。
修改完成以後記得保存一下imx6ull-alientek-emmc.dts,網絡的復位引腳驅動就修改好了。
2、修改LAN8720A的PHY地址
在uboot移植章節中,我們說過ENET1的LAN8720A地址為0x0,ENET2的LAN8720A地址為0x1。在imx6ull-alientek-emmc.dts中找到如下代碼:
示例代碼37.4.3.5 imx6ull-alientek-emmc.dts代碼段
171&fec1 {
172 pinctrl-names ="default";
173 pinctrl-0=<&pinctrl_enet1>;
174 phy-mode ="rmii";
175 phy-handle =<ðphy0>;
176 status ="okay";
177};
178
179&fec2 {
180 pinctrl-names ="default";
181 pinctrl-0=<&pinctrl_enet2>;
182 phy-mode ="rmii";
183 phy-handle =<ðphy1>;
184 status ="okay";
185
186 mdio {
187 #address-cells =<1>;
188 #size-cells =<0>;
189
190 ethphy0:ethernet-phy@0 {
191 compatible ="ethernet-phy-ieee802.3-c22";
192 reg =<2>;
193};
194
195 ethphy1:ethernet-phy@1 {
196 compatible ="ethernet-phy-ieee802.3-c22";
197 reg =<1>;
198};
199};
200};
第171~177行,ENET1對應的設備樹節點。
第179~200行,ENET2對應的設備樹節點。但是第186~198行的mdio節點描述了ENET1和ENET2的PHY地址信息。將示例代碼37.4.3.5改為如下內容:
示例代碼37.4.3.6 imx6ull-alientek-emmc.dts代碼段
171&fec1 {
172 pinctrl-names ="default";
173 pinctrl-0=<&pinctrl_enet1>;
174 phy-mode ="rmii";
175 phy-handle =<ðphy0>;
176 phy-reset-gpios =<&gpio5 7 GPIO_ACTIVE_LOW>;
177 phy-reset-duration =<26>;
178 status ="okay";
179};
180
181&fec2 {
182 pinctrl-names ="default";
183 pinctrl-0=<&pinctrl_enet2>;
184 phy-mode ="rmii";
185 phy-handle =<ðphy1>;
186 phy-reset-gpios =<&gpio5 8 GPIO_ACTIVE_LOW>;
187 phy-reset-duration =<26>;
188 status ="okay";
189
190 mdio {
191 #address-cells =<1>;
192 #size-cells =<0>;
193
194 ethphy0:ethernet-phy@0 {
195 compatible ="ethernet-phy-ieee802.3-c22";
196 smsc,disable-energy-detect;
197 reg =<0>;
198};
199
200 ethphy1:ethernet-phy@1 {
201 compatible ="ethernet-phy-ieee802.3-c22";
202 smsc,disable-energy-detect;
203 reg =<1>;
204};
205};
206};
第176和177行,添加了ENET1網絡復位引腳所使用的IO為GPIO5_IO07,低電平有效。復位低電平信號持續時間為26ms。
第186和187行,ENET2網絡復位引腳所使用的IO為GPIO5_IO08,同樣低電平有效,持續時間同樣為26ms。
第196和202行,「smsc,disable-energy-detect」表明PHY晶片是SMSC公司的,這樣Linux內核就會找到SMSC公司的PHY晶片驅動來驅動LAN8720A。
第194行,注意「ethernet-phy@」後面的數字是PHY的地址,ENET1的PHY地址為0,所以「@」後面是0(默認為2)。
第197行,reg的值也表示PHY地址,ENET1的PHY地址為0,所以reg=0。
第200行,ENET2的PHY地址為1,因此「@」後面為1。
第203行,因為ENET2的PHY地址為1,所以reg=1。
至此,LAN8720A的PHY地址就改好了,保存一下imx6ull-alientek-emmc.dts文件。然後使用「makedtbs」命令重新編譯一下設備樹。
3、修改fec_main.c文件
要在I.MX6ULL上使用LAN8720A,需要修改一下Linux內核源碼,打開drivers/net/ethernet/freescale/fec_main.c,找到函數fec_probe,在fec_probe中加入如下代碼:
示例代碼37.4.3.7 imx6ull-alientek-emmc.dts代碼段
3438staticint
3439 fec_probe(struct platform_device *pdev)
3440{
3441struct fec_enet_private *fep;
3442struct fec_platform_data *pdata;
3443struct net_device *ndev;
3444int i,irq, ret =0;
3445struct resource *r;
3446conststruct of_device_id *of_id;
3447staticint dev_id;
3448struct device_node *np =pdev->dev.of_node,*phy_node;
3449int num_tx_qs;
3450int num_rx_qs;
3451
3452/* 設置MX6UL_PAD_ENET1_TX_CLK和MX6UL_PAD_ENET2_TX_CLK
3453 * 這兩個IO的復用寄存器的SION位為1。
3454 */
3455void __iomem *IMX6U_ENET1_TX_CLK;
3456void __iomem *IMX6U_ENET2_TX_CLK;
3457
3458 IMX6U_ENET1_TX_CLK =ioremap(0X020E00DC,4);
3459 writel(0X14,IMX6U_ENET1_TX_CLK);
3460
3461 IMX6U_ENET2_TX_CLK =ioremap(0X020E00FC,4);
3462 writel(0X14,IMX6U_ENET2_TX_CLK);
3463
......
3656returnret;
3657}
第3455~3462就是新加入的代碼,如果要在I.MX6ULL上使用LAN8720A就需要設置ENET1和ENET2的TX_CLK引腳復位寄存器的SION位為1。
4、配置Linux內核,使能LAN8720驅動
輸入命令「makemenuconfig」,打開圖形化配置界面,選擇使能LAN8720A的驅動,路徑如下:
-> Device Drivers
-> Network device support
-> PHY Device support and infrastructure
-> Drivers for SMSC PHYs
如圖37.4.3.1所示:
圖37.4.3.1 使能LAN8720A驅動
圖37.4.3.1中選擇將「Drivers for SMSC PHYs」編譯到Linux內核中,因此「<>」裡面變為了「*」。LAN8720A是SMSC公司出品的,因此勾選這個以後就會編譯LAN8720驅動,配置好以後退出配置界面,然後重新編譯一下Linux內核。
5、修改smsc.c文件
在修改smsc.c文件之前先說點題外話,那就是我是怎麼確定要修改smsc.c這個文件的。在寫本書之前我並沒有修改過smsc.c這個文件,都是使能LAN8720A驅動以後就直接使用。但是我在測試NFS掛載文件系統的時候發現文件系統掛載成功率很低!老是提示NFS伺服器找不到,三四次就有一次掛載失敗!很折磨人。NFS掛載就是通過網絡來掛載文件系統,這樣做的好處就是方便我們後續調試Linux驅動。既然老是掛載失敗那麼可以肯定的是網絡驅動有問題,網絡驅動分兩部分:內部MAC+外部PHY,內部MAC驅動是由NXP提供的,一般不會出問題,否則的話用戶早就給NXP反饋了。而且我用NXP官方的開發板測試網絡是一直正常的,但是NXP官方的開發板所使用的PHY晶片為KSZ8081。所以只有可能是外部PHY,也就是LAN8720A的驅動可能出問題了。鑑於LAN8720A有「前車之鑑」,那就是在uboot中需要對LAN8720A進行一次軟復位,要設置LAN8720A的BMCR(寄存器地址為0)寄存器bit15為1。所以我猜測,在Linux中也需要對LAN8720A進行一次軟復位。
首先需要找到LAN8720A的驅動文件,LAN8720A的驅動文件是drivers/net/phy/smsc.c,在此文件中有個叫做smsc_phy_reset的函數,看名字都知道這是SMSC PHY的復位函數,因此,LAN8720A肯定也會使用到這個復位函數,此函數內容如下:
示例代碼37.4.3.8 smsc_phy_reset函數
60staticint smsc_phy_reset(struct phy_device *phydev)
61{
62 int rc =phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
63 if(rc <0)
64 returnrc;
65
66 /* If the SMSC PHY is in power down mode, then set it
67 * in all capable mode before using it.
68 */
69 if((rc &MII_LAN83C185_MODE_MASK)== MII_LAN83C185_MODE_POWERDOWN){
70 int timeout =50000;
71
72 /* set "all capable" mode and reset the phy */
73 rc |=MII_LAN83C185_MODE_ALL;
74 phy_write(phydev,MII_LAN83C185_SPECIAL_MODES, rc);
75 phy_write(phydev,MII_BMCR, BMCR_RESET);
76
77 /* wait end of reset (max 500 ms) */
78 do{
79 udelay(10);
80 if(timeout--==0)
81 return-1;
82 rc =phy_read(phydev, MII_BMCR);
83 }while(rc &BMCR_RESET);
84 }
85 return0;
86}
第69行,只有PHY處於powerdown模式的時候第70~83行的代碼段才會執行。
第75行,向LAN872A0的BMCR寄存器寫入BMCR_RESET,也就是對LAN8720A進行軟體初始化,所以smsc_phy_reset函數會對LAN8720A進行軟體初始化。
看到沒,只有LAN8720A處於powerdown模式的時候才會對LAN8720A進行軟復位,但是我們在uboot中已經「喚醒」了LAN8720A,LAN8720A也已經工作了,因此它不可能處於powerdown模式,進而就沒法對LAN8720A進行軟復位。因此,我們要對smsc_phy_reset函數函數進行修改,將復位相關的代碼從條件語句中提出來,不管LAN8720A有沒有工作在powerdown模式下,只要調用smsc_phy_reset函數就對LAN8720A進行軟復位,修改後的smsc_phy_reset函數內容如下:
示例代碼37.4.3.9 修改後的smsc_phy_reset函數
60staticint smsc_phy_reset(struct phy_device *phydev)
61{
62 int rc =phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
63 if(rc <0)
64 returnrc;
65
66 /* If the SMSC PHY is in power down mode, then set it
67 * in all capable mode before using it.
68 */
69 if((rc &MII_LAN83C185_MODE_MASK)== MII_LAN83C185_MODE_POWERDOWN){
70
71 /* set "all capable" mode and reset the phy */
72 rc |=MII_LAN83C185_MODE_ALL;
73 phy_write(phydev,MII_LAN83C185_SPECIAL_MODES, rc);
74 }
75
76 phy_write(phydev,MII_BMCR, BMCR_RESET);
77 /* wait end of reset (max 500 ms) */
78 int timeout =50000;
79 do{
80 udelay(10);
81 if(timeout--==0)
82 return-1;
83 rc =phy_read(phydev, MII_BMCR);
84 }while(rc &BMCR_RESET);
85
86 return0;
87}
重點是76~84行,我們將軟復位代碼移出來,這樣每次調用smsc_phy_reset函數LAN8720A都會被軟復位。修改以後基本上每次通過NFS掛載根文件系統都會成功。
6、網絡驅動測試
修改好設備樹和Linux內核以後重新編譯一下,得到新的zImage鏡像文件和imx6ull-alientek-emmc.dtb設備樹文件,使用網線將I.MX6U-ALPHA開發板的兩個網口與路由器或者電腦連接起來,最後使用新的文件啟動Linux內核。啟動以後使用「ifconfig」命令查看一下當前活動的網卡有哪些,結果如圖37.4.3.2所示:
圖37.4.3.2 ifconfig命令結果
從圖37.4.3.2可以看出,當前沒有活動的網卡。輸入命令「ifconfig-a」來查看一下開發板中存在的所有網卡,結果如圖37.4.3.3所示:
圖37.4.3.3 開發板所有網卡
圖37.4.3.3中can0和can1為CAN接口的網卡,eth0和eth1才是網絡接口的網卡,其中eth0對應於ENET1,eth1對應於ENET2。使用如下命令依次打開eth0和eth1這兩個網卡:
ifconfig eth0 up
ifconfig eth1 up
網卡的打開過程如圖37.4.3.4所示:
圖37.4.3.4 兩個網卡打開過程
從圖37.4.3.4中可以看到「SMSC LAN8710/LAN8720」字樣,說明當前的網絡驅動使用的就是我們前面使能的SMSC驅動。
再次輸入「ifconfig」命令來查看一下當前活動的網卡,結果如圖37.4.3.5所示:
圖37.4.3.5 當前活動的網卡。
可以看出,此時eth0和eth1兩個網卡都已經打開,並且工作正常,但是這兩個網卡都還沒有IP位址,所以不能進行ping等操作。使用如下命令給兩個網卡配置IP位址:
ifconfig eth0 192.168.1.251
ifconfig eth1 192.168.1.252
上述命令配置eth0和eth1這兩個網卡的IP位址分別為192.168.1.251和192.168.1.252,注意IP位址選擇的合理性,一定要和自己的電腦處於同一個網段內,並且沒有被其他的設備佔用!設置好以後,使用「ping」命令來ping一下自己的主機,如果能ping通那說明網絡驅動修改成功!比如我的Ubuntu主機IP位址為192.168.1.250,使用如下命令ping一下:
ping 192.168.1.250
結果如圖37.4.3.6所示:
圖37.4.3.6 ping結果
可以看出,ping成功,說明網絡驅動修改成功!我們在後面的構建根文件系統和Linux驅動開發中就可以使用網絡調試代碼啦,好嗨森!
37.4.4 保存修改後的圖形化配置文件
在修改網絡驅動的時候我們通過圖形界面使能了LAN8720A的驅動,使能以後會在.config中存在如下代碼:
CONFIG_SMSC_PHY=y
打開drivers/net/phy/Makefile,有如下代碼:
示例代碼37.4.4.1 drivers/net/phy/Makefile代碼段
11 obj-$(CONFIG_SMSC_PHY)+=smsc.o
當CONFIG_SMSC_PHY=y的時候就會編譯smsc.c這個文件,smsc.c就是LAN8720A的驅動文件。但是當我們執行「makeclean」清理工程以後.config文件就會被刪除掉,因此我們所有的配置內容都會丟失,結果就是前功盡棄,一「刪」回到解放前!所以我們在配置完圖形界面以後經過測試沒有問題,就必須要保存一下配置文件。保存配置的方法有兩個。
1、直接另存為.config文件
既然圖形化界面配置後的配置項保存在.config中,那麼就簡單粗暴,直接將.config文件另存為imx_alientek_emmc_defconfig,然後其複製到arch/arm/configs目錄下,替換以前的imx_alientek_emmc_defconfig。這樣以後執行「makeimx_alientek_emmc_defconfig」重新配置Linux內核的時候就會使用新的配置文件,默認就會使能LAN8720A的驅動。
2、通過圖形界面保存配置文件
相比於第1種直接另存為.config文件,第2種方法就很「文雅」了,在圖形界面中保存配置文件,在圖形界面中會有「< Save >」選項,如圖37.4.4.1所示:
圖37.4.4.1 保存配置
通過鍵盤的「→」鍵,移動到「< Save >」選項,然後按下回車鍵,打開文件名輸入對話框,如圖37.4.4.2所示:
圖37.4.4.2 輸入文件名
在圖37.4.4.2中輸入要保存的文件名,可以帶路徑,一般是相對路徑(相對於Linux內核源碼根目錄)。比如我們要將新的配置文件保存到目錄arch/arm/configs下,文件名為imx_alientek_emmc_defconfig,也就是用新的配置文件替換掉老的默認配置文件。那麼我們在圖37.4.4.2中輸入「arch/arm/configs/imx_alientek_emmc_defconfig」即可,如圖37.4.4.3所示:
圖37.4.4.3 輸入文件名
設置好文件名以後選擇下方的「< Ok >」按鈕,保存文件並退出。退出以後再打開imx_alientek_emmc_defconfig文件,就會在此文件中找到「CONFIG_SMSC_PHY=y」這一行,如圖37.4.4.4所示:
圖37.4.4.4 新的配置文件
同樣的,使用「makeimx_alientek_emmc_defconfig」重新配置Linux內核的時候,LAN8720A的驅動就會使能,並被編譯進Linux鏡像文件zImage中。
關於Linux內核的移植就講解到這裡,簡單總結一下移植步驟:
①、在Linux內核中查找可以參考的板子,一般都是半導體廠商自己做的開發板。
②、編譯出參考板子對應的zImage和.dtb文件。
③、使用參考板子的zImage文件和.dtb文件在我們所使用的板子上啟動Linux內核,看能否啟動。
④、如果能啟動的話就萬事大吉,如果不能啟動那就悲劇了,需要調試Linux內核。不過一般都會參考半導體官方的開發板設計自己的硬體,所以大部分情況下都會啟動起來。啟動Linux內核用到的外設不多,一般就DRAM(Uboot都初始化好的)和串口。作為終端使用的串口一般都會參考半導體廠商的Demo板。
⑤、修改相應的驅動,像NAND Flash、EMMC、SD卡等驅動官方的Linux內核都是已經提供好了,基本不會出問題。重點是網絡驅動,因為Linux驅動開發一般都要通過網絡調試代碼,所以一定要確保網絡驅動工作正常。如果是處理器內部MAC+外部PHY這種網絡方案的話,一般網絡驅動都很好處理,因為在Linux內核中是有外部PHY通用驅動的。只要設置好復位引腳、PHY地址信息基本上都可以驅動起來。
⑥、Linux內核啟動以後需要根文件系統,如果沒有根文件系統的話肯定會崩潰,所以確定Linux內核移植成功以後就要開始根文件系統的構建。