Skip to content

Linux Common Customizations

APT Repository Configuration

1. Check the software version to find the appropriate repository mirror

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.6 LTS
Release:        20.04
Codename:       focal

2. APT repository file paths

Tip

Older APT systems use sources.list (One-Line-Style) format
Newer APT systems use DEB822 format .sources files (e.g., Debian 12, Ubuntu 24.04)

/etc/apt/sources.list
/etc/apt/sources.list.d/debian.sources
/etc/apt/sources.list.d/ubuntu.sources

3. Change repository to USTC mirror

sources.list format

sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# Update package cache
sudo apt update

DEB822 format

# Debian systems
sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources
# Ubuntu systems
sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources
# Update package cache
sudo apt update

Startup Scripts

Startup script path:

/etc/init.d/kickpi.sh

Example:

Grant execution permission to the script and add the startup command to kickpi.sh to enable auto-start.

chmod +x /usr/bin/test_boot.sh
vim /etc/init.d/kickpi.sh
+ source /usr/bin/test_boot.sh

Startup Services

Create service configuration file /usr/lib/systemd/system/test-boot.service

[Unit]
Description=boot test service
After=graphical.target

[Service]
Type=simple
ExecStart=/usr/bin/test.sh
User=root
Environment=DISPLAY=:0

[Install]
WantedBy=graphical.target

Create /usr/bin/test.sh script and set permissions. After boot, check /tmp/test.log to verify if the service started successfully.

$ sudo vim /usr/bin/test.sh
#!/bin/bash

echo "hello test boot service" > /tmp/test.log

$ sudo chmod 777 /usr/bin/test.sh

Enable the service

sudo systemctl enable test-boot.service

Disable the service

sudo systemctl disable test-boot.service

Serial Port Auto Login

Default login method when using serial port

vim /lib/systemd/system/serial-getty@.service
-ExecStart=-/sbin/agetty --autologin root --keep-baud 115200,38400,9600 %I $TERM
+ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud 115200,57600,38400,9600 - $TERM

Login as kickpi user by default when using serial port

vim /lib/systemd/system/serial-getty@.service
-ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud 115200,57600,38400,9600 - $TERM
+ExecStart=-/sbin/agetty --autologin kickpi --keep-baud 115200,38400,9600 %I $TERM

Login as root user by default when using serial port

vim /lib/systemd/system/serial-getty@.service
-ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud 115200,57600,38400,9600 - $TERM
+ExecStart=-/sbin/agetty --autologin root --keep-baud 115200,38400,9600 %I $TERM

User Configuration

Default Accounts and Passwords

Default usernames and passwords for different systems:

System Username Password
Debian linaro linaro
Debian root root
Ubuntu kickpi kickpi
Ubuntu root root

Change User Password

Tip

Enter current user password (e.g., kickpi).
New Password: Enter the new root password (password is not displayed).
Retype new password: Confirm.
"password updated successfully" indicates success.

Set root password

sudo passwd root

Switch User

Note

Latest desktop versions default to login user: kickpi
Some commands may require root privileges. Add sudo before the command or switch to root user.

su $(username)

Desktop Login Configuration

The graphical interface defaults to logging in as kickpi. Modify the display manager configuration.

Check current display manager

cat /etc/X11/default-display-manager

SLiM

Modify the SLiM configuration file to change the default login user. Reboot to apply changes.

sudo vim /etc/slim.conf
--default_user        kickpi
++default_user        root

LightDM

Modify the LightDM configuration file to change the default login user. Reboot to apply changes.

Tip

Path varies by system configuration
/etc/lightdm/lightdm.conf
/etc/lightdm/lightdm.conf.d/50-myconfig.conf

sudo vim /etc/lightdm/lightdm.conf 
--autologin-user=linaro
++autologin-user=kickpi

Grant root login permission

sudo vim /etc/pam.d/lightdm-autologin
--auth required pam_succeed_if.so user != root quiet_success
++#auth required pam_succeed_if.so user != root quiet_success

Command Line Login Configuration

Check current system boot mode

sudo systemctl get-default

Disable desktop environment

Change system default to multi-user text mode. Reboot to apply changes.

sudo systemctl set-default multi-user.target
sudo reboot

Enable desktop environment

Change system default to graphical desktop mode. Reboot to apply changes.

sudo systemctl set-default graphical.target
sudo reboot

Language Configuration

Tip

Changes take effect after reboot.

  • Set English language
sudo locale-gen en_US.UTF-8
sudo sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen
sudo echo "LANG=en_US.UTF-8" >> /etc/default/locale
sudo echo "export LC_ALL=en_US.UTF-8" >> /etc/profile.d/zh_CN.sh
sudo echo "export LANG=en_US.UTF-8" >> /etc/profile.d/zh_CN.sh
sudo echo "export LANGUAGE=en_US:en" >> /etc/profile.d/zh_CN.sh
sudo reboot
  • Set Chinese language
sudo locale-gen zh_CN.UTF-8
sudo sed -i 's/^# *\(zh_CN.UTF-8\)/\1/' /etc/locale.gen
sudo echo "LANG=zh_CN.UTF-8" >> /etc/default/locale
sudo echo "export LC_ALL=zh_CN.UTF-8" >> /etc/profile.d/zh_CN.sh
sudo echo "export LANG=zh_CN.UTF-8" >> /etc/profile.d/zh_CN.sh
sudo echo "export LANGUAGE=zh_CN:zh" >> /etc/profile.d/zh_CN.sh
sudo reboot

