闲鱼便宜板子TN3399折腾全攻略

前一段某鱼有人卖便宜板子TN3399 V3

部分图片来自恩山

部分配置如下

部件名称 芯片型号 备注说明
CPU rk3399 Dual-core Cortex-A72 up to 1.8GHz;Quad-core Cortex-A53 up to 1.4GHz;Mali-T864 GPU
RAM K4B8G16 Dual-channel DDR3 1GB;板载 4 颗
Flash SanDisk SDINBDG4-16G eMMC 5.1
PMU RK808D
Ethernet RTL8211E 10/100/1000 Base-T
WIFI+BT AP6255 WIFI IEEE802.11 a/b/g/n/ac;BT4.2
SATA 3.0 JMS578
USB 2.0 FE1.1s 板载 TYPE A 插座 x 2;接插件插座x5
USB 3.0 VL817-Q7 板载 TYPE A 插座 x 2
UART SP3232EEN
HDMI 2.0+LVDS 358775G + ALC5640
Audio PA NS4258 5W x 2

同配置的开发板都要800+,这个这么多外设只要200,但是没资料,自带安卓系统

于是自己搞来玩玩,给做了个Debian固件

几个坑点

准备一台linux计算机,跑编译和刷固件需要

准备一个支持1500000波特率的串口,辣鸡pl2303啥的弄不成,去买个cp2102

准备工具链

wget -c https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchains/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
apt install -y build-essential libncurses5-dev git make

gcc放到./toolchain 然后改一下PATH

#!/bin/sh
export PATH=/home/debian/tn3399/toolchain/bin:$PATH
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

编译U-Boot

查一下rockchip官网

我们选择左边那一条启动路径(不知道为啥右边那条会跑飞)

首先clone两个仓库

git clone https://github.com/rockchip-linux/u-boot.git
git clone https://github.com/rockchip-linux/rkbin.git

编译rockchip维护的u-boot

# 不使用项目指定工具链
sed -i 's@TOOLCHAIN_ARM32=.*@TOOLCHAIN_ARM32=/@g' ./make.sh
sed -i 's@TOOLCHAIN_ARM64=.*@TOOLCHAIN_ARM64=/@g' ./make.sh
sed -i 's@${absolute_path}/bin/@@g' ./make.sh

# 编译修改过的 u-boot
./make.sh evb-rk3399

得到uboot.img和rk3399_loader_v1.24.126.bin,等下需要

制作idbloader.img

# 找到rkbin带的ddr初始化文件,用u-boot里面的mkimage制作idbloader.img
tools/mkimage -n rk3399 -T rksd -d ../rkbin/bin/rk33/rk3399_ddr_800MHz_v1.24.bin idbloader.img
# 再往后写miniloader
cat ../rkbin/bin/rk33/rk3399_miniloader_v1.26.bin >> idbloader.img

得到idbloader.img

了解一下怎么刷emmc

rk家的rom code支持usb启动,不怕弄成砖头

首先上电,插上microusb,安装rkdeveloptool

然后短接这两个脚,保持短接,按reset

这步是把emmc某个数据脚接地,让rom code找不到emmc,进入usb启动

然后用rkdeveloptool初始化ddr

root@a6:/hdd/samba/tn3399/naivekun# rkdeveloptool ld
not found any devices!
# 短接复位后
root@a6:/hdd/samba/tn3399/naivekun# rkdeveloptool ld
DevNo=1	Vid=0x2207,Pid=0x330c,LocationID=302	Maskrom
root@a6:/hdd/samba/tn3399/naivekun# rkdeveloptool db /tmp/rk3399_loader_v1.24.126.bin 
Downloading bootloader succeeded.
root@a6:/hdd/samba/tn3399/naivekun# 

然后rkdeveloptool wl <偏移> <文件名>就可以刷文件了

刷入idbloader和uboot和trust

刷完之后reset,不出意外串口就可以正常输出,进u-boot了

编译kernel

首先把linux主线kernel拉下来

改dts

linux/arch/arm64/boot/dts/rockchip/rk3399-rock960.dts内容改成以下东西

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2018 Linaro Ltd.
 */

/dts-v1/;
#include "rk3399-rock960.dtsi"

