没志青年
发布于 2025-06-14 / 31 阅读
0

Linux 系统移植

内核配置

(1)需要先设置CPU的架构,和交叉编译工具:

在顶层 Makefile 文件,将:

ARCH		?= $(SUBARCH)
CROSS_COMPILE	?= $(CONFIG_CROSS_COMPILE:"%"=%)

改为:

ARCH		?= arm
CROSS_COMPILE	?= arm-linux-gnueabihf-

(2)

在执行make任何命令之前,确保设置了交叉编译工具的环境变量,这里不把路径写死了,因为不止用一个芯片,都设置了环境变量的话,版本之间会冲突,编译报错啥的。

这里选择在终端中激活环境变量,并起别名简化代码。

每次编译的时候,必须得设置当前终端的环境变量,因为它可不知道你的arm-linux-gnueabihf-系列工具在哪。

sudo vim ~/.bashrc

在第一行添加:
alias getimx='export PATH=$PATH:/Dev-Tools/Tool-Chain/IMX6ULL/gcc-linaro-4.9.4/bin'

source ~/.bashrc

然后每次使用前在终端中输入 getimx 就行了。

(3)首先我们需要一个基础的配置文件,不用从头开始写,直接拿芯片官方评估板的配置文件,在此基础上修改。

I.MX6ULL 的评估板是 EVK,imx_v7_defconfig 和 imx_v7_mfg_defconfig 配置文件都可以,带 _mfg_ 意味着编译出来的镜像可以使用官方的 mfg 工具进行烧录。

推荐使用 imx_v7_mfg_defconfig,clean 是必要的。

在/arch/arm/configs中,复制它为一个新的文件:aaa1_defconfig

修改:

这个V6关闭掉,因为芯片是ARMV7

# CONFIG_ARCH_MULTI_V6=y

make clean
make aaa1_defconfig

成功的话输出:
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#

然后就是复制一份,搞自己的设备树了。

arch/arm/boot/dts

cp imx6ull-14x14-evk.dts aaa1.dts

在 arch/arm/boot/dts/Makefile 中添加一行:

dtb-$(CONFIG_SOC_IMX6ULL) += \
    aaa1.dtb \   添加这一行
	imx6ull-14x14-ddr3-arm2.dtb \
	imx6ull-14x14-ddr3-arm2-adc.dtb \

(4)使用图形化界面配置内核功能,其最终是修改了 .config 文件

默认配置只能保证内核拥有最基本的功能,我们需要根据自己的实际需求对内核做进一步的配置。

需保证已安装 libncurses5-dev 依赖,并且终端窗口不能太小,否则会报错。

<>有三种状态:

  • <*>:内核中该功能被选中,相关代码会被编译进内核

  • <>:内核中该功能不被选中,相关代码不会被编译进内核

  • <M>:内核中该功能被选为模块(被编译为独立的模块)

[]有两种状态:

  • [*]:内核中该功能被选中,相关代码会被编译进内核

  • []:内核中该功能不被选中,相关代码不会被编译进内核

键盘操作:

  • Y、N、M:Y选择,N取消选择,M指定为模块

  • 空格:切换 Y、N、M 几种状态

  • ESC:返回

  • Enter:进入

  • /:搜索

  • ?:帮助信息

设备树移植

通过选择官方评估板的

设备树修改

CPU 相关

(1)时钟频率

正常最高 528MHz,可超频792,但不建议。

乱七八糟的。

内核配置:

CPU Power Management

-> CPU Frequency scaling

-> Default CPUFreq governor

选择,维持最大频率。

开发板上芯片型号为 MCIMX6Y2CVM08AB ,最高频率为800MHz,所以跑696MHz没问题,792的话,不知道它的电压。

arch/arm/boot/dts/imx6ull.dtsi

这个节点用于

Linux 的 cpufreq 框架会用这张表来做 DVFS(动态电压频率调整),在切换 CPU 频率时同步调节核心电压。

operating-points = <
				/* kHz	uV */
				696000	1275000
				528000	1175000
				396000	1025000
				198000	950000
			>;

这是NXP自定义的属性

			fsl,soc-operating-points = <
				/* KHz	uV */
				696000  1275000
				528000	1175000
				396000	1175000
				198000	1175000
			>;

CPU 调频策略:

CONFIG_CPU_FREQ_GOV_