Timezone Configuration

Tip

Changes take effect after reboot.

  • Set timezone to Asia/Shanghai
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime     
  • Set timezone to America/New_York
ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime

Time Configuration

System time configuration

# Set current system time
date -s "2026-04-14 15:30:00"

# Set only date
date -s "2026-04-14"

# Set only time
date -s "15:35:00"

# View system time
date

RTC time configuration

# View hardware RTC time
hwclock -r

# Specify RTC device if multiple exist
hwclock -r --rtc=/dev/rtc0

# Write system time to hardware RTC
hwclock -w
hwclock --systohc

# Sync hardware RTC time to system
hwclock -s
hwclock --hctosys

RTC sysfs nodes

# View date
cat /sys/class/rtc/rtc0/date

# View time
cat /sys/class/rtc/rtc0/time

Configure RTC time sync on boot

$ vim /etc/init.d/rockchip.sh
- [ -f /dev/rtc0 ] &&  hwclock --systohc
+ [ -f /dev/rtc0 ] &&  hwclock --hctosys

Note

1. Rockchip platforms display logos in two stages: Uboot and Kernel. logo.bmp is for the Uboot stage, logo_kernel.bmp for the Kernel stage.
2. Logo resolution must not exceed the display resolution.
3. Replacement logo format must match the original (e.g., bmp, bit depth parameters).

SoC Model Logo Path
A133 K5/K5C device/config/chips/a133/configs/c3/android/bootlogo.bmp
RK3562/RK3568/RK3588 K1/K1B/K3/K8 kernel/logo.bmp
kernel/logo_kernel.bmp
RK3576 K7/K7C kernel-6.1/logo.bmp
kernel-6.1/logo_kernel.bmp
T527 K9 device/config/chips/t527/boot-resource/boot-resource/bootlogo.bmp

Screen Display Orientation

  • Check current display information

Tip

The output shows a single-screen setup with display device named HDMI-1.

$ xrandr
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
HDMI-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1920x1080     60.00*+  60.00    50.00    59.94    30.00    24.00    29.97    23.98  
   1920x1080i    60.00    50.00    50.00    59.94  
   1280x1024     60.02  
   1440x900      59.90  
   1360x768      60.02  
   1280x720      60.00    50.00    50.00    59.94  
   1024x768      60.00  
   800x600       60.32  
   720x576       50.00    50.00  
   720x576i      50.00  
   720x480       60.00    60.00    59.94    59.94  
   720x480i      60.00    59.94  
   640x480       60.00    59.94    59.94  
  • Rotate screen orientation

Note

normal: Normal display orientation.
left: Rotate 90 degrees counterclockwise.
inverted: Rotate 180 degrees.
right: Rotate 90 degrees clockwise.

Set rotation for a specific display device

$ xrandr --output (dev) --rotate [normal|left|inverted|right]   

Example: Rotate HDMI-1 display 90 degrees counterclockwise.

$ xrandr --output HDMI-1 --rotate left
  • Auto-start rotation service reference

Ubuntu system

Configure LVDS-1 display to rotate 90 degrees counterclockwise.

root@ubuntu2004:~# vim /etc/systemd/system/xrandr-startup.service 
[Unit]
Description=Start xrandr script on boot
After=graphical.target

[Service]
Type=oneshot
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/kickpi/.Xauthority"
ExecStart=/usr/bin/xrandr --output LVDS-1 --rotate left
User=kickpi

[Install]
WantedBy=graphical.target
sudo systemctl enable xrandr-startup
sudo systemctl start xrandr-startup

Debian system

Configure DSI-1 display to rotate 90 degrees counterclockwise.

vim /etc/systemd/system/xrandr-startup.service
[Unit]
Description=Start xrandr script on boot
After=graphical.target

[Service]
Type=oneshot
TimeoutStartSec=10
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/linaro/.Xauthority"
ExecStart=/usr/local/bin/wait-for-x11.sh /usr/bin/xrandr --output DSI-1 --rotate left
User=linaro

[Install]
WantedBy=graphical.target

Script configuration

root@linaro-alip:/# cat /usr/local/bin/wait-for-x11.sh
#!/bin/bash

while ! xrandr --query > /dev/null 2>&1; do
        sleep 1
        echo "Waiting for X server to be ready..."
done
exec "$@" 

Enable the service

sudo systemctl enable xrandr-startup
sudo systemctl start xrandr-startup

Touchscreen Orientation Configuration

1. Install tools

apt update
apt install xinput
apt install xinput-calibrator

2. List devices and IDs. The output shows touchscreen device "goodix-ts" with ID 10.

$ xinput_calibrator --list
    Device "goodix-ts" id=10

3. Configure input device calibration matrix

xinput set-prop $id --type=float "libinput Calibration Matrix" 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0

Example: Set calibration matrix for goodix-ts device.

xinput set-prop 10 --type=float "libinput Calibration Matrix" 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0
  1. Configure input device coordinate transformation matrix
