【f1c200s笔记三】Linux内核编译

一、内核源码

1、首先,源码可以从官网进行下载,官网地址是

https://www.kernel.org

本教程使用的是5.7.1,也可以从如下网址直接下载

https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.7.1.tar.gz

将下载好的压缩包放在提前准备好的路径/usr/local/f1c200s/kernel下面

2、如同u-boot,kernel也需要进行配置,且内核源码里面也有全志官方的配置文件sunxi_defconfig。但是若要适配f1c200s,仍需要修改很多其他的参数,所以我们使用比较完备的licheepi的配置文件。

配置文件下载地址

链接:https://pan.baidu.com/s/1VCKU3mChoZ2fUkkayI6WkQ?pwd=k7d6

下载之后将配置文件放置在内核同样的位置,/usr/local/f1c200s/kernel

二、源码配置

1、首先进入目录/usr/local/f1c200s/kernel,对源码进行解压缩

#进行内核源码解压缩
tar -vxf linux-5.7.1.tar.gz

#然后进入解压出来的目录
cd linux-5.7.1

2、解压缩之后,配置架构和交叉编译器。这里同样可以使用grep命令,查看CROSS_COMPILE的位置(但是实际上源代码里面并没有定义,需要手动添加)

#首先执行vim命令,打开Makefile文件
vim Makefile

#然后在Makefile文件的开头位置,添加如下代码,用来指定架构和编译器
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-gnueabi-

3、修改完Makefile之后,再对设备树进行修改。linux设备相关模型大致为 总线->>驱动->>设备。

a、总线比如说iic总线,spi总线,是一大类的统称,其中有一个比较特殊的是platform总线,表示的是没有明确归类的虚拟的总线,比如要控制一个io口可能就需要用到它。我们平时用的最多的就是虚拟总线。

b、驱动,自然就是控制设备运行的驱动程序,它和设备相互组合。

c、linux中,设备和驱动的组合,是内核自动匹配的。所以呢,假如我们要实现一个设备的功能,我们就需要注册设备和驱动,并指出设备所需要的驱动名称,内核匹配完成,就可以正常驱动设备了。

d、为了方便归纳设备,linux把原本需要从代码中添加设备的方式,变更为设备树文件的方式,这样,添加设备的时候就不需要修改代码,只需要在设备树文件.dts里面添加,在内核编译的过程中,设备树文件会被编译成dtb,被内核直接调用。

4、设备树文件之所以叫树,就是因为设备之间存在着关系,就像树一样,有主干有枝干。一个设备就是一个节点,所有的节点都挂在根节点下,f1c200s根节点以下有三个重要的节点,分别是clocks,cpus,soc。意如其名。

#include "suniv-f1c100s.dtsi"  //设备树文件也可以像c语言一样加载其他的设备文件

/{  //根节点
	...
	clocks{  //时钟节点
		...  //每个节点下都会有对应的配置信息
	}
	cpus{
		...  //子节点下还可以有自己的子节点
	}
	...
}

5、博主使用的硬件,是用TF卡启动的,而官方配置里面是用spiflash启动的,所以呢,就需要在设备树文件里面添加mmc设备(TF卡)

a、首先进入目录/usr/local/f1c200s/kernel/linux-5.7.1/arch/arm/boot/dts,打开文件suniv-f1c100s.dtsi,在节点soc->pio下添加如下内容,进行引脚申请。

			mmc0_pins: mmc0-pins {  //分号之前是给节点起的名字
				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";  //申请引脚
				function = "mmc0";  //指定设备
			};

b、依然是文件suniv-f1c100s.dtsi,在soc节点下,添加mmc0设备

		mmc0: mmc@1c0f000 {  //@后面是设备的地址
			compatible = "allwinner,suniv-f1c100s-mmc",  //这里是指定厂商和驱动,有两个参数,表示
				"allwinner,sun7i-a20-mmc";               //此设备支持这两种驱动,内核会依次查找匹配
			reg = <0x01c0f000 0x1000>;  //这里是从芯片手册得到的寄存器地址和长度
			clocks = <&ccu CLK_BUS_MMC0>,  //这里是此设备需要用到的时钟
				<&ccu CLK_MMC0>,
				<&ccu CLK_MMC0_OUTPUT>,
				<&ccu CLK_MMC0_SAMPLE>;
			clock-names = "ahb",  //给时钟起的名字
				"mmc",
				"output",
				"sample";
			resets = <&ccu RST_BUS_MMC0>;  //指定复位单元
			reset-names = "ahb";
			interrupts = <23>;  //中断号,和芯片手册相对应
			pinctrl-names = "default";  //引脚名称
			pinctrl-0 = <&mmc0_pins>;  //引脚列表,就是在soc->pio内定义的节点
			status = "disabled";  //状态设为关闭
			#address-cells = <1>;  //设置子节点的地址占用大小
			#size-cells = <0>;  //设置子节点寄存器尺寸描述占用大小
		};

