Bananapi R2 定製系統

背景

由於項目需要使用了Banana Pi R2這塊板子。參考的資料主要是官方的wiki、GitHub以及論壇。

  • 官網:http://banana-pi.org/
  • Wiki:http://wiki.banana-pi.org/Main_Page
  • 論壇:http://forum.banana-pi.org/
  • 鏡像:https://dev.banana-pi.org.cn/Image/BPI-R2/Ubuntu16.04/
  • BSP:https://github.com/BPI-SINOVOIP/BPI-R2-bsp-4.14

初探

先使用官方提供的鏡像,製作SD卡啓動盤,查看效果。

宿主機環境:

root@liu:~# uname -a
Linux liu 4.15.0-45-generic #48~16.04.1-Ubuntu SMP Tue Jan 29 18:03:48 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

從官網下載最新鏡像:

2017-11-28-ubuntu-16.04-mate-desktop-bpi-r2-sd-emmc.img.zip    

安裝工具:

root@liu:~# apt install -y gcc-arm-linux-gnueabihf u-boot-tools curl pv 
root@liu:~# curl -sL https://github.com/BPI-SINOVOIP/bpi-tools/raw/master/bpi-tools | sudo -E bash

格式化SD卡 (需要保證SD卡的容量是8G或者以上的)

查看SD卡對應的盤符
root@liu:~# fdisk –l 
刪除SD的所有分區
root@liu:~# fdisk /dev/sdx
格式化SD卡位FAT模式
root@liu:~# mkfs.vfat /dev/sdx -I

燒寫鏡像到SD卡

root@liu:~# dd if=[imagename] of=/dev/sdx bs=10M

定製系統

官方的鏡像太龐雜,希望自己可以定製一個。

編譯BSP

先清空之前的內容

root@liu:~# cd /root/src/BPI-R2-bsp-4.14、
root@liu:~# ./build.sh
選擇 7

重新編譯

root@liu:~# ./build.sh
選擇 1

需要等待一會,該過程會編譯u-boot、kerenl、以及打包。

創建文件系統

安裝依賴工具包

root@liu:~# apt-get install qemu-user-static debootstrap binfmt-support parted zip

從官網下載Ubuntu16的最小文件系統

http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/
root@liu:~# mkdir rootfs
root@liu:~# tar xvf ubuntu-base-16.04-core-armhf.tar.gz -C rootfs

利用qemu和chroot

cp /etc/resolv.conf rootfs/etc/resolv.conf
root@liu:~# cp /usr/bin/qemu-arm-static rootfs/usr/bin/
root@liu:~# chroot /root/image/rootfs

現在通過qemu模擬器進入了剛製作的根文件系統

root@liu:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@liu:/# pwd
/

更新apt源

root@liu:~# vi /etc/apt/sources.list
deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted
deb http://ports.ubuntu.com/ubuntu-ports/ xenial universe
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial universe
deb http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted
deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security multiverse
root@liu:~# apt update
root@liu:~# apt upgrade 
root@liu:~# apt-get dist-upgrade

安裝必備包

root@liu:~# apt install language-pack-en-base sudo ssh net-tools ethtool wireless-tools ifupdown network-manager iputils-ping rsyslog bash-completion vim minicom lrzsz gcc

設置主機名

root@liu:~# echo "bpi-r2" >/etc/hostname
root@liu:~# vi /etc/hosts
127.0.0.1       localhost
127.0.1.1       bpi-r2

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

設置root用戶對於的密碼

root@liu:/# passwd
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

創建普通用戶

root@liu:~# useradd -m -G users,sudo,ssh -s /bin/bash bpi
root@liu:~# passwd bpi
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

設置時區

root@liu:~# locale-gen en_US
root@liu:~# locale-gen en_US.UTF-8
root@liu:~# dpkg-reconfigure tzdata
root@liu:~# update-locale LANG=en_US.UTF-8

設置fstab

root@liu:~# vi /etc/fstab 
proc /proc proc defaults 0 0
LABEL=BPI-BOOT /boot vfat errors=remount-ro 0 1
LABEL=BPI-ROOT / ext4 defaults,noatime 0 0

設置網絡

root@liu:~# vi /etc/network/interfaces
# loop
auto lo
iface lo inet loopback

#first set the upstream-Port (NIC between CPU and MT7530-Switch) up
auto eth0
iface eth0 inet manual
  pre-up ip link set $IFACE up
  post-down ip link set $IFACE down

auto eth1
iface eth1 inet manual
  pre-up ip link set $IFACE up
  post-down ip link set $IFACE down

#then configure the lan-ports
auto lan0
iface lan0 inet static
  address 172.16.30.252
  netmask 255.255.255.0
  gateway 172.16.30.1
  pre-up ip link set $IFACE up
  post-down ip link set $IFACE down

修改ssh配置

root@liu:~# vi /etc/ssh/sshd_config
PermitRootLogin yes
PubkeyAuthentication no
#AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes

清理不必要的包

root@liu:~# rm -rf /var/lib/apt/lists/*
root@liu:~# apt clean

退出qemu

root@liu:~# exit
root@liu:~# rm /root/image/rootfs/usr/bin/qemu-arm-static

製作鏡像文件

創建一個新的image文件,大小爲8G

root@liu:~# dd if=/dev/zero bs=1M count=7296 | pv | dd of=bpi.img

加載該鏡像爲虛擬盤

root@liu:~# losetup /dev/loop8 bpi.img

分區並且格式化

root@liu:~# parted -s /dev/loop8 mklabel msdos
root@liu:~# parted -s /dev/loop8 unit MiB mkpart primary fat32 -- 100MiB 356MiB
root@liu:~# parted -s /dev/loop8 unit MiB mkpart primary ext2 -- 356MiB 7295MiB
root@liu:~# partprobe /dev/loop8

root@liu:~# mkfs.vfat /dev/loop8p1 -I -n BPI-BOOT
root@liu:~# mkfs.ext4 -O ^has_journal -E stride=2,stripe-width=1024 -b 4096 /dev/loop8p2 -L BPI-ROOT

root@liu:~# sync

掛載文件系統

root@liu:~# mkdir /mnt/rootfs
root@liu:~# mount /dev/loop8p2 /mnt/rootfs
root@liu:~# mkdir /mnt/rootfs/boot
root@liu:~# mount /dev/loop8p1 /mnt/rootfs/boot

拷貝之前製作的文件系統到該鏡像

root@liu:~# cp -a /root/image/rootfs/* /mnt/rootfs

進入BSP目錄

root@liu:~# cd /root/src/BPI-R2-bsp-4.14

拷貝boot分區文件:BPI-BOOT-bpi-r2.tgz

root@liu:~# tar xvf SD/BPI-BOOT-bpi-r2.tgz --keep-directory-symlink -C /mnt/rootfs/boot

拷貝內核文件:4.14.34-BPI-R2-Kernel.tgz、4.14.34-BPI-R2-Kernel-net.tgz

root@liu:~# tar xvf SD/4.14.34-BPI-R2-Kernel.tgz --keep-directory-symlink -C /mnt/rootfs
root@liu:~# tar xvf SD/4.14.34-BPI-R2-Kernel-net.tgz --keep-directory-symlink -C /mnt/rootfs

拷貝BootLoader文件:BOOTLOADER-bpi-r2.tgz

root@liu:~# tar xvf SD/BOOTLOADER-bpi-r2.tgz --keep-directory-symlink -C /mnt/rootfs

把電源按鍵放到黑名單

root@liu:~# echo "blacklist mtk_pmic_keys" > /mnt/rootfs/etc/modules-load.d/mtk_pmic_keys.conf

卸載文件系統

root@liu:~# umount /mnt/rootfs/boot
root@liu:~# umount /mnt/rootfs

寫入頭文件: BPI-R2-HEAD440-0k.img、BPI-R2-HEAD1-512b.img

droot@liu:~# d if=mt-pack/mtk/bpi-r2/bin/BPI-R2-HEAD440-0k.img of=/dev/loop8 bs=1024 seek=0
root@liu:~# dd if=mt-pack/mtk/bpi-r2/bin/BPI-R2-HEAD1-512b.img of=/dev/loop8 bs=512 seek=1

寫入preloader:preloader_iotg7623Np1_sd_1600M.bin 和u-boot:u-boot.bin

root@liu:~# dd if=mt-pack/mtk/bpi-r2/bin/preloader_iotg7623Np1_sd_1600M.bin of=/dev/loop8 bs=1024 seek=2
root@liu:~# dd if=u-boot-mt/u-boot.bin of=/dev/loop8 bs=1024 seek=320
root@liu:~# sync

刪除loop盤

root@liu:~# losetup -d /dev/loop8

把鏡像寫入SD卡

root@liu:~# fdisk -l
root@liu:~# dd if=/root/image/bpi.img of=/dev/sdx bs=10M

腳本

上面的命令,集成到腳本文件中

#!/bin/bash -v

IMAGE=/root/image/bpi.img
BSP=/root/BPI-R2-bsp-4.14

[ -f $IMAGE ] && rm $IMAGE

sudo dd if=/dev/zero bs=1M count=7296 | pv | dd of=$IMAGE

sudo losetup /dev/loop8 $IMAGE
sudo parted -s /dev/loop8 mklabel msdos
sudo parted -s /dev/loop8 unit MiB mkpart primary fat32 -- 100MiB 356MiB
sudo parted -s /dev/loop8 unit MiB mkpart primary ext2 -- 356MiB 7295MiB
sudo partprobe /dev/loop8
sudo mkfs.vfat /dev/loop8p1 -I -n BPI-BOOT
sudo mkfs.ext4 -O ^has_journal -E stride=2,stripe-width=1024 -b 4096 /dev/loop8p2 -L BPI-ROOT

sync