# normal
$ xinput set-prop $id 'Coordinate Transformation Matrix' 1 0 0 0 1 0 0 0 1 
# left
$ xinput set-prop $id 'Coordinate Transformation Matrix' 0 -1 1 1 0 0 0 0 1
# right
$ xinput set-prop $id 'Coordinate Transformation Matrix' 0 1 0 -1 0 1 0 0 1
# inverted
$ xinput set-prop $id 'Coordinate Transformation Matrix' -1 0 1 0 -1 1 0 0 1

Example: Use the appropriate command based on rotation. Set coordinate transformation matrix to "left" for goodix-ts.

xinput set-prop 10 'Coordinate Transformation Matrix' 0 -1 1 1 0 0 0 0 1
  1. Calibrate touchscreen
$ xinput_calibrator -v --device $id

Example: Calibrate goodix-ts device.

$ xinput_calibrator -v --device 10
  • Persist touchscreen orientation

After xinput modification succeeds, persist the touch rotation.

Tip

Option "TransformationMatrix" "0 -1 1 1 0 0 0 0 1" is the line to add.

vim /usr/share/X11/xorg.conf.d/40-libinput.conf

Section "InputClass"
        Identifier "libinput touchscreen catchall"
        MatchIsTouchscreen "on"
        MatchDevicePath "/dev/input/event*"
        Driver "libinput"
        Option "TransformationMatrix" "0 -1 1 1 0 0 0 0 1"
EndSection

Network Configuration

Common Commands

  • Display all network interface information

Tip

Network interface names may vary depending on the environment.

$ ifconfig -a
enP3p49s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 82:76:b8:2f:96:6d  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 168  base 0xd000  

enP4p65s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 6a:cb:0c:a5:15:e0  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 179  base 0x1000  
...
  • Display specific network interface information

Tip

To display information for a specific interface (e.g., eth0), run ifconfig eth0.

ifconfig <dev>
  • Set IP address
ifconfig eth0 <ip> netmask <nmask>

Example: Set IP address 192.168.1.101 with netmask 255.255.255.0 for eth0.

ifconfig eth0 192.168.1.101 netmask 255.255.255.0
  • Enable network interface
ifconfig <dev> up
  • Disable network interface
ifconfig <dev> down

Example: Disable eth0.

ifconfig eth0 down
  • Set MAC address

Tip

Some operating systems may not allow setting MAC address directly with ifconfig or may require additional steps.

ifconfig <dev> down
ifconfig <dev> hw ether <new MAC address>
ifconfig <dev> up

Static IP Configuration

Example 1: Configure static IP 192.168.1.50 for eth0 using netplan YAML.

$ vim /etc/netplan/01-network-manager-all.yaml

network:
    version: 2
    ethernets:
        eth0:
          dhcp4: no
          addresses: [192.168.199.160/24]
          optional: true
          routes:
            - to: default
              via: 192.168.199.1
          nameservers:
            addresses: [8.8.8.8, 8.8.4.4]

Example 2: Configure static IP 192.168.77.196 for eth1 using network/interfaces.

$ sudo vim /etc/network/interfaces.d/eth1.cfg
auto eth1
iface eth1 inet static
address 192.168.77.196
netmask 255.255.255.0
gateway 192.168.77.1
dns-nameservers 8.8.4.4 8.8.8.8

Restart the service

$ reboot

Wi-Fi Hotspot Configuration

  • Check AP mode support

Tip

AP/VLAN indicates hardware support.

$ iw list | grep AP
Device supports AP-side u-APSD.
         * AP
         * AP/VLAN
        HE Iftypes: AP
        HE Iftypes: AP
         * wake up on EAP identity request
         * AP/VLAN
         * #{ managed } <= 1, #{ AP, P2P-client, P2P-GO } <= 1, #{ P2P-device } <= 1,
    Driver supports full state transitions for AP/GO clients
    Driver/device bandwidth changes during BSS lifetime (AP/GO mode)
         * AP: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
         * AP/VLAN: 0x00 0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0 0xc0 0xd0 0xe0 0xf0
         * AP: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
         * AP/VLAN: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0

Virtual Interface Hotspot

1. Install dependencies

$ sudo apt-get install util-linux hostapd dnsmasq iptables iproute2 haveged make

2. Create virtual wireless interface

Note

<wirelessname> is the physical wireless interface name (check with ifconfig). <virtualwlanname> is the virtual wireless interface name.

$ sudo iw dev <wirelessname> interface add <virtualwlanname> type __ap  

Example:

$ sudo iw dev wlan0 interface add wlo2 type __ap

3. Assign MAC address to virtual interface

Tip

<virtualwlanname> can be any name. Change it if a conflict occurs.

$ sudo ip link set dev <virtualwlanname> address 22:33:44:55:66:00

Example:

$ sudo ip link set dev wlo2 address 22:33:44:55:66:00

4. Verify creation

Warning

The virtual interface will be removed after system reboot.

$ sudo iw dev wlo2 info
   Interface wlo2
    ifindex 5
    wdev 0x5
    addr 22:33:44:55:66:00
    type managed
    wiphy 0
    txpower 0.00 dBm
    multicast TXQ:
        qsz-byt qsz-pkt flows   drops   marks   overlmt hashcol tx-bytestx-packets
        0   0   0   0   0   0   0   0   0

