rk3328編譯Linux固件

1、編譯 Linux 固件

這一章將介紹編譯 ROC-RK3328-CC Linux 固件的整個流程。html

1.1 準備工做

Linux 固件在以下的環境中編譯:python

  • Ubuntu 16.04 amd64

安裝如下包:linux

sudo apt-get install bc bison build-essential curl \
     device-tree-compiler dosfstools flex gcc-aarch64-linux-gnu \
     gcc-arm-linux-gnueabihf gdisk git gnupg gperf libc6-dev \
     libncurses5-dev libpython-dev libssl-dev libssl1.0.0 \
     lzop mtools parted repo swig tar zip

 

1.2 下載 Linux SDK

建立工程目錄:git

# create project dir
mkdir ~/proj/roc-rk3328-cc
cd ~/proj/roc-rk3328-cc

 

下載 Linux SDK:github

# U-Boot
git clone -b roc-rk3328-cc https://github.com/FireflyTeam/u-boot
# Kernel
git clone -b roc-rk3328-cc https://github.com/FireflyTeam/kernel --depth=1
# Build
git clone -b debian https://github.com/FireflyTeam/build
# Rkbin
git clone -b master https://github.com/FireflyTeam/rkbin

 

提示:經過以上連接能夠在線瀏覽源碼。shell

開發板編譯配置在:express

build/board_configs.sh

 

1.3 編譯 U-Boot

編譯 U-Boot:bootstrap

./build/mk-uboot.sh roc-rk3328-cc

 

輸出:ubuntu

out/u-boot/
├── idbloader.img
├── rk3328_loader_ddr786_v1.06.243.bin
├── trust.img
└── uboot.img

 

  • rk3328_loader_ddr786_v1.06.243.bin: DDR 初始化文件。
  • idbloader.img: DDR 初始化與 miniloader 結合的文件。
  • trust.img: ARM trusted 固件。
  • uboot.img: U-Boot映像文件。

相關文件:vim

  • configs/roc-rk3328-cc_defconfig: 默認 U-Boot 配置

1.4 編譯 Kernel

編譯 kernel:

./build/mk-kernel.sh roc-rk3328-cc

 

輸出:

out/
├── boot.img
└── kernel
    ├── Image
    └── rk3328-roc-cc.dtb

 

  • boot.img: 包含 Image and rk3328-roc-cc.dtb 的映像文件, 爲 fat32 文件系統格式。
  • Image: 內核映像。
  • rk3328-roc-cc.dtb: 設備樹 blob。

相關文件:

  • arch/arm64/configs/fireflyrk3328_linux_defconfig: 默認內核配置。
  • arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts: 開發板設備樹描述。
  • arch/arm64/boot/dts/rockchip/rk3328.dtsi: CPU 設備樹描述。

自定義內核配置和更新默認配置:

# 這很是重要!
export ARCH=arm64

cd kernel

# 首先使用默認配置
make fireflyrk3328_linux_defconfig

# 自定義你的 kernel 配置
make menuconfig

# 保存爲默認配置
make savedefconfig
cp defconfig arch/arm64/configs/fireflyrk3328_linux_defconfig

 

注意: 構建腳本不會將內核模塊複製到根文件系統。

1.5 編譯根文件系統

能夠下載預編譯的根文件系統,或參考《編譯 Linux 根文件系統》本身編譯一個。

環境:

  • Ubuntu 16.04 amd64

安裝依賴包:

sudo apt-get install qemu qemu-user-static binfmt-support debootstrap

下載 Ubuntu core:

wget -c http://cdimage.ubuntu.com/ubuntu-base/releases/16.04.1/release/ubuntu-base-16.04.1-base-arm64.tar.gz

建立一個大小爲 1000M 的根文件系統映像文件,並使用 Ubuntu 的基礎包去初始化:

fallocate -l 1000M rootfs.img
sudo mkfs.ext4 -F -L ROOTFS rootfs.img
mkdir mnt
sudo mount rootfs.img mnt
sudo tar -xzvf ubuntu-base-16.04.1-base-arm64.tar.gz -C mnt/
sudo cp -a /usr/bin/qemu-aarch64-static mnt/usr/bin/

qemu-aarch64-static是其中的關鍵,能在 x86_64 主機系統下 chroot 到 arm64 文件系統:

Chroot 到新的文件系統中去並初始化:

sudo chroot mnt/

# 這裏能夠修改設置
USER=firefly
HOST=firefly

# 建立用戶
useradd -G sudo -m -s /bin/bash $USER
passwd $USER
# 輸入密碼

