Openwrt1806在全志H3上移植(银杏icore5)

会有一股神秘感。 提交于 2020-02-26 03:51:10

写在前边

H3有很多开发板可以参考,主要有nanopi、orangepi等,这些开发板上大部分支持debian的系统,本着学习的目的,想运行一把openwrt。Openwrt18.06已经对全志的很多板子做了支持,这里主要参考了nanopi-m1-plus.

openwrt开发环境配置及原理

  1. 下载openwrt,可以通过github拉取最新代码,网速比较慢也可以下载压缩包后再解压,最新已经有19.07,不过我这里用的是18.06。
git clone https://github.com/openwrt/openwrt.git  (github直接下载)
https://github.com/openwrt/openwrt  (或者从网站下载压缩包)
  1. Linux系统,我用的是虚拟机安装ubuntu18.04LTS,4G内存+100GB硬盘,小了不够用。
  2. 参考openwrt readme应该更新一下源和软件包
/scripts/feeds update -a
./scripts/feeds install -a

有时候会出错,我这里一般是网络问题,速度太不给力,可以直接点击链接,用迅雷一类的工具下载会快一些。还有一种情况不是网络问题,类似依赖一类的问题,Openwrt邮箱列表有人提到再执行一遍这两条命令可解决,中间遇到过一次,果然如此。
4. 如果使用的是openwrt支持的板子,剩下就非常简单,直接配置板子,编译,等待。。。就行

make menuconfig
make
  1. Openwrt初看起来,源码都没有,由一堆脚本和配置文件组成,网上讲解较多,主要关注目录结构,主Makefile流程
https://www.jianshu.com/p/1fe3d27509da

<target>目录包含了openwrt支持的平台相关的代码,重点关注内核补丁,如果需要移植新的平台或者在支持的平台添加新的板子,都需要修改这里,添加补丁。
<package>目录包含了很多openwrt基础包,内部boot文件夹包含了uboot对一些平台的支持,本次移植也要在这里打上uboot的补丁用来支持我们自己的板子。

<dl>目录包含了下载的压缩包

除了这些原有和自带的目录外,我们可以新建一个 <files>目录,这个目录下的内容会在构建RootFS时覆盖原有的文件,一般可放一些配置文件,比如etc/config/network,放一下统一的配置,减少我们手动修改配置的过程。

移植前的准备

所谓移植,也不是从0开始,我们可以选择一个类似的平台,比如本次我们主要参考的有nanopi-m1-plus 和orangepi-plus. 列个表格对比一下重点关注硬件的不同。

配置 icore5 nanopi-m1-plus orangepi-plus
ddr3 1GB 1GB 1GB
sdio0 sd卡 sd卡 sd卡
sdio0-cd PF6 PF6 PF6
sdio1 fpga bcm4329 rtl8189
sdio2 emmc emmc emmc
gmac rgmii phyaddr01 rgmii phyaddr 07 rgmii
USB3 rtl8188 - -
pmic AXP152 - SY8106A

由上可以看到主要的差别时在pmic和wifi上边,pmic负责启动板上外设电源,如ddr、io、core电源等,电源启动必须在系统外设使能前,如必须在ddr使用前给ddr3供电,uboot第二阶段代码已经在ddr上执行,所以必须在spl中使能pmic(i2c接口),并正确配置电源电压。另外就是sdio1, 参考的板卡都是接到了wifi卡上,我们这个接到了fpga上,用来交互信息,暂时忽略;usb wifi也暂时忽略,不影响移植,后续在加。

openwrt 增加新支持设备的方法。

网上说法很多,先看看官方的说法

https://openwrt.org/docs/guide-developer/adding_new_device

嗯~,说的很详细,一步一步添加什么文件,但是看不懂,还是不知道怎么做,怎么添加没告诉我们。再看看网友的说法

https://blog.csdn.net/chenyefei/article/details/77905919

这位网友很不错,附上了3个示例提交,大约知道怎么添加了。 总结一下:

  1. 在 <./target/linux/$(platform)/image/Makefile>内添加新设备影像的配置,针对icore5,就是在cortexa7.mk内添加内容,模仿nanopi添加以下内容,就可以在make menuconfig中看到新板子了