5. Download and install create_ap

$ git clone https://github.com/oblique/create_ap
$ cd */create_ap
$ sudo make install

6. Create hotspot with create_ap

Note

<wirelessname>: Wireless interface name
<virtualwlanname>: Virtual interface name
<SSID> <password>: Hotspot SSID and password.

$ sudo create_ap -c 11 <virtualwlanname> <wirelessname> <SSID> <password> 

Example:

$ sudo create_ap -c 11 wlo2 wlan0 m3 88888888

If the hotspot creation hangs with the following error:

#RTNETLINK answers: Device or resource busy

#ERROR: Maybe your WiFi adapter does not fully support virtual interfaces.
     #  Try again with --no-virt.

Stop the previously created hotspot and restart.

$ sudo create_ap --stop <virtualwlanname>  

Physical Interface Hotspot

1. Install dependencies and create_ap

$ sudo apt-get install util-linux hostapd dnsmasq iptables iproute2 haveged make
$ git clone https://github.com/oblique/create_ap
$ cd */create_ap
$ sudo make install

2. Configure firewall

$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
$ iptables --version

3. Create hotspot "MyAccessPoint" with password "12345678", sharing eth0 network

$ sudo create_ap --no-virt wlan0 eth0 MyAccessPoint 12345678 &

4. Restore Wi-Fi interface after using create_ap

$ sudo create_ap --fix-unmanaged

USB Camera

  • Check camera device nodes
$ ls /dev/video*
/dev/video-dec0  /dev/video-enc0  /dev/video0  /dev/video1  /dev/video2
  • Open camera with ffmpeg
$ sudo apt install ffmpeg 
$ ffplay -f v4l2 -i /dev/video* 

Example:

$ ffplay -f v4l2 -i /dev/video1

Filesystem Backup

Export filesystem

1. Check if ff_export_rootfs script exists. If not, download ff_export_rootfs and copy it to /usr/bin/ on the board.

ls /usr/bin/ff_export_rootfs

2. Insert a USB drive (โ‰ฅ 16GB) or other storage device. Export the filesystem to the USB drive path.

Note

FAT32 has a 4GB single file limit. Format the USB drive as ext4 or exFAT.
Output package name format: e.g., rootfs.img.
/mnt/usb: USB drive mount point.

sudo chmod +x /usr/bin/ff_export_rootfs
sudo ./ff_export_rootfs $(out_path) -t ext4
# Export image to /mnt/usb
sudo ./ff_export_rootfs /mnt/usb -t ext4

3. Verify the exported filesystem format.

file Ubuntu_24.04.2_LTS_ext4_202503062020.img 
# Output similar to: Ubuntu_24.04.2_LTS_ext4_202503062020.img: Linux rev 1.0 ext4 filesystem data, UUID=71584b93-ad99-452e-a8e2-6b9ed76eff7d, volume name "rootfs" (extents) (64bit) (large files) (huge files)

Update image filesystem

rootfs.img can be used to repackage a complete RK platform image. Create a full update package update-*.img for batch flashing. See RK Image Unpack and Repack.

Replace filesystem only

Tip

Replacing rootfs this way may cause mount UUID issues. Check the correct UUID with blkid and modify /etc/fstab.

rootfs.img can be flashed standalone to replace the board's filesystem. After flashing, if the root filesystem occupies exactly the size of rootfs.img, run this command to restore full capacity.

$ resize2fs /dev/mmcblk1p6 0

RK Image Unpack and Repack

Tutorial on how to unpack and repack RK firmware on Linux.

  • Get the tools

1. Download tools, or find them in the SDK.

// Linux-SDK source path:
rk356x-linux\tools\linux\Linux_Pack_Firmware
// Android-SDK source path:
rk-android13.0\RKTools\linux\Linux_Pack_Firmware
  • Unpack

1. Copy Linux_Pack_Firmware to your VM working directory.

ls Linux_Pack_Firmware/
rockdev

2. Place the firmware to unpack under the rockdev directory and rename it to update.img.

cd Linux_Pack_Firmware/rockdev
mv update-rk3568-kickpi-k1-linux-debian--20250403-150845.img update.img

3. Run the unpack script

./unpack.sh

4. Unpacked files location.

ls output/
Image  MiniLoaderAll.bin  package-file  parameter.txt
  • Repack

Tip

After modifying the unpacked images, repack them.

1. Copy files to the corresponding paths in rockdev. Delete the update.img used for unpacking.