[ -d /mnt/rootfs ] || sudo mkdir /mnt/rootfs
sudo mount /dev/loop8p2 /mnt/rootfs
[ -d /mnt/rootfs/boot ] || sudo mkdir /mnt/rootfs/boot
sudo mount /dev/loop8p1 /mnt/rootfs/boot

sudo cp -a /root/image/rootfs/* /mnt/rootfs


cd $BSP

sudo tar xvf SD/BPI-BOOT-bpi-r2.tgz --keep-directory-symlink -C /mnt/rootfs/boot

sudo tar xvf SD/4.14.34-BPI-R2-Kernel.tgz --keep-directory-symlink -C /mnt/rootfs
sudo tar xvf SD/4.14.34-BPI-R2-Kernel-net.tgz --keep-directory-symlink -C /mnt/rootfs

sudo tar xvf SD/BOOTLOADER-bpi-r2.tgz --keep-directory-symlink -C /mnt/rootfs

sudo umount /mnt/rootfs/boot
sudo umount /mnt/rootfs

sudo dd if=mt-pack/mtk/bpi-r2/bin/BPI-R2-HEAD440-0k.img of=/dev/loop8 bs=1024 seek=0
sudo dd if=mt-pack/mtk/bpi-r2/bin/BPI-R2-HEAD1-512b.img of=/dev/loop8 bs=512 seek=1
sudo dd if=mt-pack/mtk/bpi-r2/bin/preloader_iotg7623Np1_sd_1600M.bin of=/dev/loop8 bs=1024 seek=2
sudo dd if=u-boot-mt/u-boot.bin of=/dev/loop8 bs=1024 seek=320

sync

sudo losetup -d /dev/loop8

sudo dd if=$IMAGE of=/dev/sdc bs=10M


應用

業務層面需要使用操作GPIO和UART,需要注意的的一些細節如下。

GPIO

查看GPIO的基數,可以看到是:232

root@liu:~# mount -t debugfs none /sys/kernel/debug
root@liu:~# cat /sys/kernel/debug/pinctrl/1000b000.pinctrl/gpio-r 
GPIO ranges handled:
0: 1000b000.pinctrl GPIOS [232 - 511] PINS [0 - 279]

以GPIO205爲例,具體的值爲,437(232+205) 操作方式如下

root@liu:~# echo 437 > /sys/class/gpio/export
root@liu:~# echo out > /sys/class/gpio/gpio437/direction
root@liu:~# echo 1 > /sys/class/gpio/gpio437/value
root@liu:~# echo 292 > /sys/class/gpio/unexport

UART

通過設備數可以瞭解到終端使用的是ttyS0,對應關係如下

  • ttyS0 <–> Uart2
  • ttyS1 <–> Uart0
  • ttyS2 <–> Uart1
    設備數信息
root@liu:~# vi linux-mt/arch/arm/boot/dts/mt7623.dtsi
        uart2: serial@11004000 {
                compatible = "mediatek,mt7623-uart",
                             "mediatek,mt6577-uart";
                reg = <0 0x11004000 0 0x400>;
                interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
                clocks = <&pericfg CLK_PERI_UART2_SEL>,
                         <&pericfg CLK_PERI_UART2>;
                clock-names = "baud", "bus";
                status = "disabled";
        };

        uart0: serial@11002000 {
                compatible = "mediatek,mt7623-uart",
                             "mediatek,mt6577-uart";
                reg = <0 0x11002000 0 0x400>;
                interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
                clocks = <&pericfg CLK_PERI_UART0_SEL>,
                         <&pericfg CLK_PERI_UART0>;
                clock-names = "baud", "bus";
                status = "disabled";
        };

        uart1: serial@11003000 {
                compatible = "mediatek,mt7623-uart",
                             "mediatek,mt6577-uart";
                reg = <0 0x11003000 0 0x400>;
                interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
                clocks = <&pericfg CLK_PERI_UART1_SEL>,
                         <&pericfg CLK_PERI_UART1>;
                clock-names = "baud", "bus";
                status = "disabled";
        };
root@liu:~# vi linux-mt/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts    
        uart0_pins_a: uart@0 {
                pins_dat {
                        pinmux = <MT7623_PIN_79_URXD0_FUNC_URXD0>,
                                 <MT7623_PIN_80_UTXD0_FUNC_UTXD0>;
                };
        };

        uart1_pins_a: uart@1 {
                pins_dat {
                        pinmux = <MT7623_PIN_81_URXD1_FUNC_URXD1>,
                                 <MT7623_PIN_82_UTXD1_FUNC_UTXD1>;
                };
        };

&uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
        status = "okay";
};

&uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_pins_a>;
        status = "okay";
};

&uart2 {
        status = "okay";
};

參考

http://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:start
http://forum.banana-pi.org/t/how-to-build-an-ubuntu-debian-sd-image-from-scratch/6805
http://forum.banana-pi.org/t/gpio-uart-not-the-debug-port/3748/6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章