define Device/sun8i-h3-icore5
	DEVICE_TITLE:=icore5
	DEVICE_PACKAGES:=kmod-rtc-sunxi \
		kmod-leds-gpio kmod-ledtrig-heartbeat \
		kmod-brcmfmac brcmfmac-firmware-43430-sdio wpad-mini
	SUPPORTED_DEVICES:=xinda,icore5
	SUNXI_DTS:=sun8i-h3-icore5
endef
TARGET_DEVICES += sun8i-h3-icore5

里边的内容,SUNXI_DTS指定了新的设备树文件。这个内核中还没有,需要添加,添加的方法有直接添加和打补丁两种,都介绍一下。
a. 直接添加
在<./build_dir/target-$(chip)/linux-$(chip)/linux-$(version)> 找到linux源码树,针对本例也就是 ./openwrt-openwrt-18.06/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-sunxi_cortexa7/linux-4.14.160。如果找不到这个路径,就是之前还没编译过,运行 make target/linux/prepare 准备一下源码树,这个操作会将<dl>目录下的linux内核源码压缩包解压到上述路径,并且将<./target/linux/$(platform)/patches-$(version)/>目录内的补丁按照补丁的编号依次打上,如果出错则退出。准备好源码树后,就可以针对icore5,在dts目录下添加自己板子的设备树。直接添加的代码,在运行 make target/linux/clean时会被删除,只建议在测试时使用,测试通过后一定要制作补丁,否则代码丢了就得不偿失。
b. 打补丁添加
由上述步骤可知,编译时,会自动打补丁,也就是我们可以将补丁放到指定目录中,让系统自动打,这样也不会污染源码,更方便后续维护。制作补丁的方法,简单点就是准备好源码树后,进入源码目录,执行quilt new num-new.patch; 然后通过quilt edit 修改代码或者添加代码,最后执行quilt refresh生成补丁,将补丁拷贝至<./target/linux/$(platform)/patches-$(version)/>目录内即可。

  1. 重新make menuconfig 选择icore5板子,编译;失败,看提示,应该时uboot缺失,因为更改了目标,uboot中还没有添加相应的规则。类似的,uboot 在<./package/boot/uboot-sunxi/>目录,发现该目录下也有个patch目录,是的,这个目录跟linux源码patch目录的作用时一样的。首先修改Makefile,添加icore5的配置
define U-Boot/icore5
  BUILD_SUBTARGET:=cortexa7
  NAME:=Icore5
  BUILD_DEVICES:=sun8i-h3-icore5
endef

并在下边的UBOOT_TARGETS中添加icore5, 注意定义的名字应该与 **_defconfig 一致,如上述定义,我们应该在uboot源码树中添加icore5_defconfig; 这样在编译uboot时就会自动执行 make icore5_defconfig.
同样的,我们建议在uboot下打补丁修改代码。

最终验证

在<files>目录添加配置 <etc/config/network> ,当前只有rgmii phy这一路通了,就先配一路, 内容如下:

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd71:468e:86c5::/48'

config interface 'lan'
        option type 'bridge'
        option ifname 'eth0'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '192.168.10.2'

config device 'lan_eth0_dev'
        option name 'eth0'
        option macaddr '0c:ef:af:c3:14:9e'

最终在bin目录下生成了 ext4和squashfs两种类型的镜像,我选择ext4镜像,解压到当前目录,使用dd命令下载到sd卡中,插上sd卡,使用dd命令将镜像烧录在sd卡起始位置。系统跑起来了:

U-Boot SPL 2017.11 (Dec 26 2019 - 13:02:32)
DRAM: 0 MiB
### ERROR ### Please RESET the board ###

U-Boot SPL 2017.11 (Dec 26 2019 - 13:02:32)
DRAM: 1024 MiB
Trying to boot from MMC1


U-Boot 2017.11 (Dec 26 2019 - 13:02:32 +0000) Allwinner Technology