/ {
	model = "TN3399 V3";
	compatible = "vamrs,rock960", "rockchip,rk3399";

	chosen {
		stdout-path = "serial2:1500000n8";
	};

	clkin_gmac: external-gmac-clock {
		compatible = "fixed-clock";
		clock-frequency = <125000000>;
		clock-output-names = "clkin_gmac";
		#clock-cells = <0>;
	};

	leds {
		compatible = "gpio-leds";
		pinctrl-names = "default";
		pinctrl-0 = <&user_led1>, <&user_led2>, <&user_led3>,
			    <&user_led4>, <&wlan_led>, <&bt_led>;

		user_led1 {
			label = "green:user1";
			gpios = <&gpio4 RK_PC2 0>;
			linux,default-trigger = "heartbeat";
		};

		user_led2 {
			label = "green:user2";
			gpios = <&gpio4 RK_PC6 0>;
			linux,default-trigger = "mmc0";
		};

		user_led3 {
			label = "green:user3";
			gpios = <&gpio4 RK_PD0 0>;
			linux,default-trigger = "mmc1";
		};

		user_led4 {
			label = "green:user4";
			gpios = <&gpio4 RK_PD4 0>;
			panic-indicator;
			linux,default-trigger = "none";
		};

		wlan_active_led {
			label = "yellow:wlan";
			gpios = <&gpio4 RK_PD5 0>;
			linux,default-trigger = "phy0tx";
			default-state = "off";
		};

		bt_active_led {
			label = "blue:bt";
			gpios = <&gpio4 RK_PD6 0>;
			linux,default-trigger = "hci0-power";
			default-state = "off";
		};
	};

};


&gmac {
	assigned-clocks = <&cru SCLK_RMII_SRC>;
	assigned-clock-parents = <&clkin_gmac>;
	clock_in_out = "input";
	phy-supply = <&vcc3v3_sys>;
	phy-mode = "rgmii";
	pinctrl-names = "default";
	pinctrl-0 = <&rgmii_pins>;
	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	snps,reset-delays-us = <0 10000 50000>;
	tx_delay = <0x28>;
	rx_delay = <0x11>;
	status = "okay";
};

&pcie0 {
	ep-gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
};

