NanoPi-NEO 全志H3移植Ubuntu 22.04 LTS、u-boot、Linux核心/核心樹、mt7601u USB-Wi-Fi支援、配置CLion用於Linux驅動開發

ErBW_s發表於2024-04-22

前言

想在NanoPi-NEO上開發螢幕驅動,但是看了下檔案目錄發現沒有核心樹,導致最基礎的file_operations結構體都無法使用,於是尋找核心樹安裝方法。但官方提供的核心為4.14太舊了apt找不到對應的linux-source版本(其實後面發現不需要用apt,可以在kernel.org上下載,但反正都裝了那就當學習一下怎麼移植了),於是選擇自己重新構建了整個系統。

1. 準備工作

  1. x86_64 Linux 機器或者虛擬機器。

如果是Apple Silicon Mac最好用UTM安裝一個x86_64 Ubuntu server,因為本文使用的安裝rootfs的工具僅x86_64系統可用。
當然也有buildrootdebootstrap方法。debootstrap感覺一般;buildroot或許會比本文方法更好用,但我沒用,想使用這種方法可以考慮去參考這篇文章

  1. 一張sd卡。
  2. 建立一個資料夾存放移植所需各種檔案,如 ~/nanopi-neo

2. 準備SD卡

  1. 可以選擇直接從 NanoPi-NEO 官網燒錄一個映象到SD卡,他會自動幫你分好區(不過也需要修改),也可以手動操作。
  2. 使用fdisk進行分割槽操作(假設這裡SD卡是/dev/sdb,且已經燒錄官方映象)[1]
sudo fdisk /dev/sdb

# 輸入m檢視各種命令
m
# 輸入p列印分割槽情況
p

  1. 如圖,sdb1boot分割槽,sdb2rootfs分割槽

  2. 官方映象可能會多一個sdb3存放userdata,需要刪除後兩個分割槽並格式化,下面展示將末尾分割槽刪除。

  3. 使用如下所示命令建立分割槽。

  4. 其中sector部分延續sdb1131071,第二個直接留空

  5. 執行下面的命令將rootfs分割槽格式化

sudo mkfs.ext4 -L rootfs /dev/sdb2

你也可以選擇從頭建立SD啟動卡,關於這部分可以檢視該教程,這裡不做展開

3. 移植u-boot

  1. Github 上下載最新 u-boot.tar.gz,這裡以2024.04為例[2]

  2. Arm GNU 官網按圖尋找下載正確的交叉編譯鏈。

  3. 解壓

cd nanopi-neo/
tar -vxzf u-boot-2024.04.tar.gz
tar -vxf arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz
  1. 安裝交叉編譯鏈
# 修改交叉編譯鏈檔名方便操作
mv arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf arm-none-linux-gnueabihf

# 移動資料夾
sudo mkdir -p /usr/local/toolchains
sudo mv arm-none-linux-gnueabihf /usr/local/toolchains/

# 新增環境變數
vim .bashrc
# 新增以下三行
export PATH=/usr/local/toolchains/arm-none-linux-gnueabihf/bin/:$PATH
export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabihf-
  1. 編譯 u-boot
cd u-boot-2024.04/
# 生成配置檔案
make nanopi_neo_defconfig
# 生成燒錄檔案 u-boot-sunxi-with-spl.bin
make -j8
# 燒錄到SD卡
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8 oflag=direct

出現錯誤一般是有模組沒有安裝,可以自行搜尋怎麼安裝

4. 移植kernel

  1. Kernel Archives 上下載最新的stable版本 Linux 核心,這裡以6.8.7為例[2:1]
  2. 編譯配置檔案
# 解壓
cd ~/nanopi-neo/
tar -vxf linux-6.8.7.tar.xz

# 安裝一些工具(可能不全,如果編譯遇到缺工具就安裝一下)
sudo apt-get install libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf dwarves bc

cd linux-6.8.7/
# 生成配置檔案.config
make sunxi_defconfig
  1. 增加usb-wifi支援(本文以mt7601u為例)[3]
make menuconfig

按下/搜尋mt7601u,按enter進行搜尋它所需的依賴項

截個屏或者拍個照,找到所有[=n]的對應內容按下y將它加入核心編譯中

如果按y出現彈框,並且關閉彈框後發現是M不是*的話,記得用/尋找對應內容並一一加入核心編譯。
如圖是未配置進核心而是配置為module,需要尋找其他依賴項一一加入核心編譯

一直按esc直到出現該介面,按enter選擇儲存配置

  1. 編譯zImagesun8i-h3-nanopi-neo.dtb
# 編譯時間大概1-2小時
make -j8
  1. 安裝到SD卡中
sudo mount /dev/sdb1 /mnt
sudo cp arch/arm/boot/zImage /mnt/zImage
sudo cp arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo.dtb /mnt/sun8i-h3-nanopi-neo.dtb
sync
sudo umount /mnt
  1. 將SD卡插入開發板中,進入u-boot命令列拉取核心啟動[4]
setenv bootcmd 'fatload mmc 0 0x46000000 zImage; fatload mmc 0 0x48000000 sun8i-h3-nanopi-neo.dtb; bootz 0x46000000 - 0x48000000'
setenv bootargs "console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"
saveenv
boot