c、当然不能忘了,在文件suniv-f1c100s.dtsi的开头位置,添加两个头文件,不然设备节点上面调用的时钟就找不到定义的位置了。

#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
#include <dt-bindings/reset/suniv-ccu-f1c100s.h>

d、再接下来,就需要修改suniv-f1c100s-licheepi-nano.dts了,同样是在路径/usr/local/f1c200s/kernel/linux-5.7.1/arch/arm/boot/dts下,打开文件suniv-f1c100s-licheepi-nano.dts。细心的读者就会发现,在文件的开头,已经把suniv-f1c100s.dtsi加载进来了。

两个文件的两个根节点,其实就是同一个根节点。在根节点下添加3.3v设备。在根节点之外,启动mmc设备。

	reg_vcc3v3: vcc3v3 {
		compatible = "regulator-fixed";
		regulator-name = "vcc3v3";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
	};
&mmc0 {
	vmmc-supply = <&reg_vcc3v3>;
	bus-width = <4>;
	broken-cd;
	status = "okay";
};

e、做完上面的操作,设备树就已经配置完成啦。

6、配置完设备树,然后就可以进行菜单配置了。

#首先进入目录
cd /usr/local/f1c200s/kernel

#解压缩licheepi的官方配置
unzip linux-licheepi_nano_defconfig.zip

#将配置文件复制到指定目录
cp linux-licheepi_nano_defconfig linux-5.7.1/arch/arm/configs/

#进入内核源码目录
cd linux-5.7.1

#在进行最终配置的时候,先安装一些必须的插件
sudo apt-get install flex
sudo apt-get install bison
sudo apt-get install openssl
sudo apt-get install libssl-dev
sudo apt-get install bc

#将licheepi官方配置套用到源码
make linux-licheepi_nano_defconfig

如果还需要配置其他的参数,还可以通过执行make menuconfig进行菜单配置。最后,执行make命令,进行编译

7、编译完成之后,会在路径/usr/local/f1c200s/kernel/linux-5.7.1/arch/arm/boot下,生成zImage,会在路径/usr/local/f1c200s/kernel/linux-5.7.1/arch/arm/boot/dts下,生成文件suniv-f1c100s-licheepi-nano.dtb。这两个文件就分别是内核和设备树。

三、TF卡分区

1、u-boot那一篇讲过,在芯片启动的时候,soc会自动的从启动位置(TF卡)读取4k内容,而这4k内容,在tf卡上就是开头的绝对物理地址。

2、上一篇也讲过,u-boot启动以后,会从mmc读取内核和设备树到内存。所以tf卡是需要我们提前分区处理好,并且要提前把内核和设备树文件放入到指定位置。

3、ubuntu下有gparted软件,可以很方便的对TF卡进行分区,而且是界面操作。

4、首先把TF卡的开头2M预留出来,用作u-boot的存储。

5、接着2M的空间,设置32M大小的区域,并且设置文件系统为fat16格式。u-boot配置时有命令load mmc 0:1 0x80008000 zImage;等,就是从这个空间复制文件到内存,因为u-boot只能识别fat16格式,所以格式设置为fat16,名称设置为boot。

6、在之后的TF卡剩余空间,可以根据需求设置大小,但是最小不能小于100M,因为这里是放根文件系统的地方。把这个区域设置为ext4文件系统,设置名称为roots。

7、接下来,就可以使用mount命令挂载磁盘了。使用cp命令,将文件zImage和suniv-f1c100s-licheepi-nano.dtb复制到boot内。完成后记得使用umount卸载磁盘。

8、最后,将TF卡插入到开发板上,上电,就可以看到加载内核的打印信息。

博客内容均系原创,未经允许严禁转载!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