&pinctrl {
	gmac {
		rgmii_sleep_pins: rgmii-sleep-pins {
			rockchip,pins =
				<1 RK_PB2 RK_FUNC_GPIO &pcfg_output_low>;
		};
	};

	leds {
		user_led1: user_led1 {
			rockchip,pins =
				<4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		user_led2: user_led2 {
			rockchip,pins =
				<4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		user_led3: user_led3 {
			rockchip,pins =
				<4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		user_led4: user_led4 {
			rockchip,pins =
				<4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		wlan_led: wlan_led {
			rockchip,pins =
				<4 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		bt_led: bt_led {
			rockchip,pins =
				<4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};

	pcie {
		pcie_drv: pcie-drv {
			rockchip,pins =
				<2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
			};
	};

	usb2 {
		host_vbus_drv: host-vbus-drv {
			rockchip,pins =
				<4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};
};

/*
&spi0 { */
	/* On Low speed expansion (LS-SPI0) */
	/* status = "okay";
};

&spi4 { */
	/* On High speed expansion (HS-SPI1) */
/*	status = "okay";
}; */


&thermal_zones {
	cpu_thermal: cpu {
		polling-delay-passive = <100>;
		polling-delay = <1000>;
		thermal-sensors = <&tsadc 0>;
		sustainable-power = <1550>;

		trips {
			cpu_alert0: cpu_alert0 {
				    temperature = <65000>;
				    hysteresis = <2000>;
				    type = "passive";
			};

			cpu_alert1: cpu_alert1 {
				    temperature = <75000>;
				    hysteresis = <2000>;
				    type = "passive";
			};

			cpu_crit: cpu_crit {
				  temperature = <95000>;
				  hysteresis = <2000>;
				  type = "critical";
			};
		};

		cooling-maps {
			     map0 {

			     trip = <&cpu_alert1>;
			     cooling-device =
					<&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
					<&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
			};
		};
	};
};

&usbdrd_dwc3_0 {
	dr_mode = "otg";
};

&usbdrd_dwc3_1 {
	dr_mode = "host";
};

&vcc3v3_pcie {
	gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>;
};

&vcc5v0_host {
	gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
};

然后还要把linux/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi里面改一个网卡型号,在522行

把网卡改成bcm43455-fmac

这个不改后面跑起来会莫名其妙占cpu

编译kernel

touch .scmversion # 这个是为了防止编译出来版本号后面带-xxxxx奇怪的东西,给module_install带来麻烦
make defconfig
make -j24

然后等一会,kernel就编译出来了

找到arch/arm64/boot/Image就是内核二进制文件

然后找到arch/arm64/boot/dts/rockchip/rk3399-rock960.dtb,这个是dtb。这两个文件留着,接下来要用

制作rootfs

我讨厌Ubuntu

下面开始制作debian镜像

bootstrap

首先apt装一下qemu-aarch64-static

debootstrap --arch=arm64 --foreign buster debianFS https://mirrors.ustc.edu.cn/debian/   # 拉个文件系统
cp /usr/bin/qemu-aarch64-static debianFS/usr/bin/

然后准备一下mount.sh

#!/bin/bash
# 


function mnt() {
    echo "MOUNTING"
    sudo mount -t proc /proc ${2}proc
    sudo mount -t sysfs /sys ${2}sys
    sudo mount -o bind /dev ${2}dev
    sudo mount -o bind /dev/pts ${2}dev/pts		
    sudo chroot ${2}
}

function umnt() {
    echo "UNMOUNTING"
    sudo umount ${2}proc
    sudo umount ${2}sys
    sudo umount ${2}dev/pts
    sudo umount ${2}dev

}


if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
    mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
    umnt $1 $2
else
    echo ""
    echo "Either 1'st, 2'nd or both parameters were missing"
    echo ""
    echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
    echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
    echo ""
    echo "For example: ch-mount -m /media/sdcard/"
    echo ""
    echo 1st parameter : ${1}
    echo 2nd parameter : ${2}
fi

之后挂载并chroot进去

./mount.sh -m ./debianFS/

然后开始配文件系统,时区,语言,源,必要的包啥的,还要改一下getty,具体看我的history

debootstrap/debootstrap --second-stage
apt install apt-transport-https
vi /etc/apt/sources.list
vi /etc/apt/sources.list
apt update
useradd -G sudo,adm -m -s /bin/bash naivekun
passwd naivekun
vi /etc/sudoers
apt install sud
apt install sudo git tmux vim
useradd -G sudo -m -s /bin/bash
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
apt install locales
dpkg-reconfigure locales
ln -s /lib/systemd/system/serial-getty\@.service /etc/systemd/system/getty.target.wants/serial-getty@ttyS2.service
apt install alsa-utils libasound2-dev
apt install ssh ifupdown net-tools udev wget curl
vi /etc/hostname
vi /etc/hosts

配完记得./mount.sh -u xxx

安装kernel modules和headers

转到linux目录

make modules_install INSTALL_MOD_PATH=../debian_fs/debianFS/
make headers_install INSTALL_HDR_PATH=../debian_fs/debianFS/

打包kernel和rootfs

首先偷个脚本,来自https://github.com/lanseyujie/tn3399_v3/

找到那个仓库的build-image.sh

开始打包

按照原文说明,建好文件目录

打包boot.img

打包rootfs.img

烧进去

还是日常操作,初始化ddr,然后写镜像

Done!

没什么意外,板子复位就直接跑进系统了,这个rk3399真的牛逼,爆快,4s进登录框

开机之后wifi会爆炸,因为缺个文件

如图,把https://github.com/RPi-Distro/firmware-nonfree/blob/master/brcm/brcmfmac43455-sdio.txt下载到/lib/firmware/brcm

当然之前做文件系统的时候放进去最好

懒得写咋卡刷了,这么牛逼的emmc用啥辣鸡sd卡

测一下wifi和网卡稳的一批,cpu也没有异常占用,dmesg也没有奇奇怪怪的报错

后续焊上那俩usb3.0,画了个亚克力外壳,淘宝定做18包邮,前面板接口完美

sata电源,天线孔,sata硬盘位,风扇,散热孔都有,完美

sata盘既可以装里面也可以装外面

需要固件或者图纸的给我发邮件,邮箱见简介 图纸已公开:传送门

参考链接 && 致谢

  1. https://www.right.com.cn/forum/thread-4033942-1-1.html dts修改思路和网卡占cpu问题解决来自这个帖子
  2. https://github.com/lanseyujie/tn3399_v3 总体过程参考
  3. http://opensource.rock-chips.com/wiki_Boot_option rockchip官方wiki
  4. http://opensource.rock-chips.com/wiki_U-Boot 同上
  5. https://blog.csdn.net/cry1994/article/details/100518871 另一个参考链接

todo

板子右上角那个led接口是否通电是由gpio控制的,准备移植进dtb

外壳实际厚度2.7mm,插口做的3.0,感觉。。有点松

补焊的两个usb3,靠近cpu那个usb3用不了,好像它的usb2是连到cpu的,或许是个otg,没有正确配置