5. 移植rootfs

  1. Ubuntu cdimage 下載映象[5],本文使用Ubuntu 22.04 LTS,則進入jammy/daily/current/目錄下載jammy-base-armhf.tar.gz
  2. 建立資料夾並解壓
cd ~/nanopi-neo/
mkdir temp
sudo tar -xpf jammy-base-armhf.tar.gz.tar.gz -C temp
  1. 安裝qemu-user-static(就是這東西只支援x86_64,害我好幾天配置不好)
sudo apt-get install qemu-user-static
  1. 準備工作
# 網路檔案
sudo cp -b /etc/resolv.conf temp/etc/resolv.conf
# qemu檔案
sudo cp /usr/bin/qemu-arm-static temp/usr/bin/

# 建立mount.sh檔案
touch mount.sh
sudo vim mount.sh
  1. mount.sh檔案內容如下
#!/bin/bash
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
}
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
fi

很多教程這裡會讓你換國內源,但是我每次換源後apt很多東西裝不上,因此請自行選擇是否換apt源
關於換源方法見:清華 Ubuntu Ports 軟體倉庫

  1. 使用chroot進入根目錄
# 修改檔案許可權
chmod 777 mount.sh
# 執行.sh檔案
./mount.sh -m temp/
# 切換root
sudo chroot temp
  1. 執行必要命令
# apt更新
apt update
apt upgrade
apt-get update

# 安裝必要工具
apt install -y systemd
apt install vim sudo openssh-server net-tools network-manager
apt install ifupdown htop iputils-ping kmod rsync

# 新增使用者
useradd -s '/bin/bash' -m -G adm,sudo username
# 新增使用者密碼
passwd username
# 新增root密碼
passwd root

# 退出
exit
./mount.sh -u temp/
  1. 把核心原始碼複製到rootfs
sudo cp -r linux-6.8.7/ temp/usr/src/
  1. 安裝rootfs到SD卡
sudo mount /dev/sdb2 /mnt
sudo rm -rf /mnt/*
sudo cp -rp temp/* /mnt/
sudo umount /mnt/
  1. 插入SD卡,開機,首先連線網路
nmcli n
# 如果是disabled執行下面這行命令
nmcli n on
# 檢視網路裝置
nmcli dev

wifi一般是正常的,eth0如果是unmanaged則執行該命令[6]

sudo nmcli dev set eth0 managed yes

我這樣成功了,但不保證一定可以。如果仍然不行可以看註腳的網址,那篇回答同時介紹了另一種方法

連線wifi

# 開啟Wi-Fi
nmcli r wifi on
# 掃描附近Wi-Fi熱點
nmcli dev wifi
# 連線Wi-Fi,替換SSID為Wi-Fi名,PASSWORD為Wi-Fi密碼
nmcli dev wifi connect "SSID" password "PASSWORD" ifname wlx70f11c658d80

配置靜態ip

# 獲取當前ip(假設獲取到ip為192.168.31.102)
ifconfig
# 將當前ip設為靜態ip
sudo nmcli con mod wlx70f11c658d80 ipv4.method manual ipv4.addr 192.168.31.102/24 ipv4.gateway 192.168.31.1 ipv4.dns 192.168.31.1
sudo reboot
  1. 解決中文亂碼[7]
locale -a


正常情況下這裡應該只有CC.utf8POSIX,輸入下面的命令

sudo dpkg-reconfigure locales

按3下enter直到出現如圖所示內容

輸入下面這些數字並回車

# en_US, zh_CN, zh_SG
160 492 497


選擇自己想作為的系統主語言,回車,等待配置完成後重啟即可。

  1. 修改hostname
#修改檔案第一行為自己想要的名字即可
sudo vim /etc/hostname

6. 移植核心樹

理論上只需要這樣就可以了[8]

cd /usr/src/linux-6.8.7/
# 因為之前移植kernel編譯過了,應該不用再make一遍了吧?
# 反正不行就再make一次(被打)
sudo make modules
sudo make modules_install

題外話(配置Clion用於Linux驅動開發)

這篇文章起因是Clion無法找到file_operations結構體,但這樣移植之後還是找不到。配置Clion遠端開發的教程很多,比如這篇,這裡不做贅述,僅提出我這個問題的解決辦法:

  1. CMakeLists.txt中加入這樣一段
include_directories("/usr/src/linux-6.8.7/include/")
  1. File -> Reload CMake Project
  2. Tool -> Resync with Remote Hosts


  1. ubuntu製作SD啟動卡 ↩︎

  2. 全志H3 | 移植主線最新uboot 2023.04和kernel 6.1.11到Nanopi NEO開發板 ↩︎ ↩︎

  3. usbwifi網路卡mt7601u驅動配置 ↩︎

  4. Uboot命令 ↩︎

  5. Ubuntu rootfs customization ↩︎

  6. Ethernet device not managed ↩︎

  7. 解決ubuntu系統中文亂碼問題 ↩︎

  8. 【Linux核心樹】五步構建 ↩︎

相關文章