cp -rf output/* ./ 
mv parameter.txt Image/
mv MiniLoaderAll.bin Image/
rm update.img

2. Modify the package-file to point to the correct file paths.

# NAME  PATH
package-file    package-file
parameter       Image/parameter.txt
bootloader      Image/MiniLoaderAll.bin
uboot   Image/uboot.img
misc    Image/misc.img
boot    Image/boot.img
recovery        Image/recovery.img
backup  RESERVED
rootfs  Image/rootfs.img

3. Run the repack script for the corresponding version.

./rk356x-mkupdate.sh

4. The repacked image is located in the rockdev directory.

ls update.img

RK System Partition Configuration

Warning

Repartitioning requires re-flashing. To preserve the system without formatting, backup rootfs first.

Two modification methods:

  • Modify full image

Refer to Firmware Unpack and Repack. Modify parameter.txt and repack.

  • Modify within SDK

Modify the corresponding file and recompile.

RK356x:

SDK$ device/rockchip/rk3566_rk3568/parameter-buildroot-fit.txt

RK3588:

SDK$ device/rockchip/rk3588/parameter.txt 

Modification content:

Repartitioning primarily involves modifying the parameter.txt partition file.

Example: Allocate all remaining space to the root directory.

mtdparts=:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00010000@0x00068000(backup),-@0x00078000(rootfs:grow)

Note

Partition rules:
Partition size: 0x01c00000 * 512 Bytes / 1024 / 1024 / 1024 โ‰ˆ 14GB
Partition start address: previous partition start address + previous partition size
Last partition format: -@0x0xxxxx(xxx:grow) - The remaining space is auto-allocated.

Linux systems require an additional step: comment out automatic mounting of oem and userdata.

$ sudo mount -o loop rootfs.img rootfs
$ sudo vim rootfs/etc/fstab 

Compilation Toolchain Configuration

Installation command

$ sudo apt update && sudo apt install -y build-essential manpages-dev

Samba Configuration

1. Install samba

$ sudo apt install samba samba-common

2. Grant permissions to the shared directory

$ sudo chmod 777 /home/kickpi/

3. Add samba user

$ sudo smbpasswd -a

4. Configure samba

$ sudo vim /etc/samba/smb.conf

Add the following at the end of smb.conf:

Tip

[kickpi] is the share name visible to clients.

[kickpi] 
    comment = kickpi 
    path = /home/kickpi
    public = yes   
    writable = yes 
    workgroup = kickpi 

5. Restart the service

$ sudo systemctl restart smbd

NFS Configuration

  • Environment setup
sudo apt install nfs-kernel-server
sudo apt install rpcbind
sudo apt install nfs-common
  • Server side

1. Configure shared directory

$ mkdir /home/kickpi/nfs_share
$ chmod 777 /home/kickpi/nfs_share
$ vi /etc/exports
+ /home/kickpi/nfs_share *(rw,sync,no_subtree_check,insecure)

2. Start the service

sudo service nfs-kernel-server restart

3. Verify shared directories on the server

$ showmount -e localhost
Export list for localhost:
/home/kickpi/nfs_share *
  • Client side

1. Check server shared directories

showmount -e 192.168.19.173
Export list for 192.168.19.173:
/home/kickpi/nfs_share *

2. Mount the shared directory

$ mkdir nfs_tmp
$ sudo mount -t nfs 192.168.19.173:/home/kickpi/nfs_share nfs_tmp/

3. Verify successful mount

$ ls nfs_tmp/
1.txt

SSH Configuration

SSH connection

Connect via SSH from command line:

ssh <username>@<IP>

Root login configuration

$ vim /etc/ssh/sshd_config
+ PermitRootLogin yes
$ cat /etc/ssh/sshd_config | grep PermitRootLogin
PermitRootLogin yes
$ sudo /etc/init.d/ssh restart

Remove stale host key

Target Linux host reinstalled system / reset SSH โ†’ key fingerprint changed. Windows still has old invalid key โ†’ connection refused.

ssh-keygen -R 192.168.77.165

SCP File Transfer

1. Usage

usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]
           [-i identity_file] [-J destination] [-l limit]
           [-o ssh_option] [-P port] [-S program] source ... target

2. Quick usage

Note

$local_path: Local file path
$username: Username
$ip: Board IP address
$target_path: Destination path

$ scp $local_path username@$ip:$target_path

Example:

$ scp .\1.wav linaro@192.168.77.165:/home/linaro/Desktop/

4G/5G Configuration

Script Configuration

4G/5G modules auto-configure on boot. The script checks for module presence and initiates dial-up.

Tip

Dial-up occurs only once at boot by default. If signal is poor or communication is abnormal, dial-up may fail. Run the dial-up script manually to retry.

$ cat /usr/bin/hardware-optimization 
4g_config() {
    wait_time=30
        for((i=1;i<=$wait_time;i++));
        do 
                if [ -c /dev/ttyUSB2 ]; then
                        echo "$i: 4g /dev/ttyUSB2 exists and is a character device." >> $LOG_FILE
                        /usr/bin/4G_dialing.sh
            break;
                else
                        echo "$i: 4g /dev/ttyUSB2 does not exist or is not a character device." >> $LOG_FILE
                        sleep 1
                fi
        done
}

Dial-up script, compatible with RG200U / EC200 / EC20

$ ls /usr/bin/4G_dialing.sh

Network Testing

1. Check if the module is detected by viewing logs.

Tip

/dev/ttyUSB2 exists and is a character device. indicates successful device detection.

$ cat /tmp/kickpi-hardware.log 
1: 4g /dev/ttyUSB2 does not exist or is not a character device.
2: 4g /dev/ttyUSB2 does not exist or is not a character device.
...
24: 4g /dev/ttyUSB2 does not exist or is not a character device.
25: 4g /dev/ttyUSB2 exists and is a character device.

Alternatively, check if /dev/ttyUSB2 exists.

$ ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2  /dev/ttyUSB3  /dev/ttyUSB4

2. Check if dial-up succeeded.

Tip

Device name format: enx* (suffix varies). Use the actual name from your environment.

(console)$ ifconfig
enxca7f24fb0e94: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.138.192.102  netmask 255.255.255.0  broadcast 10.138.192.255
        inet6 fe80::583f:ed51:782d:318d  prefixlen 64  scopeid 0x20<link>
        ether ca:7f:24:fb:0e:94  txqueuelen 1000  (Ethernet)
        RX packets 181  bytes 15185 (14.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 194  bytes 17394 (16.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

3. Ping network test

Tip

Specify interface enx3e003a5bd6ad for the ping test.

(console)$ ping www.baidu.com -I enxca7f24fb0e94
PING www.wshifen.com (103.235.46.115) from 10.138.192.102 enxca7f24fb0e94: 56(84) bytes of data.
64 bytes from 103.235.46.115 (103.235.46.115): icmp_seq=1 ttl=45 time=1094 ms
64 bytes from 103.235.46.115 (103.235.46.115): icmp_seq=2 ttl=45 time=3924 ms
64 bytes from 103.235.46.115 (103.235.46.115): icmp_seq=3 ttl=45 time=1870 ms

Customizing Dial-up Functionality

The board uses the official quectel-CM tool for dial-up by default. To customize dial-up functionality, download the official Quectel Linux software for customization.

# Clone on the board
git clone https://github.com/quectel-open-source/Quectel_QConnectManager_Linux.git
make

GPU

GPU Usage

cat /sys/devices/platform/*gpu/utilisation

Example:

Monitor GPU usage in real-time. Move the mouse, drag windows, or run a GPU benchmark to check if hardware acceleration is enabled.

$ watch -n 1 'cat /sys/devices/platform/*gpu/utilisation'

GLmark2 Performance Test

1. Use Rockchip's official NPU test script

$ ls /rockchip-test/gpu
gpu_test.sh  test_fullscreen_glmark2.sh  test_normal_glmark2.sh test_offscreen_glmark2.sh  test_stress_glmark2.sh

2. Debian/Ubuntu filesystems include the glmark2-es performance testing tool. Run the following command in a virtual terminal or debug serial terminal to start GPU performance testing.

Tip

Surface Size: 800x600 windowed. glmark2 score: 1405.
Test results are for reference only. Actual scores depend on the test environment.

root@linaro-alip:/# source /rockchip-test/gpu/test_offscreen_glmark2.sh 
run glmark2 x11 with offscreen......
arm_release_ver: g13p0-01eac0, rk_so_ver: 10
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      ARM
    GL_RENDERER:    Mali-G52
    GL_VERSION:     OpenGL ES 3.2 v1.g13p0-01eac0.0fd2effaec483a5f4c440d2ffa25eb7a
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   800x600 windowed
=======================================================
=======================================================
                                  glmark2 Score: 1405 
=======================================================

NPU

NPU Testing

Rockchip provides NPU test scripts.

# ls /rockchip-test/npu2
model  npu_freq_scaling.sh  npu_stress_test.sh  npu_test.sh

NPU frequency scaling test script npu_freq_scaling.sh

usage()
{
    echo "Usage: npu_freq_scaling.sh [test_second] [every_freq_stay_second]"
    echo "example: ./npu_freq_scaling.sh 3600 30"
    echo "means npu_freq_scaling.sh will run 1 hour and every cpu frequency stay 30s"
}

Example: Run NPU frequency scaling for 60 seconds, changing frequency every 10 seconds.

# ./npu_freq_scaling.sh 60 10
test will run 60 seconds
every npu frqeucny will stay 10 seconds
set ddr frequency to 700000000
set ddr frequency to 300000000
...
======TEST SUCCESSFUL, QUIT=====

NPU stress test script npu_stress_test.sh

# ./npu_stress_test.sh
rknn_api/rknnrt version: 2.0.0b0 (35a6907d79@2024-03-24T10:31:14), driver version: 0.9.7
model input num: 1, output num: 1
input tensors:
  index=0, name=input, n_dims=4, dims=[1, 224, 224, 3], n_elems=150528, size=150528, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=0, scale=0.007812
output tensors:
  index=0, name=MobilenetV1/Predictions/Reshape_1, n_dims=2, dims=[1, 1001, 0, 0], n_elems=1001, size=2002, fmt=UNDEFINED, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000
custom string: 
Begin perf ...
   0: Elapse Time = 2.85ms, FPS = 351.12
   1: Elapse Time = 2.70ms, FPS = 370.37
   2: Elapse Time = 2.59ms, FPS = 386.85
   3: Elapse Time = 2.69ms, FPS = 371.61
   4: Elapse Time = 2.62ms, FPS = 381.97
   5: Elapse Time = 2.61ms, FPS = 383.44
   6: Elapse Time = 2.58ms, FPS = 387.75
   7: Elapse Time = 2.70ms, FPS = 370.51
   8: Elapse Time = 2.64ms, FPS = 378.36
   9: Elapse Time = 2.68ms, FPS = 372.44
---- Top5 ----
0.935059 - 156
0.057037 - 155
0.003881 - 205
0.003119 - 284
0.000172 - 285

Note

Performance test data interpretation:
The content after Begin perf... shows performance metrics for multiple inference runs. Each entry includes the test round number, inference time (Elapse Time), and frames per second (FPS).
Example: 0: Elapse Time = 2.85ms, FPS = 351.12 means the first inference round took 2.85ms, which translates to 351.12 inferences per second. FPS is calculated as 1000ms รท inference time, representing NPU inference efficiency.
Inference result interpretation:
The ---- Top5 ---- section shows the top five classification results with confidence scores and class IDs:
1. 0.935059 - 156: The model assigns 93.51% confidence that the input belongs to class 156. This high confidence indicates reliable classification.
2. Subsequent entries (0.057037 - 155, etc.) show the 2nd through 5th highest confidence results, with decreasing confidence scores.

RKNN Deployment

Click to jump to RKNN Deployment.

MPP

Debug Information

Enable debug information

$ export mpp_syslog_perror=1
$ echo 0x100 > /sys/module/rk_vcodec/parameters/mpp_dev_debug
# After enabling debug, hardware codec calls produce log output similar to:
[  893.134037] rk_vcodec: 27b00100.rkvdec:0 session 3705:19 time: 1333 us hw 1312 us
[  893.167444] rk_vcodec: 27b00100.rkvdec:0 session 3705:19 time: 1381 us hw 1313 us
[  893.200503] rk_vcodec: 27b00100.rkvdec:0 session 3705:19 time: 1420 us hw 1313 us

Disable debug information

$ export mpp_syslog_perror=0
$ echo 0x100 > /sys/module/rk_vcodec/parameters/mpp_dev_debug

mpi_enc_test Hardware Encoding

  • mpi_enc_test hardware encoding test
usage: mpi_enc_test [options]
 -i       input_file          input frame file                       
 -o       output_file         output encoded bitstream file          
 -w       width               the width of input picture             
 -h       height              the height of input picture            
 -hstride hor_stride          the horizontal stride of input picture 
 -vstride ver_stride          the vertical stride of input picture   
 -f       format              the format of input picture            
 -t       type                output stream coding type              
 -tsrc    source type         input file source coding type          
 -n       max frame number    max encoding frame number              
 -g       gop reference mode  gop_mode:gop_len:vi_len                
 -rc      rate control mode   set rc_mode, 0:vbr 1:cbr 2:fixqp 3:avbr
 -bps     bps target:min:max  set tareget:min:max bps                
 -fps     in/output fps       set input and output frame rate        
 -qc      quality control     set qp_init:min:max:min_i:max_i        
 -fqc     frm quality control set fqp min_i:max_i:min_p:max_p        
 -s       instance_nb         number of instances                    
 -v       trace option        q - quiet f - show fps                 
 -l       loop count          loop encoding times for each frame     
 -ini     ini file            encoder extra ini config file          
 -slt     slt file            slt verify data file                   
 -sm      scene mode          scene_mode, 0:default 1:ipc 

Encode 100 frames of H.264 at 4096x2160

$ mpi_enc_test -w 4096 -h 2160 -t 7 -o ./test.h264 -n 100
# Test result
$ tail -f /var/log/syslog
kickpi mpp[3557]: mpi_enc_test: chn 0 encode 100 frames time 3763 ms delay  27 ms fps 26.57 bps 10605252

Encode 100 frames of H.265 at 4096x2160

$ mpi_enc_test -w 4096 -h 2160 -t 16777220 -o ./test.h265 -n 100
# Test result
$ tail -f /var/log/syslog
kickpi mpp[3560]: mpi_enc_test: chn 0 encode 100 frames time 4086 ms delay  36 ms fps 24.47 bps 19594276

mpi_dec_test Hardware Decoding

  • mpi_dec_test hardware decoding test
 usage: mpi_dec_test [options]
 -i       input_file   input bitstream file                                 
 -o       output_file  output decoded frame file                            
 -w       width        the width of input bitstream                         
 -h       height       the height of input bitstream                        
 -t       type         input stream coding type                             
 -f       format       output frame format type                             
 -n       frame_number max output frame number                              
 -s       instance_nb  number of instances                                  
 -v       trace option q - quiet f - show fps                               
 -slt     slt file     slt verify data file                                 
 -help    help         show help                                            
 -bufmode buffer mode  hi - half internal (default) i -internal e - external

Decode 100 frames of H.264 at 4096x2160

$ mpi_dec_test -t 7 -i test.h264 -n 100
# Test result
$ tail -f /var/log/syslog
kickpi mpp[3564]: mpi_dec_test: decode 100 frames time 596 ms delay  25 ms fps 167.53

Decode 100 frames of H.265 at 4096x2160

$ mpi_dec_test -t 16777220 -i test.h265 -n 100
# Test result
$ tail -f /var/log/syslog
kickpi mpp[3569]: mpi_dec_test: decode 100 frames time 803 ms delay  49 ms fps 124.47

Third-party Software Hardware Codec

Tip

RK platform Linux Ubuntu has compatibility issues with hardware codec in Chromium and GStreamer.
RK platform Linux Ubuntu 24.04 can use a fix script to configure hardware codec for Chromium or GStreamer. Due to compatibility issues, only one can be active at a time.
For hardware codec, RK Linux Debian is recommended for better compatibility.

  • Chromium video test

Connect a display to the board. Open a virtual terminal or debug serial terminal and run:

$ source /rockchip-test/chromium/test_chromium_with_video.sh

Chromium is configured by default. If Chromium is not using hardware decoding, apply the fix:

$ source /rockchip-test/chromium/chromium_mpp_fix.sh
  • GStreamer video test
$ sudo GST_DEBUG=2 gst-launch-1.0 playbin uri=file:///usr/local/test.mp4 video-sink="autovideosink" audio-sink=fakesink

Chromium is configured by default. To enable GStreamer hardware decoding, apply the fix (requires network connection):

$ source /rockchip-test/gstreamer/gstreamer_mpp_fix.sh
  • Chromium hardware acceleration test example

Test platform: RK3568 Debian 11 Chromium

Test results:

1080P@30fps: GPU usage around 42%-48%. Decode time per frame log snippet:

[  639.172225] rk_vcodec: fdf80200.rkvdec:0 session 2268:56 time: 4195 us hw 4095 us
[  639.180185] rk_vcodec: fdf80200.rkvdec:0 session 2268:56 time: 12116 us hw 7960 us
[  639.190246] rk_vcodec: fdf80200.rkvdec:0 session 2268:56 time: 19541 us hw 10027 us
...

4K@30fps: GPU usage around 60%-68%. Decode time per frame log snippet:

[  938.649847] rk_vcodec: fdf80200.rkvdec:0 session 2799:80 time: 93967 us hw 27794 us
[  938.683932] rk_vcodec: fdf80200.rkvdec:0 session 2799:80 time: 93243 us hw 34114 us
[  938.717400] rk_vcodec: fdf80200.rkvdec:0 session 2799:80 time: 93712 us hw 33463 us
...

Common Issues

  • Linux system reboots after first boot?

To support different chips, /etc/init.d/rockchip.sh installs various chip-specific packages (e.g., libmali, isp) on first boot, then restarts the display service. For custom projects, handle these differences when building the image.

  • create_ap shows dnsmasq error?

Error during hotspot creation:

dnsmasq: failed to bind DHCP server socket: Address already in use

create_ap needs to start dnsmasq, but dnsmasq is already running.

$ sudo lsof -i

Find the PID of dnsmasq.

$ sudo kill -9 <PID> 
  • create_ap compatibility patch for iw version 6.7 and above?
@@ -321,9 +321,9 @@ can_transmit_to_channel() {

    if [[ $USE_IWCONFIG -eq 0 ]]; then
        if [[ $FREQ_BAND == 2.4 ]]; then
-           CHANNEL_INFO=$(get_adapter_info ${IFACE} | grep " 24[0-9][0-9] MHz \[${CHANNEL_NUM}\]")
+           CHANNEL_INFO=$(get_adapter_info ${IFACE} | grep " 24[0-9][0-9]\(\.0\+\)\? MHz \[${CHANNEL_NUM}\]")
        else
-           CHANNEL_INFO=$(get_adapter_info ${IFACE} | grep " \(49[0-9][0-9]\|5[0-9]\{3\}\) MHz \[${CHANNEL_NUM}\]")
+           CHANNEL_INFO=$(get_adapter_info ${IFACE} | grep " \(49[0-9][0-9]\|5[0-9]\{3\}\)\(\.0\+\)\? MHz \[${CHANNEL_NUM}\]")
        fi
        [[ -z "${CHANNEL_INFO}" ]] && return 1
        [[ "${CHANNEL_INFO}" == *no\ IR* ]] && return 1
@@ -339,7 +339,9 @@ can_transmit_to_channel() {

# taken from iw/util.c
ieee80211_frequency_to_channel() {
-   local FREQ=$1
+   local FREQ_MAYBE_FRACTIONAL=$1
+   local FREQ=${FREQ_MAYBE_FRACTIONAL%.*}

    if [[ $FREQ -eq 2484 ]]; then
        echo 14
    elif [[ $FREQ -lt 2484 ]]; then
@@ -356,7 +358,7 @@ ieee80211_frequency_to_channel() {
}

is_5ghz_frequency() {
-    [[ $1 =~ ^(49[0-9]{2})|(5[0-9]{3})$ ]]
+   [[ $1 =~ ^(49[0-9]{2})|(5[0-9]{3})(\.0+)?$ ]]
}

is_wifi_connected() {
    return 1
}
  • Slim login manager username modification issue

1. After boot, change hostname to the new username.

sudo hostnamectl set-hostname kickpi-new

2. Modify auto-login user configuration to the new username.

/etc/lightdm/lightdm.conf 
/etc/pam.d/lightdm-autologin
/lib/systemd/system/serial-getty@.service

3. Use usermod to change the username.

Tip

kickpi-new: New username
kickpi: Old username

sudo usermod -l kickpi-new kickpi

4. Set the new user home directory.

mv /home/kickpi /home/kickpi-new
sudo usermod -d /home/kickpi-new -m kickpi-new

5. Clear graphical interface cache.

rm -f /home/kickpi-new/.Xauthority
rm -rf /var/run/slim/*
rm -rf /var/lib/slim/

6. Reconfigure the Slim display manager.

sudo pam-auth-update