文章目錄
內核的下載
生成配置文件
編譯
解決錯誤
啟動內核
配置u-boot的環境變量
編譯內核并啟動
注意點
網絡支持
SD/MMC支持
設備樹的其它修改
點擊下方閱讀原文可訪問文中超鏈接
內核的下載
還是和u-boot移植的步驟差不多,首先是要選擇一個版本,然后下載鏡像,確保能夠正確編譯成功。對于版本的選擇,因為我是學習用,所以選擇較新的版本,我看了一下目前版本比較新且是穩定版的是5.7.8版本,所以決定采用這個版本的內核進行移植。下載鏈接如下:
https://www.kernel.org/
生成配置文件
和u-boot的一樣,也是首先生成.config配置文件,實際上u-boot那一套都是從內核這里移植過去的。解壓內核后進入內核根目錄運行如下命令:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- s5pv210_defconfig
編譯
執行如下命令編譯內核:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
不幸的是我這里才開始編譯就出錯了,提示找不到頭文件,這個是加解密相關的:
HOSTCC scripts/kallsyms
HOSTCC scripts/sorttable
HOSTCC scripts/asn1_compiler
HOSTCC scripts/extract-cert
scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: 沒有那個文件或目錄
#include <openssl/bio.h>
^~~~~~~~~~~~~~~
compilation terminated.
解決錯誤
如果你的編譯沒有問題,那么直接跳過。先通過如下命令搜索一下有沒有這個頭文件:
sudo find / -name bio.h
查找出來只有兩個,但是并不是我們想要的,我看了一下,我的ubuntu中安裝了openssl的,只是缺少相應的文檔及頭文件,因為以前沒有做過安全套接字或者加解密相關的應用開發,所以沒有發現缺少相關的文檔及頭文件。
/usr/src/linux-headers-4.15.0-106/include/linux/bio.h
/usr/src/linux-headers-4.15.0-101/include/linux/bio.h
通過如下命令安裝好即可:
sudo apt-get install openssl
# 主要是這個
sudo apt-get install libssl-dev
接下來繼續編譯,已經能夠編譯成功了。
啟動內核
配置u-boot的環境變量
我這里直接貼出我的環境變量,不進行講解,直接修改include/configs/s5p_goni.h頭文件里面定義環境變量的宏即可,高版本的u-boot啟動內核時可以使用類似shell腳本的方式,需要單獨編寫一個類似shell腳本的文件,啟動內核時u-boot會讀取這個腳本文件,根據對應內容來啟動內核,但是我這里還是使用傳統方式:
#define CONFIG_EXTRA_ENV_SETTINGS \
"bootcmd=run mmcboot\0" \
"serverip=192.168.0.160\0" \
"ipaddr=192.168.0.10\0" \
"bootk=bootz 30008000 - 30500000\0" \
"nfsboot=" \
"set bootargs root=/dev/nfs nfsroot=192.168.0.160:/home/wei/Desktop/nfs/rootfs ip=${ipaddr} rw rootwait earlyprintk console=ttySAC2,115200n8;"\
"tftpboot 30008000 zImage;" \
"tftpboot 30500000 s5pv210-smdkv210.dtb;" \
"run bootk\0" \
"mmcboot=" \
"set mmcdev 1;" \
"fatload mmc 1 30008000 zImage;" \
"fatload mmc 1 30500000 s5pv210-smdkv210.dtb;" \
"run bootk\0"
啟動u-boot后看到的環境變量如下,其中有幾個是在u-boot代碼中設置的:
baudrate=115200
bootcmd=run mmcboot
bootk=bootz 30008000 - 30500000
ethact=dm9000
fdtcontroladdr=4af8e190
ipaddr=192.168.0.10
mmcboot=set mmcdev 1;fatload mmc 1 30008000 zImage;fatload mmc 1 30500000 s5pv210-smdkv210.dtb;run bootk
nfsboot=set bootargs root=/dev/nfs nfsroot=192.168.0.160:/home/***/rootfs ip=${ipaddr} rw rootwait earlyprintk console=ttySAC2,115200n8;tftpboot 30008000 zImage;tftpboot 30500000 s5pv210-smdkv210.dtb;run bootk
serverip=192.168.0.160
編譯內核并啟動
確定內核能夠正確編譯后,第一件事先配置輸出早期的調試信息,確定下當前內核使用的調試串口是哪一個,要是接錯了串口就算啟動了內核也是什么也看不到,由于在u-boot中使用的串口2,懶得切換所以這里也用串口2作為調試串口。通過menuconfig配置內核通過串口2輸出調試信息:
Kernel hacking --->
arm Debugging --->
[*] Kernel low-level debugging functions (read help!)
Kernel low-level debugging port (Use Samsung S3C UART 0 for low-level debug) --->
(X) Use Samsung S3C UART 2 for low-level debug
[*] Early printk
再次編譯后,嘗試啟動內核,內核已經能夠成功啟動了。
...
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 5.7.8 (wei@ubuntu) (gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04), GNU ld (GNU Binutils for Ubuntu) 2.30) #4 PREEMPT Wed Jul 15 08:25:10 PDT 2020
CPU: ARMv7 Processor [412fc082] revision 2 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt: Machine model: YIC System SMDKV210 based on S5PV210
printk: bootconsole [earlycon0] enabled
...
注意點
啟動內核前確定好u-boot中的bootargs參數是否正確,我的做法是在u-boot中不設置bootargs參數,而是使用內核設備樹傳參的方式設置,因為u-boot中的bootargs參數會覆蓋掉設備樹中的。
網絡支持
把開發板上面的dm9000網卡驅動起來,修改內核支持dm9000網卡,通過menuconfig配置:
Device Drivers --->
[*] Network device support --->
[*] Ethernet driver support --->
<*> DM9000 support
修改設備樹dm9000網卡的內容:
/*參考Documentation/devicetree/bindings/net/davicom-dm9000.txt*/
ethernet@88000000 {
compatible = "davicom,dm9000";
reg = <0x88000000 0x2 0x88000004 0x2>;
interrupt-parent = <&gph1>;
/*中斷引腳gph1_2*/
interrupts = <2 4>;
local-mac-address = [00 00 de ad be ef];
davicom,no-eeprom;
vcc-supply = <ð0_power>;
clocks = <&clocks CLK_SROMC>;
clock-names = "sromc";
};
/*參考其它板子,設不設置都不影響,只是強迫癥*/
eth0_power: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "eth0_power";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
添加dm9000網卡sromc時鐘初始化補丁,參考補丁網址:
--- dm9000.original.c 2020-07-16 07:55:30.293510666 -0700
+++ drivers/net/ethernet/davicom/dm9000.c 2020-07-16 07:55:35.429510583 -0700
@@ -35,6 +35,9 @@
#include <asm/irq.h>
#include <asm/io.h>
+//用于sromc時鐘
+#include <linux/clk.h>
+
#include "dm9000.h"
/* Board/System/Debug information/definition ---------------- */
@@ -1428,6 +1431,8 @@ dm9000_probe(struct platform_device *pde
enum of_gpio_flags flags;
struct regulator *power;
bool inv_mac_addr = false;
+ //用于sromc時鐘
+ const char *clk_name;
power = devm_regulator_get(dev, "vcc");
if (IS_ERR(power)) {
@@ -1563,6 +1568,19 @@ dm9000_probe(struct platform_device *pde
goto out;
}
+ /* Enable clock if specified */
+ //用于sromc時鐘
+ if (!of_property_read_string(dev->of_node, "clock-names", &clk_name)) {
+ struct clk *clk = devm_clk_get(dev, clk_name);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "cannot get clock of %s\n", clk_name);
+ ret = PTR_ERR(clk);
+ goto out;
+ }
+ clk_prepare_enable(clk);
+ dev_info(dev, "enable clock ‘%s’\n", clk_name);
+ }
+
/* fill in parameters for net-dev structure */
ndev->base_addr = (unsigned long)db->io_addr;
SD/MMC支持
修改設備樹,我的SD0是EMMC,SD2是SD卡,在設備樹中只使能這兩個通道:
&sdhci0 {
bus-width = <4>;
pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus1 &sd0_bus4>;
pinctrl-names = "default";
status = "okay";
//不能進行熱插拔,設備一直連接
non-removable;
};
&sdhci2 {
bus-width = <4>;
pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
pinctrl-names = "default";
status = "okay";
//指定熱插拔檢測引腳GPG2_2,低電平激活
cd-gpios = <&gpg2 2 1>;
};
設備樹的其它修改
未使用的設備暫時全部disable掉
內存的配置
memory@20000000 {
device_type = "memory";
/*起始地址和大小*/
reg = <0x30000000 0x20000000>;
};
bootargs的配置,我的文件系統被固化在了mmc的第二個分區,第一個分區用來存儲zImage和設備樹
chosen {
bootargs = "console=ttySAC2,115200n8 root=/dev/mmcblk0p2 rw rootwait ignore_loglevel earlyprintk";
};
歡迎掃碼關注我的微信公眾號