一、硬件

原理图

打板焊接

二、系统移植

2.1 安装交叉编译器

①下载交叉编译器 arm-cortexa9-linux-gnueabihf-4.9.3.tar.xz,然后解压编译器:

1
2
3
SHELL
mkdir -p /opt/YuanPi-Plus/toolchain
tar xf arm-cortexa9-linux-gnueabihf-4.9.3.tar.xz -C /opt/FriendlyARM/toolchain/

②将编译器的路径加入到 PATH 中,vi ~/.bashrc,在末尾加入以下内容:

1
2
3
4
SHELL
export PATH=/opt/FriendlyARM/toolchain/4.9.3/bin:$PATH
export GCC_COLORS=auto
# 执行一下~/.bashrc脚本,让设置立即在当前shell窗口中生效,注意"."后面有个空格:. ~/.bashrc

③这个编译器是 64 位的,不能在 32 位的 Linux 系统上运行,安装完成后,验证是否安装成功:

1
2
3
SHELL
arm-linux-gcc -v
# 显示出gcc version 4.9.3 (ctng-1.21.0-229g-FA)即成功了

2.2 编译适配 U-boot

①下载 U-boot 源码,并切换分支:

1
2
SHELL
git clone https://github.com/friendlyarm/u-boot.git -b sunxi-v2017.x --depth 1

②安装 Python 库:

1
2
SHELL
apt-get install swig python-dev python3-dev

③使用 nanopi_h3_defconfig 配置:

1
2
3
4
5
SHELL
# 修改DDR3频率为768M,经过测试我的硬件最大支持这个频率
vim configs/nanopi_h3_defconfig
# 将 CONFIG_DRAM_CLK=408 修改为 CONFIG_DRAM_CLK=768
make nanopi_h3_defconfig ARCH=arm CROSS_COMPILE=arm-linux-

④编译 U-boot:

1
2
3
SHELL
make ARCH=arm CROSS_COMPILE=arm-linux- -j12
# 编译成功后会生成文件u-boot-sunxi-with-spl.bin

⑤更新 SD 上的 U-boot:

1
2
3
4
5
SHELL
dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
sync && eject /dev/sdX
# /dev/sdX替换为实际的TF卡设备文件名。
# sync命令可以确保数据成功写到TF卡中,eject命令用于弹出TF卡。

⑥SD 卡运行系统时,可以先用 scp 命令拷贝 u-boot-sunxi-with-spl.bin 到开发板上,然后用 dd 命令更新 SD 卡上的 U-boot:

1
2
3
4
5
SHELL
scp u-boot-sunxi-with-spl.bin root@192.168.31.134:/root/
dd if=/root/u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8
# root@后面替换成板子上的IP地址,EMMC也可以用此方法
# H3的启动设备的设备节点总是/dev/mmcblk0

⑦成功效果如下:

2.3 编译适配 Linux 内核

①下载 Linux 内核源码,并切换分支:

1
2
SHELL
git clone https://github.com/friendlyarm/linux.git -b sunxi-4.14.y --depth 1

②默认配置先跑起来:

1
2
3
4
5
6
SHELL
apt-get install u-boot-tools
touch .scmversion
make sunxi_defconfig ARCH=arm CROSS_COMPILE=arm-linux-
make zImage dtbs ARCH=arm CROSS_COMPILE=arm-linux-
# 编译完成后会在arch/arm/boot/目录下生成zImage,在arch/arm/boot/dts/目录下生成dtb文件

③更新 SD 上的 zImage 和 dtb 文件:假设 SD 卡的 boot 分区挂载在 /media/SD/boot/

1
2
3
4
5
6
SHELL
cp arch/arm/boot/zImage /media/SD/boot/
cp arch/arm/boot/dts/sun8i-*-nanopi-*.dtb /media/SD/boot/
# 也可以用scp命令通过网络更新:
scp arch/arm/boot/zImage root@192.168.31.134:/boot
scp arch/arm/boot/dts/sun8i-*-nanopi-*.dtb root@192.168.31.134:/boot

④bootargs 与 bootcmd:全志 H3 使用 boot.cmd 生成 boot.scr 来描述配置,boot.cmd:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
SHELL

# Recompile with: mkimage -C none -A arm -T script -d boot.cmd boot.scr CPU=H3
# OS=friendlycore/ubuntu-oled/ubuntu-wifiap/openwrt/debian/debian-nas...

echo "running boot.scr"
setenv fsck.repair yes
setenv ramdisk rootfs.cpio.gz
setenv kernel zImage

setenv env_addr 0x43000000
setenv kernel_addr 0x46000000
setenv ramdisk_addr 0x47000000
setenv dtb_addr 0x48000000

fatload mmc 0 ${kernel_addr} ${kernel}
fatload mmc 0 ${ramdisk_addr} ${ramdisk}
setenv ramdisk_size ${filesize}

fatload mmc 0 ${dtb_addr} sun8i-h3-YuanPi-plus.dtb
fdt addr ${dtb_addr}

# setup MAC address
fdt set ethernet0 local-mac-address ${mac_node}

# setup boot_device
fdt set mmc0 boot_device <1>

setenv fbcon map:1

setenv overlayfs data=/dev/mmcblk0p3
#setenv hdmi_res drm_kms_helper.edid_firmware=HDMI-A-1:edid/1280x720.bin video=HDMI-A-1:1280x720@60

setenv bootargs console=tty1 console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait fsck.repair=${fsck.repair} panic=10 ${extra} fbcon=${fbcon} ${hdmi_res} ${overlayfs}
bootz ${kernel_addr} ${ramdisk_addr}:${ramdisk_size} ${dtb_addr}