CPU:   Allwinner H3 (SUN8I 1680)
Model: icore5
DRAM:  1 GiB
MMC:   SUNXI SD/MMC: 0, SUNXI SD/MMC: 1
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
starting USB...
No controllers found
Hit any key to stop autoboot:  0 
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
reading /boot.scr
377 bytes read in 14 ms (25.4 KiB/s)
## Executing script at 43100000
reading uImage
2518520 bytes read in 134 ms (17.9 MiB/s)
reading dtb
14332 bytes read in 22 ms (635.7 KiB/s)
## Booting kernel from Legacy Image at 42000000 ...
   Image Name:   ARM OpenWrt Linux-4.14.160
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2518456 Bytes = 2.4 MiB
   Load Address: 40008000
   Entry Point:  40008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 43000000
   Booting using the fdt blob at 0x43000000
   Loading Kernel Image ... OK
   Using Device Tree in place at 43000000, end 430067fb

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.14.160 (yhangzzz@yhangzzz-virtual-machine) (gcc version 7.3.0 (OpenWrt GCC 7.3.0 unknown)) #0 SMP PREEMPT Thu Dec 26 13:02:32 2019
[    0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=30c5387d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache

	
	
	...
root@OpenWrt:/# ifconfig
br-lan    Link encap:Ethernet  HWaddr 0C:EF:AF:C3:14:9E  
          inet addr:192.168.10.2  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::eef:afff:fec3:149e/64 Scope:Link
          inet6 addr: fd71:468e:86c5::1/60 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:692 errors:0 dropped:0 overruns:0 frame:0
          TX packets:218 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:97464 (95.1 KiB)  TX bytes:22147 (21.6 KiB)

eth0      Link encap:Ethernet  HWaddr 0C:EF:AF:C3:14:9E  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1130 errors:0 dropped:7 overruns:0 frame:0
          TX packets:403 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:154722 (151.0 KiB)  TX bytes:78851 (77.0 KiB)
          Interrupt:28 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:192 errors:0 dropped:0 overruns:0 frame:0
          TX packets:192 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:13056 (12.7 KiB)  TX bytes:13056 (12.7 KiB)

最后附上,uboot和linux的补丁文件。

uboot补丁文件:
--- /dev/null
+++ b/configs/icore5_defconfig
@@ -0,0 +1,15 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=408
+CONFIG_MMC0_CD_PIN="PF6"
+CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL_TEXT_BASE=0x60
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-icore5"
+CONFIG_SUN8I_EMAC=y
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-icore5.dts
@@ -0,0 +1,44 @@
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "icore5";
+	compatible = "icore5", "allwinner,sun8i-h3";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_8bit_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -331,7 +331,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
 	sun8i-h3-nanopi-m1.dtb \
 	sun8i-h3-nanopi-m1-plus.dtb \
 	sun8i-h3-nanopi-neo.dtb \
-	sun8i-h3-nanopi-neo-air.dtb
+	sun8i-h3-nanopi-neo-air.dtb \
+	sun8i-h3-icore5.dtb
 dtb-$(CONFIG_MACH_SUN8I_R40) += \
 	sun8i-r40-bananapi-m2-ultra.dtb
 dtb-$(CONFIG_MACH_SUN8I_V3S) += \
	
	
linux 补丁文件:
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-icore5.dts
@@ -0,0 +1,63 @@
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+
+/ {
+	model = "icore5";
+	compatible = "xinda,icore5", "allwinner,sun8i-h3";
+
+	aliases {
+		serial0 = &uart0;
+		ethernet0 = &emac;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+	status = "okay";
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_8bit_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+&emac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&emac_rgmii_pins>;
+	phy-handle = <&rgmii_phy>;
+	phy-mode = "rgmii";
+	snps,reset-gpio = <&pio 3 14 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 30000>;
+	status = "okay";
+};
+
+&external_mdio {
+	rgmii_phy: ethernet-phy@1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};

注意: linux补丁文件不全,没有在 dts/Makefile中添加 sun8i-h3-icore5.dtb ,测试时直接再源码树修改了Makefile,有兴趣的同学可以再做一个补丁。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!