Try   HackMD

Raspberry Pi Introduction

tags: Linux

Raspberry Pi 3 基本介紹


使用 QEMU 模擬 Raspberry Pi

取得 QEMU

  • 安裝 QEMU
    • $ sudo apt install qemu

取得 Raspbian Image

  • 下載 Raspbian disk image 的 zip 檔
    • $ wget https://downloads.raspberrypi.org/raspbian/images/raspbian-2018-11-15/2018-11-13-raspbian-stretch.zip
  • 解壓縮
    • $ unzip 2018-11-13-raspbian-stretch.zip
    • 解壓縮後的檔名為 2018-11-13-raspbian-stretch.img

取得 Raspberry Pi Kernel

由於 QEMU 和真實的 Pi 還是有些不同的,因此無法使用 2018-11-13-raspbian-stretch.zip 裡面提供的 kernel 來開機,需要自行編出 QEMU 用的 kernel

  • 這邊我們使用了 dhruvvyas90/qemu-rpi-kernel 所編譯好的 kernel 來作使用
    • $ curl https://raw.githubusercontent.com/dhruvvyas90/qemu-rpi-kernel/master/kernel-qemu-4.4.34-jessie --output kernel-qemu-4.4.34-jessie

執行 QEMU

$ sudo qemu-system-arm                                \
  -kernel ./kernel-qemu-4.4.34-jessie                 \
  -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \
  -hda 2018-11-13-raspbian-stretch.img                \
  -cpu arm1176                                        \
  -m 256                                              \
  -M versatilepb                                      \
  -no-reboot                                          \
  -serial stdio                                       \
  -net nic                                            \
  -net user                                           \
  -net tap,ifname=vnet0,script=no,downscript=no

使用 QEMU 模擬 Raspberry Pi 3

編譯 QEMU

由於使用 apt 工具安裝的 QEMU 並不支援 Pi 3,因此我們要自己手動編譯 2.12.0 版本的 QEMU

  • 安裝相關工具
    • $ sudo apt install gcc build-essential automake gcc-arm-linux-gnueabihf
  • 下載 QEMU source code
    • $ wget https://download.qemu.org/qemu-2.12.0-rc3.tar.xz
  • 解壓縮
    • $ tar xvf qemu-2.12.0-rc3.tar.xz
  • 配置設定
    • $ cd qemu-2.12.0-rc3
    • $ ./configure --target-list=arm-softmmu,aarch64-softmmu
      • 相關設定
        • --target-list: 指令想要編譯的模擬器
        • --prefix: 指定程式要安裝的路徑
        • 其他設定與選項皆可從 ./configure --help 得知
  • 編譯及安裝
    • $ make -j$(nproc)
    • $ make install
  • 設定路徑
    • $ echo "export PATH=$(pwd)/aarch64-softmmu:\$PATH" >> ~/.bashrc
    • $ source ~/.bashrc

取得 Raspbian Image

  • 下載 Raspbian disk image 的 zip 檔
    • $ wget https://downloads.raspberrypi.org/raspbian/images/raspbian-2018-11-15/2018-11-13-raspbian-stretch.zip
  • 解壓縮
    • $ unzip 2018-11-13-raspbian-stretch.zip
    • 解壓縮後的檔名為 2018-11-13-raspbian-stretch.img

取得 Raspberry Pi Kernel

由於 QEMU 和真實的 Pi 還是有些不同的,因此無法使用 2018-11-13-raspbian-stretch.zip 裡面提供的 kernel 來開機,需要自行編出 QEMU 用的 kernel,而在這邊參考了 dhruvvyas90/qemu-rpi-kernel 的編譯方式

  • 下載 kernel source code
    • $ git clone git://github.com/raspberrypi/linux.git --branch raspberrypi-kernel_1.20180619-1 --single-branch --depth 1
  • 修正編譯上的錯誤
  • 編譯 kernel
    • 編譯 kernel7.img
      • $ KERNEL=kernel7
    • 初始化 config
      • $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- versatile_defconfig
    • 設定 config
      • dhruvvyas90/qemu-rpi-kernel 上取得 config_fileconfig_ip_tables
      • 添加 config
        • ​​​​​​​​$ cat >> .config << EOF
          ​​​​​​​​CONFIG_CROSS_COMPILE="arm-linux-gnueabihf"
          ​​​​​​​​EOF
          
        • $ cat ./config_file >> .config
        • $ cat ./config_ip_tables >> .config
    • 開啟 menuconfig
      • $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
    • 編譯 kernel 和 dtb
      • $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bzImage dtbs
  • 設定路徑
    • $ cd ..
    • $ cp linux/arch/arm/boot/zImage ./kernel7.img
    • $ cp linux/arch/arm/boot/dts/versatile-pb.dtb ./versatile-pb.dtb

執行 QEMU

  • 使用圖形介面
    ​​$ sudo qemu-system-arm                 \ 
    ​​  -M versatilepb                       \
    ​​  -cpu arm1176                         \
    ​​  -m 256                               \
    ​​  -hda 2018-11-13-raspbian-stretch.img \
    ​​  -kernel kernel7.img                  \
    ​​  -dtb versatile-pb.dtb                \
    ​​  -net nic                             \
    ​​  -net user,hostfwd=tcp::5022-:22      \
    ​​  --append "root=/dev/sda2 panic=1"    \
    ​​  -no-reboot
    
  • 使用終端機介面
    ​​$ sudo qemu-system-arm                                \
    ​​  -M versatilepb                                      \
    ​​  -cpu arm1176                                        \
    ​​  -m 256                                              \
    ​​  -hda 2018-11-13-raspbian-stretch.img                \
    ​​  -kernel kernel7.img                                 \
    ​​  -dtb versatile-pb.dtb                               \
    ​​  -net nic                                            \
    ​​  -net user,hostfwd=tcp::5022-:22                     \
    ​​  --append "rw console=ttyAMA root=/dev/sda2 panic=1" \
    ​​  -nographic                                          \
    ​​  -no-reboot
    
  • Raspberry Pi 預設帳號密碼
    • 帳號︰pi
    • 密碼︰raspberry
  • 離開 QEMU
    • Ctrl-A + X

如何除錯 Raspberry Pi 3 虛擬機器

掛載 image 檔

有時候想要不藉由開機,希望直接從外面改裡面的程式,故使用之

  • 使用 losetup 設定 loop device
    • $ losetup -P -f --show XXX.img
  • 查看 loop device 狀態
    • $ losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0         0      0         0  0   XXX.img   0     512
  • 掛載 image 檔
    • $ mkdir one two
    • $ sudo mount -o loop /dev/loop0p1 ./one
    • $ sudo mount -o loop /dev/loop0p2 ./two
  • 若忘記掛載到哪裡了可以使用 mount -l 查看

使用 GDB 除錯

若發生進不去 OS 的情況 (e.g. Kernel panic, ),就需要藉由外部 debugger 找尋錯誤

  • 說明︰QEMU 內建了一個 GDBServer,可與外部的 GDB 進行一個遠端的除錯,其中藉由 ip:port 網路方式或藉由串列 /dev/ttyS* 的方式來進行工作
  • 如何使用
    • qemu-system-* 後面添加 -S -gdb tcp::1234
    • 使用 arm-linux-gnueabihf-gdb -q 進入 GDB
    • 輸入 (gdb) target remote localhost:1234 即可

參考資料