boot.cmd –> boot.scr:将 boot.scr 也放入 SD 卡的 /boot 中即可

1
2
SHELL
mkimage -C none -A arm -T script -d boot.cmd boot.scr CPU=H3

2.4 文件系统

①文件系统解压到 SD 卡:

1
2
SHELL
sudo tar -xvf rootfs.tar -C /media/qing/rootfs/

②编译和更新驱动模块:更新 SD 卡上 rootfs 的驱动模块:

1
2
3
SHELL
make modules ARCH=arm CROSS_COMPILE=arm-linux-
make modules_install INSTALL_MOD_PATH=/media/SD/rootfs/ ARCH=arm CROSS_COMPILE=arm-linux-

make modules_install 命令的作用是:

  1. 将编译好的内核模块从内核源代码目录 copy 到 /lib/modules 下。也可自己指定 ko 安装路径,在交叉编译的情况下,需要将 ko 模块安装到 rootfs。也即:INSTALL_MOD_PATH=/media/SD/rootfs/。
  2. 运行 modules_install 的另一个作用是会运行 depmod 去生成 modules.dep 文件,该文件记录了模块之间的依赖关系。这样当 modprobe XXX 的时候就能够把 XXX 所依赖的模块一并加载了。

2.5 挂载 nfs

  1. ubuntu 先安装 nfs 服务:apt-get install nfs-kernel-server rpcbind
  2. 配置相关文件夹为 nfs 文件夹:vi /etc/exports
  3. 在最后一行加上文件夹路径:/home/qing/work/nfs/rootfs_friendlycore-focal_4.14 *(rw,sync,no_root_squash)
  4. 然后重启 ubuntu 服务:/etc/init.d/nfs-kernel-server restart
  5. 被挂载的文件夹最好 :chmod 777 xxx/
  6. 在开发板里面也要安装 nfs 服务:apt-get install nfs-kernel-server rpcbind
  7. 重启开发板的 nfs 服务:/etc/init.d/nfs-kernel-server restart
  8. 挂载:mount -t nfs ubuntu-IP:/home/qing/work/nfs/rootfs_friendlycore-focal_4.14/ /mnt/ -o nolock

参考 OrangePi,以太网要修改 sun8i-h3-YuanPi-plus.dts:因为友善 M1-Plus 用了 RTL8211E,我们是直连的。

三、软件适配

3.1 st7789v 彩屏 (SPI)

3.1.1 修改设备树

①首先复制一份 sun8i-h3-nanopi-m1-plus.dts 重命名为 sun8i-h3-YuanPi-plus.dts,并修改设备树目录下的 Makefile 加上我们的设备树。最后在 sun8i-h3-YuanPi-plus.dts 中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MAKEFILE

&spi0 {
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
cs-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>;

st7789vw: st7789vw@0{
compatible ="sitronix,st7789vw";
reg = <0>;
status = "okay";
spi-max-frequency = <50000000>;
buswidth = <8>;
rotate = <0>;
fps = <60>;
rgb;
spi-cpol;
spi-cpha;
dc-gpios = <&pio 0 0 GPIO_ACTIVE_HIGH>; /* PA0 */
reset-gpios = <&pio 0 1 GPIO_ACTIVE_HIGH>; /* PA1 */
debug = <0x00>;
};
};

②修改 sun8i-h3-nanopi.dtsi,将 spi0 结点下的设备都 disabled:

3.1.2 修改 kernel

①make menuconfig 使能 fbtft 框架,并勾选 fb_st7789vw.c:

1
2
3
4
5
6
7
8
![3.1.2修改kernel1](linux卡片电脑/3.1.2修改kernel1.png)SHELL
Device Drivers --->
[*] Staging drivers --->
<*> Support for small TFT LCD display modules --->
<*> Support sysfs for small TFT LCD display modules
<*> FB driver for the ST7789VW LCD Controller
<*> Generic FB driver for TFT LCD displays
<*> Module to for adding FBTFT devices

②修改 drivers/staging/fbtft/fb_st7789vw.c:

我们的屏幕不需要偏移,将偏移去除:

修改分辨率:

最后修改初始化代码:将 init_display (struct fbtft_par *par) 中初始化代码换成当下屏幕的即可。

3.1.3 修改 bootargs

修改 boot.cmd –> boot.scr,让屏幕作为 console:

1
2
3
SHELL
fatload mmc 0 ${dtb_addr} sun8i-h3-YuanPi-plus.dtb
setenv bootargs console=tty1 console=ttyS0,115200 earlyprintk...

3.1.4 编译烧录找 bug

编译出 zImage、sun8i-h3-YuanPi-plus.dtb、boot.scr,重新烧录后发现屏幕不起作用,但是在启动阶段发现有微弱的闪动,开启找 bug 之旅。

最终发现不用外接上拉电阻,直接将 spi0 配置成上拉模式即可,并且 spi 频率也可以设置为 72M,96M 不行,屏幕大。

3.1.5 音视频播放

①安装 mplayer:

1
2
SHELL
apt-get install mplayer

②安装 alsa 包:

1
2
3
4
5
SHELL
apt-get update
apt-get install libasound2
apt-get install alsa-base
apt-get install alsa-utils

③播放视频:

1
2
SHELL
mplayer -ao alsa -vo fbdev:/dev/fb_st7789vw -x 240 -y 240 -zoom 被动-伍佰.mp4

④alsamixer 可以调节音量,声音太大到了高潮部分功率上不去会卡死。

⑤爱伍佰,做他一半就好……