1、移植Linux内核
首先去下载一份Linux源码,然后将它解压编译:
tar xzf linux-4.20.9.tar.gz
cd linux-4.20.9/
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v6_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j96
ls -l arch/arm/boot/zImage arch/arm/boot/dts/imx6ull-14x14-evk.dtb # 编译生成镜像和设备树文件
将编译生成的zImage和imx6ull-14x14-evk.dtb通过tftp下载或者其他方式进行启动,查看现象(mmc中已经烧录过rootfs文件系统了):
[ 3.293373] mmcblk1boot0: mmc1:0001 8GTF4R partition 1 4.00 MiB
[ 3.302758] mmcblk1boot1: mmc1:0001 8GTF4R partition 2 4.00 MiB
[ 3.314072] NET: Registered protocol family 17
[ 3.321206] mmcblk1rpmb: mmc1:0001 8GTF4R partition 3 512 KiB, chardev (244:0)
[ 3.328954] can: controller area network core (rev 20170425 abi 9)
[ 3.335794] NET: Registered protocol family 29
[ 3.349613] can: raw protocol (rev 20170425)
[ 3.354339] can: broadcast manager protocol (rev 20170425 t)
[ 3.362870] can: netlink gateway (rev 20170425) max_hops=1
[ 3.373898] mmcblk1: p1 p2
[ 3.378598] Key type dns_resolver registered
[ 3.387168] cpu cpu0: Linked as a consumer to regulator.2
[ 3.411398] cpu cpu0: Linked as a consumer to regulator.3
[ 3.436852] Registering SWP/SWPB emulation handler
[ 3.448656] Loading compiled-in X.509 certificates
[ 3.553456] imx_thermal tempmon: Industrial CPU temperature grade - max:105C critical:100C passive:95C
[ 3.571483] snvs_rtc 20cc000.snvs:snvs-rtc-lp: setting system clock to 2019-08-14 13:04:25 UTC (1565787865)
[ 3.581967] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 3.598600] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[ 3.606425] VSD_3V3: disabling
[ 3.609999] ALSA device list:
[ 3.613016] No soundcards found.
[ 3.618048] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[ 3.626818] platform regulatory.0: Falling back to syfs fallback for: regulatory.db
[ 3.638888] VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[ 3.646416] Please append a correct "root=" boot option; here are the available partitions:
[ 3.655085] 0100 65536 ram0
[ 3.655091] (driver?)
# 省略 ...
[ 3.742420] (driver?)
[ 3.748727] 010f 65536 ram15
[ 3.748733] (driver?)
[ 3.755000] b300 7634944 mmcblk1
[ 3.755006] driver: mmcblk
[ 3.761925] b301 131072 mmcblk1p1 5ee8f5c0-01
[ 3.761931]
[ 3.768851] b302 7493632 mmcblk1p2 5ee8f5c0-02
[ 3.768855]
[ 3.775707] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 3.784270] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---
根据最后这两句log可以知道内核奔溃,说挂载根文件系统出错了:
[ 3.775707] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 3.784270] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---
而根据以下log可以看到,说明MMC已经能识别出来了:
[ 3.293373] mmcblk1boot0: mmc1:0001 8GTF4R partition 1 4.00 MiB
[ 3.302758] mmcblk1boot1: mmc1:0001 8GTF4R partition 2 4.00 MiB
[ 3.314072] NET: Registered protocol family 17
[ 3.321206] mmcblk1rpmb: mmc1:0001 8GTF4R partition 3 512 KiB, chardev (244:0)
我们MMC设备中已经有文件系统了,但是却提示了以下log:
[ 3.646416] Please append a correct "root=" boot option; here are the available partitions:
说是让我们设置好“root=xxx”来指定文件系统所在设备分区等来传递,先不管之前uboot环境变量是怎样设置来兼容多种启动方式的,我们重新进入u-boot来重新设置一个:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' # 可以不用急着saveenv
tftp 80800000 zImage;tftp 83000000 imx6ull-14x14-evk.dtb;bootz 80800000 - 83000000
tftp下载镜像之后重新启动系统,这时发现能够正常启动了。
2、其他修改
2.1 网卡修改
参考网卡驱动系列文章和Documentation/devicetree/bindings/net/fsl-fec.txt
文档来修改。
对于正点原子的Mini版开发板来说,只外接了一个网口(ENET2):
所以修改dts如下(imx6ull-14x14-evk.dts里面include包含了imx6ul-14x14-evk.dtsi):
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
@@ -98,6 +98,7 @@
};
};
+/*
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
@@ -105,6 +106,7 @@
phy-handle = <ðphy0>;
status = "okay";
};
+*/
&fec2 {
pinctrl-names = "default";
@@ -117,15 +119,17 @@
#address-cells = <1>;
#size-cells = <0>;
+/*
ethphy0: ethernet-phy@2 {
reg = <2>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET_REF>;
clock-names = "rmii-ref";
};
+*/
ethphy1: ethernet-phy@1 {
- reg = <1>;
+ reg = <1>; /* accordinig to hardware, ensure addr is 0x01 */
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET2_REF>;
clock-names = "rmii-ref";
上面修改就是屏蔽fec1(ENET1)和PHY0节点,这时使用新的dtb文件进行启动,就只有一个能使用的ENET2了,之前无法正常使用的ENET1已经被我们屏蔽掉了,防止混淆视线。
此外,对于PHY驱动,一般会有两套驱动,一套是内核的通用驱动(Generic PHY),一套是PHY厂家针对自家芯片的驱动,通用PHY驱动能驱动一部分符合规范的芯片了,如果不能驱动起来,也可以使用厂家提供的特定的驱动,对应的驱动文件一般放在drivers/net/phy
目录下,根据该目录下的Makefile指示的CONFIG_XXX_PHY
去make menuconfig
菜单里选中即可(本版本默认已配置了SMSC的PHY驱动)。
注意!Linux-4.20.9版本的内核里面默认没有配置PHY芯片的复位引脚,这个属性在上面文档中说是可选的,如果网络出现问题的话可以添加复位引脚的使用。
2.2 emmc
其实emmc并没有什么需要修改的,不过数据的位宽倒是可以调整一下的,默认填写的是4bit,硬件原理图:
而开发板是8bit数据带宽,所以,修改dts中的对应节点:
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
no-1-8-v;
keep-power-in-suspend;
wakeup-source;
bus-width = <8>; /* overlay it with 8 bit */
status = "okay";
};
修改后重启系统查看信息:
root@IMX6ULL:~# cat /sys/kernel/debug/mmc1/ios
clock: 52000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 3 (8 bits) /* 修改后变成8bit位宽 */
timing spec: 8 (mmc DDR52)
signal voltage: 0 (3.30 V)
driver type: 0 (driver type B)
root@IMX6ULL:~#
此外,还可以算下容量:
root@IMX6ULL:~# cat /sys/block/mmcblk1/size
15269888
root@IMX6ULL:~#
容量 = 15269888 block * 512Bytes/block = 7,818,182,656 Bytes = 7,634,944 KBytes = 7,456 MBytes = 7.28125 GBytes
这就对应于系统启动时的打印:
[ 3.132548] mmcblk1: mmc1:0001 8GTF4R 7.28 GiB
2.3 SD卡测试
插上SD卡,查看打印:
[ 30.547634] mmc0: Tuning failed, falling back to fixed sampling clock
[ 30.574852] mmc0: new ultra high speed SDR104 SDHC card at address 59b4
[ 30.612676] mmcblk0: mmc0:59b4 NCard 14.9 GiB
[ 30.712609] mmc0: Tuning failed, falling back to fixed sampling clock
[ 30.850448] mmc0: Tuning failed, falling back to fixed sampling clock
[ 30.862775] mmcblk0: p1
[ 30.940431] mmc0: Tuning failed, falling back to fixed sampling clock
[ 30.992448] mmc0: Tuning failed, falling back to fixed sampling clock
...
很明显,sd卡用不了。参考公版修改usdhc1节点:
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -856,6 +856,10 @@
<&clks IMX6UL_CLK_USDHC1>,
<&clks IMX6UL_CLK_USDHC1>;
clock-names = "ipg", "ahb", "per";
+ assigned-clocks = <&clks IMX6UL_CLK_USDHC1_SEL>, <&clks IMX6UL_CLK_USDHC1>;
+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+ assigned-clock-rates = <0>, <132000000>;
+ fsl,tuning-step= <2>;
bus-width = <4>;
status = "disabled";
修改后下载重新启动,正常使用:
root@IMX6ULL:~# [ 80.197467] mmc0: host does not support reading read-only switch, assuming write-enable
[ 80.256790] mmc0: new ultra high speed SDR104 SDHC card at address 59b4
[ 80.274353] mmcblk0: mmc0:59b4 NCard 14.9 GiB
[ 80.301858] mmcblk0: p1
[ 81.341775] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
root@IMX6ULL:~# mount -t vfat /dev/mmcblk0p1 /mnt/SDCard/
root@IMX6ULL:~#
root@IMX6ULL:~# ls -l /mnt/SDCard/
total 32
drwxrwx--- 2 root disk 32768 Mar 19 2021 'System Volume Information'
-rwxrwx--- 1 root disk 0 Mar 19 2021 hello.txt
root@IMX6ULL:~#
root@IMX6ULL:~# umount /dev/mmcblk0p1
root@IMX6ULL:~#
root@IMX6ULL:~# ls -l /mnt/SDCard/
total 0
root@IMX6ULL:~#
2.4 U盘测试
root@IMX6ULL:/# [ 878.667578] usb 1-1: new high-speed USB device number 4 using ci_hdrc
[ 878.913337] usb-storage 1-1:1.0: USB Mass Storage device detected
[ 878.921623] scsi host0: usb-storage 1-1:1.0
[ 879.942648] scsi 0:0:0:0: Direct-Access Kingston DataTraveler 3.0 PQ: 0 ANSI: 6
[ 879.969810] sd 0:0:0:0: [sda] 60437492 512-byte logical blocks: (30.9 GB/28.8 GiB)
[ 879.993424] sd 0:0:0:0: [sda] Write Protect is off
[ 879.999646] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[ 880.027679] sda: sda1
[ 880.051462] sd 0:0:0:0: [sda] Attached SCSI removable disk
[ 880.915533] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
root@IMX6ULL:/#
root@IMX6ULL:/# mount /dev/sda1 /mnt/
root@IMX6ULL:/# ls -l /mnt/
total 16
drwxrwx--- 2 root disk 16384 May 29 2021 'System Volume Information'
-rwxrwx--- 1 root disk 0 May 29 2021 test.txt
root@IMX6ULL:/#
root@IMX6ULL:/# umount /dev/sda1
root@IMX6ULL:/# ls -l /mnt/
total 0
root@IMX6ULL:/#
2.5 LCD
看了下linux-4.20.9内核,imx6ull的LCD不是使用传统的framebuffer框架了,根据 Documentation/devicetree/bindings/display/mxsfb.txt
说明,使用了新的DRM框架,它的节点如下:
lcdif: lcdif@21c8000 {
compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
reg = <0x021c8000 0x4000>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
<&clks IMX6UL_CLK_LCDIF_APB>,
<&clks IMX6UL_CLK_DUMMY>;
clock-names = "pix", "axi", "disp_axi";
status = "disabled";
};
&lcdif {
assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
status = "okay";
port {
display_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};
panel {
compatible = "lg,lg4573";
backlight = <&backlight_display>;
port {
panel_in: endpoint {
remote-endpoint = <&display_out>;
};
};
};
默认情况下背光能亮,但屏幕显示只有一小部分。找了好久不知道正点原子4.3英寸800x480的LCD采用的哪个IC,后来通过grep -rn "lg,lg4573" drivers/
找到公版使用的驱动在drivers/gpu/drm/panel/
目录下,继续grep -rn "compatible" drivers/gpu/drm/panel/
找了下都支持哪些,然后就试了几个,发现最接近能使用的就只有sii,43wvf1g
属性,这方面的驱动后面再看看如何工作的吧,暂时用着先。(对比了下硬件原理图和dts中LCD的pinctrl配置是一样的)
2.6 其他
其他驱动估计还是要改的,目前先到这里,有需要再补充。