文章目录
内核的下载
生成配置文件
编译
解决错误
启动内核
配置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
^~~~~~~~~~~~~~~
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_2*/
interrupts = <2 4>;
local-mac-address = [00 00 de ad be ef];
davicom,no-eeprom;
vcc-supply = ;
clocks = ;
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
#include
+//用于sromc时钟
+#include
+
#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 = ;
pinctrl-names = "default";
status = "okay";
//不能进行热插拔,设备一直连接
non-removable;
};
&sdhci2 {
bus-width = <4>;
pinctrl-0 = ;
pinctrl-names = "default";
status = "okay";
//指定热插拔检测引脚GPG2_2,低电平激活
cd-gpios = ;
};
设备树的其它修改
未使用的设备暂时全部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";
};
欢迎扫码关注我的微信公众号