内核配置
(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=ymake 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 = <ðphy0>;
status = "okay";
};修改:
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
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 = <ðphy1>;
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 = <ðphy1>;
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 */
}