# 設置主機名和以太網
echo $HOST > /etc/hostname
echo "127.0.0.1    localhost.localdomain localhost" > /etc/hosts
echo "127.0.0.1    $HOST" >> /etc/hosts
echo "auto eth0" > /etc/network/interfaces.d/eth0
echo "iface eth0 inet dhcp" >> /etc/network/interfaces.d/eth0
echo "nameserver 127.0.1.1" > /etc/resolv.conf

# 使能串口
ln -s /lib/systemd/system/serial-getty\@.service /etc/systemd/system/getty.target.wants/serial-getty@ttyS0.service

# 安裝包
apt-get update
apt-get upgrade
apt-get install ifupdown net-tools network-manager
apt-get install udev sudo ssh
apt-get install vim-tiny

卸載文件系統:

sudo umount rootfs/

 

1.6 打包原始固件

把你的 Linux 根文件系統映像文件放在 out/rootfs.img

out 目錄將包含如下文件:

$ tree out
out
├── boot.img
├── kernel
│   ├── Image
│   └── rk3328-roc-cc.dtb
├── rootfs.img
└── u-boot
    ├── idbloader.img
    ├── rk3328_loader_ddr786_v1.06.243.bin
    ├── trust.img
    └── uboot.img

2 directories, 8 files

 

打包原始固件:

./build/mk-image.sh -c rk3328 -t system -r out/rootfs.img

這條命令根據《存儲映射》所描述的佈局,將分區映像文件寫到指定位置,最終打包成 out/system.img

燒寫原始固件的步驟,請參考 《上手指南》 一章。

 

2、遇到的問題

2.1 uboot編譯問題

  • rkbin路徑沒有加上bin
  • 文件丟失
    • rk3328_ddr_786MHZ_v1.06.bin
    • rk3328_miniloader_v2.43.bin
    • rk3328_bl31_v1.34.bin
    • rk3328_loader_ddr786_v1.06.243.bin

 

firefly丟失的文件能夠在下面資源找到

https://github.com/gkkpch/rock64-bin    

改完路徑,拷貝以上文件,u-boot編譯成功

 

2.2 編譯kernel遇到的問題

原本內核是在ubuntu16上編譯的,可是我在18上編譯了。不少都是gcc版本引發的,解決起來也比較簡單

drivers/net/wireless/rockchip_wlan/rtl8821cu/hal/phydm/phydm_adc_sampling.c:46:5: warning: this ‘else’ clause does not guard... [-Wmisleading-indentation]
error, forbidden warning: phydm_adc_sampling.c:46

沒加大括號
if-else錯誤

 另外一個錯誤是~號

drivers/net/wireless/rockchip_wlan/rtl8821cu/hal/btc/halbtc8821c1ant.c:2333:30: warning: ‘~’ on a boolean expression [-Wbool-operation]
error, forbidden warning: halbtc8821c1ant.c:2333
~號錯誤提示

修改辦法:

把~號改爲!,雖然可能會有問題。可是解決了編譯的問題

 

drivers/net/wireless/rockchip_wlan/rtl8812au/hal/rtl8812a/rtl8812a_mp.c:640:7: warning: statement will never be executed [-Wswitch-unreachable]

解決辦法:

把語句放在switch外面

 

drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c:2488:3: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation]
error, forbidden warning: dm.c:2488

解決辦法:後面加括號

 

2.3 編譯根文件的問題

編譯根文件的時候可能沒法apt-get update,網絡錯誤。使用指令:

cp /etc/resolv.conf mnt/etc/resolv.conf 解決

使用中沒有lsusb命令:

apt-get install usbutils

沒有lspci:

apt-get install pciutils  

沒有insmod:

apt-get install kmod

啓動A start job is running for Raise network interfaces:

命令:sudo vim /etc/systemd/system/network-online.target.wants/networking.service
將裏面的TimeoutStartSec=5min  修改成TimeoutStartSec=2sec

燒錄鏡像後沒有擴容剩餘空間

首先須要安裝apt-get install parted,而後#vi /etc/rc.local
在exit 0前添加/usr/local/bin/first-boot-recovery.sh啓動腳本,給予可執行權限,用來擴容根目錄,記得在根目錄下新建一個firstboot文件

#!/bin/bash

clean_first_boot () {
    rm -f /firstboot 2>/dev/null
    sync
}


if [ -e /firstboot ]; then
    echo "======Expanding the rootfs..."
    parted /dev/mmcblk0 -- unit s resizepart 5 -34s
    e2fsck -f /dev/mmcblk0p5
    resize2fs /dev/mmcblk0p5
    clean_first_boot
fi
腳本內容如上,紅色部分看實際狀況更改
相關文章
相關標籤/搜索