「正點原子Linux連載」第三十七章Linux內核移植

2020-12-24 正點原子

第三十七章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 =<&ethphy0>;

176 status ="okay";

177};

178

179&fec2 {

180 pinctrl-names ="default";

181 pinctrl-0=<&pinctrl_enet2>;

182 phy-mode ="rmii";

183 phy-handle =<&ethphy1>;

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 =<&ethphy0>;

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 =<&ethphy1>;

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內核移植成功以後就要開始根文件系統的構建。

相關焦點

  • 「正點原子Linux連載」第五十八章Linux INPUT子系統實驗
    第五十八章Linux INPUT子系統實按鍵、滑鼠、鍵盤、觸控螢幕等都屬於輸入(input)設備,Linux內核為此專門做了一個叫做input子系統的框架來處理輸入事件。輸入設備本質上還是字符設備,只是在此基礎上套上了input框架,用戶只需要負責上報輸入事件,比如按鍵值、坐標等信息,input核心層負責處理這些事件。
  • 「正點原子Linux連載」第五十九章Linux LCD驅動實驗
    pinctrl_lcdif_reset是LCD復位IO信息節點,正點原子的I.MX6U-ALPHA開發板的LCD沒有用到復位IO,因此pinctrl_lcdif_reset可以刪除掉。第6行,display屬性,指定LCD屬性信息所在的子節點,這裡為display0,下面就是display0子節點內容。
  • 「正點原子Linux連載」第四十二章新字符設備驅動實驗
    解決這兩個問題最好的方法就是要使用設備號的時候向Linux內核申請,需要幾個就申請幾個,由Linux內核分配設備可以使用的設備號。Linux內核添加字符設備。42.4硬體原理圖分析本章實驗硬體原理圖參考8.3小節即可。42.5實驗程序編寫本實驗對應的例程路徑為:開發板光碟->2、Linux驅動例程->3_newchrled。本章實驗在上一章實驗的基礎上完成,重點是使用了新的字符設備驅動、設置了文件私有數據、添加了自動創建設備節點相關內容。
  • Linux-1.1.1 Linux與開源軟體(背書連載)
    很多新手都有一個疑惑的問題:「linux我聽過,但是學習之後能用來幹什麼呢?或者說linux能具體做什麼呢?」帶著這個疑問,本書開篇先概述linux與開源軟體的關係以及linux的應用領域和未來的發展方向。
  • Linux內核學習:簡單的字符設備驅動
    學習Linux內核最好的入門方式之一是從字符設備驅動開始模仿(來自於《奔跑吧 Linux內核——入門篇》)。對於我們日常生活中存在的大量設備,如攝像頭,USB充電器,藍牙,Wi-Fi等,這些設備在電氣特性和實現原理均不相同,對Linux系統來說如何抽象和描述他們呢?Linux很早就根據設備共同特徵將其劃分為三大類型:1,字符設備;塊設備;網絡設備。
  • ZYNQ Linux作業系統移植四個部分說明文檔
    > ZYNQ上面移植Linux作業系統包括四個部分,uboot,devicetree,kernel,ramdisk.(這個根據硬體在sdk中創建),然後執行uboot,uboot會將kernel、devicetree和ramdisk載入ddr,跳轉到內核入口處執行,這樣linux就啟動了。
  • vxworks和linux有什麼區別
    微內核便是將服務轉移到進程上的一種內核模式,主要應用在實時系統和嵌入式系統上,主要是因為通常這些系統都不帶磁碟,整個系統必須都放在EPROM中,常常受到存儲空間的限制,而且所需的服務也比較單一,如PSOS,VxWorks等。 宏內核是一種傳統的內核結構,它將進程管理,內存管理等各項服務功能都放到內核中去,通常用在通用式內核上,如UNIX,linux等。
  • 「正點原子Linux連載」第四十五章 pinctrl和gpio子系統實驗一
    第四十五章 pinctrl和gpio子系統實驗上一章我們編寫了基於設備樹的LED驅動,但是驅動的本質還是沒變,都是配置LED燈所使用的GPIO寄存器,驅動開發方式和裸機基本沒啥區別。如果對Linux內核的pinctrl子系統實現原理感興趣的話可以看本小節。所有的東西都已經準備好了,包括寄存器地址和寄存器值,Linux內核相應的驅動文件就會根據這些值來做相應的初始化。
  • 《Linux就該這麼學》與《鳥哥的linux私房菜》哪個更適合初學者?
    也就是說無論你使用Windows多好,對於linux系統來說你都是個小白。時不時在一起聚會中也會說到一些關於linux的話題,談及關於linux「升級」話題時,一致的表示linux是一個「先苦後甜」系統。學習使用的時候非常難,但是一旦學習成功,那就是步入一馬平川之境界。
  • 從串口驅動到Linux驅動模型,想轉Linux的必會!
    前段時間有黑客成功的把Linux移植到一個佳能照相機上。並且在這個照相機上運行了一些主流的軟體。可以說。只要有足夠可以利用的硬體資源。就可以把Linux移植到這個硬體平臺上去。這個資源的最低要求往往很低。這可以與對硬體資源要求很高的Windows有一個鮮明的對比。舉個例子就是。當Windows 10的升級提示從你計算機的右下角彈出時。你可以不假思索的點擊『馬上升級』嗎?
  • 麒麟作業系統:在linux上運行安卓應用
    使用安卓生態,對於發展linux系統來說相當重要,畢竟安卓也是基於linux內核,兩者關係密切。麒麟軟體和技徳系統團隊合作,讓麒麟系統可以運行安卓應用。其依託安卓運行環境Kydroid 3.0,可提供完全原生、高兼容性的使用體驗。
  • linux系統工控機-ubuntu烏班圖嵌入式工業電腦
    linux系統工控機-807A正面Linux是自由的免費開源的,它是以unix為原型改造的,一個多用戶多任務的作業系統,任何人都可以修改其代碼和頁面,其中主要的目的就是為了不收商業化的限制,而我們將伺服器部署在linux系統上會更加高效穩定、安全(註:UNIX作業系統(尤尼斯),是一個強大的多用戶、多任務作業系統,支持多種處理器架構
  • Linux-1.2.1 常見的Linux發行版本(背書連載)
    雖然歷史不及其他Linux歷史久遠,但比起很多的linux發行套件還是要歷史悠久很多的。自從Red Hat 9.0發行之後,2004年4月30日 Red Hat公司就不在開發桌面版本的Linux發行套件了,而是將全部的精力集中到伺服器版本的開發上,也就是Red Hat Enterprise Linux版。
  • 微軟能否放棄 Windows 轉向 Linux?|Linux 中國
    本文字數:2939,閱讀時長大約:4分鐘 https://linux.cn/article-12718-1.html 作者:Jack-wallen 譯者:XianLei Gao Jack Wallen 認為,Microsoft
  • Arch Linux 2018.08.01 更新發布,使用Linux Kernel 4.17.11
    Linux 4.17.11是目前最先進的穩定內核,在編寫的時候,它被推薦給所有Arch Linux用戶,以及其他GNU/Linux發行版的用戶,如果他們能夠從他們最喜歡的作業系統的官方軟體庫中安裝它的話。但是,與以前的ISO快照一樣,Arch Linux 2018.08.01僅針對計劃因為任何原因重新安裝Arch Linux計算機的用戶。
  • linux基礎04:linux用戶相關的命令有哪些?怎樣切換用戶?
    通過前面的幾節課,我們在windows系統中安裝好了linux虛擬機,也通過xshell遠程終端連接上了linux虛擬。從今天開始,我們就可以正式開始學習linux的知識了。今天,我們主要介紹的是用戶相關的一些命令,如:創建用戶命令、用戶退出登錄命令、用戶切換命令等。
  • linux 虛擬主機好嗎
    linux 虛擬主機好嗎?linux 虛擬主機是採用Linux系統搭建的虛擬主機,是企業和個人都非常喜歡使用的虛擬主機種類。運行穩定,對軟體的兼容遠超Windows系統。又由於代碼開源,即使linux不幸感染病毒,維護人員也容易查出運行異常之處,並加以解決。平時,linux系統也可利用自帶防火牆、入侵檢測和安全認證等工具及時修補漏洞,提高系統安全性。
  • 黑客神器-kali linux
    kali linux。ta已經預裝了很多安全方面的神器,比在windows使用一個個安裝的工具要舒服很多,現在這個kali linux已經出到2019版了,2020版應該很快也會出來了,想要下載最新版的kali linux可以百度一下kali linux就會出現官網了。然後下載。這個可以進行arp攻擊等等,還能進行社工等等。
  • Linux進程終止命令kill或killall筆記
    在linux命令下,如果需要終止某個進程,可以使用kill或者killall等命令來實現。終止命令的原理都是向linux內核發送一個系統操作的信號以及某個進程的ID,然後系統內核會根據指定的進程ID進行相應的處理。
  • WireGuard VPN使其達到1.0 並成為下一個Linux內核
    Android內核存儲庫也有一個誘人的不同之處,暗示Android用戶可能會在未來的Android版本中看到更新後的內核版本。WireGuard本身的版本增加到了1.0.0,同時也加入了新內核。那些熟悉開源版本控制標準的人可能並沒有因為它之前的0.8版本而感到沮喪。x或0.9。畢竟,Dovecot多年來一直是世界上使用0.4版本的IMAP4伺服器,但現在是1版本。x版本控制可能會緩解管理人員或不太熟悉linux的人的顧慮。