(2)

板载硬件资源

(1)EMMC

原来是 4 线模式的,而开发板上的是 8 线的。

打开设备树,将:

&usdhc2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_usdhc2>;
    non-removable;
    status = "okay";
};

改为:

&usdhc2 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc2_8bit>;
    pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
    bus-width = <8>;
    non-removable;
    no-1-8-v;
    status = "okay";
};

(2)网卡

开发板 PHY 芯片为 SR8201F

第一步就是修改引脚

1、

		pinctrl_spi4: spi4grp {
                        fsl,pins = <
                                MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
                                MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
                                MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x70a1
                                MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x80000000
                        >;
                };

SPI4占用了引脚,把它删掉:

		pinctrl_spi4: spi4grp {
                        fsl,pins = <
                                MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
                                MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
                        >;
                };

2、

	spi4 {
		compatible = "spi-gpio";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_spi4>;
		pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
		status = "okay";
		gpio-sck = <&gpio5 11 0>;
		gpio-mosi = <&gpio5 10 0>;
		cs-gpios = <&gpio5 7 0>;
		num-chipselects = <1>;
		#address-cells = <1>;
		#size-cells = <0>;

改为:

给它注释或删掉

	spi4 {
		compatible = "spi-gpio";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_spi4>;
		/* pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; */
		status = "okay";
		gpio-sck = <&gpio5 11 0>;
		gpio-mosi = <&gpio5 10 0>;
		/* cs-gpios = <&gpio5 7 0>; */
		num-chipselects = <1>;
		#address-cells = <1>;
		#size-cells = <0>;

这里为了实现以太网的适配,所以先不管SPI4,后面用到SPI4再修改它。

3、

&iomuxc_snvs {
	pinctrl-names = "default_snvs";
        pinctrl-0 = <&pinctrl_hog_2>;
        imx6ul-evk {

/* 添加这个 */
pinctrl_enet1_reset: enet1resetgrp { 
	fsl,pins = < 
		MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0 
	 >; 
 }; 

/* 添加这个 */
pinctrl_enet2_reset: enet2resetgrp { 
	fsl,pins = <
 		MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0 
	>; 
};

第二步修改PHY地址

&fec1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet1>;
	phy-mode = "rmii";
	phy-handle = <&ethphy0>;
	status = "okay";
};

修改:

&fec1 { 
    pinctrl-names = "default"; 
    pinctrl-0 = <&pinctrl_enet1 
             &pinctrl_enet1_reset>; 
    phy-mode = "rmii"; 
    phy-handle = <&ethphy0>; 
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; 
    phy-reset-duration = <200>; 
    status = "okay"; 
};

&fec2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_enet2>;
	phy-mode = "rmii";
	phy-handle = <&ethphy1>;
	status = "okay";

	mdio {
		#address-cells = <1>;
		#size-cells = <0>;

		ethphy0: ethernet-phy@2 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <2>;
		};

		ethphy1: ethernet-phy@1 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <1>;
		};
	};
};

修改:

&fec2 { 
     pinctrl-names = "default"; 
     pinctrl-0 = <&pinctrl_enet2 
                &pinctrl_enet2_reset>; 
     phy-mode = "rmii"; 
     phy-handle = <&ethphy1>; 
     phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; 
     phy-reset-duration = <200>; 
     status = "okay"; 
  
     mdio { 
         #address-cells = <1>; 
         #size-cells = <0>; 
  
         ethphy0: ethernet-phy@2 { 
             compatible = "ethernet-phy-ieee802.3-c22"; 
             smsc,disable-energy-detect; 
             reg = <2>; 
          }; 
   
         ethphy1: ethernet-phy@1 { 
             compatible = "ethernet-phy-ieee802.3-c22"; 
             smsc,disable-energy-detect; 
             reg = <1>; 
         }; 
     }; 
 }; 

第三步修改内核源码

gedit drivers/net/ethernet/freescale/fec_main.c

搜索 static void fec_reset_phy(struct platform_device *pdev)

在函数最后加上一个延时,因为这个芯片手册中写到,复位结束后至少再延时 150ms 才能继续操作 SR8201F。

	msleep(msec);
	gpio_set_value(phy_reset, 1);
	msleep(200); /* 复位结束后至少再延时 150ms才能继续操作SR8201F */
}