You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

383 lines
14 KiB

\chapter{代码编译}
\section{开发环境搭建}
主机系统推荐使用 Ubuntu >= 20.04 的版本。
\subsection{编译器和下载工具}
从公司共享目录获取 RK3588 的编译工具:
\texttt {
\footnotesize
\textbackslash{}\textbackslash{}192.168.1.202\textbackslash{}常用工具\textbackslash{}2.开发工具\textbackslash{}RK3588\textbackslash{}gcc-arm-9.2-2019.12-x86\_64-aarch64-none-linux-gnu.tar.xz。
} \\
下载后用放在 linux 系统下,用命令解压:
\shellcmd{bash}{tar xpvf gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz}
下载 USB 的烧写程序和驱动程序文件:\\
\texttt {
\small
\textbackslash{}\textbackslash{}192.168.1.202\textbackslash{}常用工具\textbackslash{}2.开发工具\textbackslash{}RK3588\textbackslash{}RkDevTool。
} \\
其目录结构如下:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (tree) at (0,0) {
\begin{tcolorbox}[colframe=gray!20]
\begin{small}
\begin{Verbatim}
├── RKDevTool_Release_v2.96
│   ├── Language
│   ├── Log
│   └── bin
├── driver
└── rockdev
\end{Verbatim}
\end{small}
\end{tcolorbox}
};
\end{tikzpicture}
\caption{RkDevTool 目录}
\end{figure}
用于烧写的程序文件放在 rockdev 目录下面。双击\\
\verb+RKDevTool_Release_v2.96\RKDevTool.exe+
程序,连接 USB 线来更新固件程序,运行界面如图 \ref{fig:rkdevtool} 所示。
\subsection{U-Boot 代码下载}
U-Boot 源代码在这里:\\
\texttt {
\small
http://192.168.1.202:8888/rk3588/uboot.git
} \\
用 git 命令下载:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{bash}
git clone http://192.168.1.202:8888/rk3588/uboot.git
\end{minted}
\subsection{Kernel 代码下载}
kernel 源代码在这里:\\
\texttt {
\small
http://192.168.1.202:8888/rk3588/kernel.git
} \\
用 git 命令下载:
\shellcmd{bash}{git clone http://192.168.1.202:8888/rk3588/kernel.git}
准备好文件以后,目录结构如下图所示:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (tree) at (0,0) {
\begin{tcolorbox}[colframe=gray!20]
\begin{small}
\begin{Verbatim}
$ tree -d rk3588 -L 1
rk3588
├── gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu
├── kernel
└── uboot
\end{Verbatim}
\end{small}
\end{tcolorbox}
};
\end{tikzpicture}
\caption{代码目录结构}
\end{figure}
\section{U-Boot}
\subsection{U-Boot 编译}
\noindent 用下面的命令编译 U-Boot :
\shellcmd{bash}{./make.sh sytc}
编译生成的文件是 uboot.img。
\subsection{U-Boot 版本号}
U-Boot 在启动的时候会打印我们内部的版本号,例如:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (image) at (0,0) {
\begin{tcolorbox}[colframe=gray!20, coltitle=blue!80]
\scriptsize
\begin{Verbatim}
ON=0x00, OFF=0x00
vdd_gpu_s0 750000 uV
vdd_cpu_lit_s0 750000 uV
vdd_log_s0 750000 uV
vdd_vdenc_s0 init 750000 uV
vdd_ddr_s0 850000 uV
SYTC boot version: 1.0
get vp0 plane mask:0x5, primary id:2, cursor_plane:-1, from dts
get vp1 plane mask:0xa, primary id:3, cursor_plane:-1, from dts
get vp2 plane mask:0x140, primary id:8, cursor_plane:-1, from dts
get vp3 plane mask:0x280, primary id:9, cursor_plane:-1, from dts
Could not find baseparameter partition
Model: Rockchip RK3588 SYTC Board
\end{Verbatim}
\end{tcolorbox}
};
\begin{scope}[
x={($0.1*(image.south east)$)},
y={($0.1*(image.north west)$)}
]
% grid for debugging
% \draw [lightgray, step=1] (image.south west) grid (image.north east);
% \foreach \x in {0, 1, ..., 10} {\node [below] at (\x, 0) {\x};}
% \foreach \y in {0, 1, ..., 10} {\node [left] at (0, \y) {\y};}
\draw [red,thick, rounded corners] (0.3, 4.7) rectangle (3.3, 5.4);
\end{scope}
\end{tikzpicture}
\caption{U-Boot 内部版本号}
\end{figure}
给客户发布新版本的时候,需要修改版本号。这里有主、次版本号两个域。版本号的修改规则是:用于新的项目从 1.0 开始。主版本号与硬件的一致,硬件有升级,增加主版本号。
软件的修改升级,需要增加次版本号。
U-Boot 的版本号在 \verb+include/configs/sytc_rk3588.h+ 里修改:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (image) at (0,0) {
\begin{tcolorbox}[title={include/configs/sytc\_rk3588.h:},colframe=gray!20, coltitle=blue!80]
\footnotesize
\begin{Verbatim}
#define SYTC_BOOT_MAJOR_VERSION 1
#define SYTC_BOOT_MINOR_VERSION 0
\end{Verbatim}
\end{tcolorbox}
};
\end{tikzpicture}
\caption{修改 U-Boot 版本号}
\end{figure}
\section{Kernel}
\subsection{kernel 编译}
\noindent kernel 编译:
\shellcmd{bash}{./make.sh}
编译生成的文件是当前目录下的 boot.img。
\subsection{kernel 版本号}
为了内部版本管控,在内核代码的 \verb+init/main.c+ 中增加了内部版本号的打印:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (image) at (0,0) {
\begin{tcolorbox}[title={\small init/main.c:start\_kernel()},colframe=gray!20, coltitle=blue!80]
\scriptsize
\begin{Verbatim}
pr_notice("%s", linux_banner);
pr_notice("SYTC Linux version: %d.%d (%s)",
CONFIG_SYTC_MAJOR_VERSION, CONFIG_SYTC_MINOR_VERSION, UTS_VERSION);
early_security_init();
setup_arch(&command_line);
\end{Verbatim}
\end{tcolorbox}
};
\begin{scope}[
x={($0.1*(image.south east)$)},
y={($0.1*(image.north west)$)}
]
% grid for debugging
%\draw [lightgray, step=1] (image.south west) grid (image.north east);
%\foreach \x in {0, 1, ..., 10} {\node [below] at (\x, 0) {\x};}
%\foreach \y in {0, 1, ..., 10} {\node [left] at (0, \y) {\y};}
\draw [red,thick, rounded corners] (0.2, 3.3) rectangle (9.1, 5.70);
\end{scope}
\end{tikzpicture}
\caption{Kernel 版本号}
\end{figure}
在启动过程中的打印中有内部版本号,例如:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (image) at (0,0) {
\begin{tcolorbox}[colframe=gray!20, coltitle=blue!80]
\scriptsize
\begin{Verbatim}
[ 0.947325] Booting Linux on physical CPU 0x0000000000 [0x412fd050]
[ 0.947345] Linux version 5.10.110 (user@DESKTOP-8539AN4)
[ 0.947359] SYTC Linux version: 1.0 (#14 SMP Mon Mar 18 15:58:58 CST 2024)
[ 0.954751] Machine model: Rockchip RK3588 SYTC Board
[ 0.954811] earlycon: uart8250 at MMIO32 0x00000000feb50000 (options '')
[ 1.008442] printk: bootconsole [uart8250] enabled
\end{Verbatim}
\end{tcolorbox}
};
\begin{scope}[
x={($0.1*(image.south east)$)},
y={($0.1*(image.north west)$)}
]
% grid for debugging
% \draw [lightgray, step=1] (image.south west) grid (image.north east);
% \foreach \x in {0, 1, ..., 10} {\node [below] at (\x, 0) {\x};}
% \foreach \y in {0, 1, ..., 10} {\node [left] at (0, \y) {\y};}
\draw [red,thick, rounded corners] (0.3, 5.0) rectangle (9.8, 6.3);
\end{scope}
\end{tikzpicture}
\caption{Kernel 版本号示例}
\end{figure}
版本号的修改规则与 U-Boot 的一样。需要修改的地方在文件\\
{\small\verb+arch/arm64/configs/rk3588_sytc_defconfig+}中:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (image) at (0,0) {
\begin{tcolorbox}[title={\small arch/arm64/configs/rk3588\_sytc\_defconfig:},colframe=gray!20, coltitle=blue!80]
\scriptsize
\begin{Verbatim}
CONFIG_SYTC_MAJOR_VERSION=1
CONFIG_SYTC_MINOR_VERSION=0
\end{Verbatim}
\end{tcolorbox}
};
\end{tikzpicture}
\caption{修改 Kernel 版本号}
\end{figure}
\section{设备树文件}
U-Boot 和 Kernel 使用的都是 boot.img 里面的 DTB 文件。设备树文件从这个文件:
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node [anchor=south west, inner sep=0] (image) at (0,0) {
\begin{tcolorbox}[title={\small{}arch/arm64/boot/dts/rockchip/rk3588-sytc.dts:},colframe=gray!20, coltitle=blue!80]
\scriptsize
\begin{Verbatim}
/dts-v1/;
/* #include "rk3588-sytc-hrgz.dtsi" */
#include "rk3588-sytc-evb.dtsi"
/ {
model = "Rockchip RK3588 SYTC Board";
compatible = "rockchip,rk3588-sytc", "rockchip,rk3588";
chosen: chosen {
bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0
irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=614e0000-0000 rw rootwait";
};
};
&fiq_debugger {
rockchip,baudrate = <115200>;
};
\end{Verbatim}
\end{tcolorbox}
};
\end{tikzpicture}
\caption{dts 入口文件}
\end{figure}
开始查看,它会通过 \verb+include+ 指令引入别的文件。新项目开始的时候建议从
\verb+rk3588-sytc-evb.dtsi+ 复制并重命名一个新文件,然后 \verb+include+ 它。 如注释掉的 \verb+rk3588-sytc-hrgz.dtsi+ 一样。
\section{rootfs.img 修改}
rootfs.img 是一个 ext4 文件系统格式的文件,可以通过 mount 的方式挂载到系统下进行修改。由于这个文件给的剩余空间比较小,
直接修改的方式可能会报失败。这里的示例是将文件先复制出来,按需修改好文件系统以后再重新做一个 ext4 的打包文件。
%\subsection{rootfs.img 修改}
可以按下面的步骤进行修改:
\begin{enumerate}[(1),nosep]
\item 将 rootfs.img 挂载到系统下,例如:
\shellcmd{bash}{sudo mount -o loop rootfs.img /media}
\item 将 rootfs 的内容复制出来:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{bash}
sudo mkdir rootfs
sudo cp -a /media/* rootfs/
sudo umount /media
\end{minted}
\item chroot 到 rootfs 的文件系统:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{pwsh}
sudo mount -o bind /proc rootfs/proc
sudo mount -o bind /dev rootfs/dev
sudo mount -o bind /sys rootfs/sys
sudo chroot rootfs /bin/bash
\end{minted}
\item 安装新的软件包,例如:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{bash}
apt-get update
apt-get install tcpdump
\end{minted}
\item 安装所需软件以后,清理临时文件并退出 chroot 环境:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{bash}
apt-get clean
exit
\end{minted}
\item 卸载 bind 的文件系统:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{bash}
sudo umount rootfs/proc
sudo umount rootfs/dev
sudo umount rootfs/sys
\end{minted}
\item 重新打包文件系统:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{bash}
IMAGE_SIZE_MB=$(( $(sudo du -sh -m rootfs | cut -f1) + 300 ))
dd if=/dev/zero of=rootfs.img bs=1M count=0 seek=${IMAGE_SIZE_MB}
sudo mkfs.ext4 -d rootfs rootfs.img
\end{minted}
\end{enumerate}
文件系统里面的 root 用户密默认是 \zhsquote{root}
\section{打包升级文件}
参考 RKDevTool\_Release\_v2.96\textbackslash{}bin 目录下的 mkupdate.bat 脚本:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{text}
mklink /J Image ..\..\rockdev
Afptool.exe -pack ./ Image\update.img
RKImageMaker.exe -RK3588 Image\MiniLoaderAll.bin Image\update.img update.img \
-os_type:androidos
rem update.img is new format, Image\update.img is old format, so delete older one
del Image\update.img
pause
\end{minted}
打包进 update.img 在文件由 package-file 文件控制:
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{text}
# NAME Relative path
#
#HWDEF HWDEF
package-file package-file
bootloader Image/MiniLoaderAll.bin
parameter Image/parameter.txt
#
# if uboot.img is fit, uboot.img had include uboot and trust,
# so ignore trust.img
# file Image/uboot.img
# Image/uboot.img: Device Tree Blob version 17
#
# trust Image/trust.img
#
uboot Image/uboot.img
misc Image/misc.img
#resource Image/resource.img
#kernel Image/kernel.img
boot Image/boot.img
rootfs Image/rootfs.img
recovery Image/recovery.img
oem Image/oem.img
userdata:grow Image/userdata.img
# 要写入backup分区的文件就是自身(update.img)
# SELF 是关键字,表示升级文件(update.img)自身
# 在生成升级文件时,不加入SELF文件的内容,但在头部信息中有记录
# 在解包升级文件时,不解包SELF文件的内容。
#backup RESERVED
#update-script update-script
#recover-script recover-script
\end{minted}
\# 开头的行是注释。 打包文件时要注意以下几点:
\begin{itemize}
\item 打包 update.img 固件时需要注意,升级固件不一定要全分区升级,可修改 package-file 文件,将不
要升级的分区去掉,这样可以减少升级包(update.img )的大小。
\item package-file 中 recovery.img 如果打包进去的话 ,不会在 Recovery 模式中升级,为了预防升级
recovery.img过程中掉电导致后面其他分区无法正常升级的问题,该分区升级放在 normal 系统下升
级,即,执行 update 命令时会先检测 update.img 升级包中是否有打包 recovery.img,若有则升级
recovery 分区,再进入 Recovery 模式升级其他分区固件。
\item misc 分区不建议打包进 update.img 中,即使有打包进去,也会在升级程序中加载判断到而忽略该分
区,即使升级了 misc 分区,升级成功后 recovery 程序仍会清空 misc 分区中所有的命令及参数,从
而导致达不到预想的结果。
\item 如果将 update.img 升级包放置在 flash 中的 userdata 分区,则需要保证 package-file 中括 不包括
userdata.img 被打包进去,原因是可能会导致文件系统的损坏,升级成功后可能使 oem或 userdata 分
区mount不成功。若从SD卡或 U 盘升级时,可以打包 userdata.img,从而对userdata 分区进行升级。
升级完成后会对 userdata 分区重新resize 操作。
\end{itemize}