在 QEMU 中運行 ubuntu 16.04 armhf 填坑記

0、前言

  • 參考

    作者: 摩斯電碼

    博客: https://www.cnblogs.com/pengdonglin137/p/9540670.html

    發佈: 2018-08-27 10:38

  • 平臺

    • QEMU 運行環境

      • QEMU: 3.1.0
      • Linux: 3.18.135
      • Board: aarch32 vexpress-ca9
      • FS: ubuntu 16.04.6 armhf
      • Host: CentOS 7
      • Network: CentOS 7 通過 Apache proxy 上網;QEMU 通過 tap 橋接 CentOS 7 的網絡
    • 製作FS環境

      • Vmware: 10.7
      • Linux: Ubuntu 16.04.6 i386

1、在UBUNTU 16.04 中安裝qemu-user-static

在Linux PC主機上安裝模擬器:

sudo apt-get install qemu-user-static

2、下載和解壓 ubuntu-core

# 從官方上獲取ubuntu core的tar包:http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/
wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/16.04.6/release/ubuntu-base-16.04-core-armhf.tar.gz

選擇下載ubuntu-base-16.04-core-armhf.tar.gz,下載完之後,創建臨時文件夾並解壓根文件系統:

mkdir tmp
sudo tar -xf ubuntu-base-16.04-core-armhf.tar.gz -C tmp/

3、修改根文件系統

  • 1、準備網絡

    sudo cp -b /etc/resolv.conf tmp/etc/resolv.conf
    

    這個文件存放了DNS服務器的地址

  • 2、準備qemu

    cp /usr/bin/qemu-arm-static tmp/usr/bin/
    
  • 3、增加軟件源

    中科大鏡像站 http://mirrors.ustc.edu.cn/ ,在ubuntu-ports這一行點擊help,將內容複製到source.list文件中

    sudo vim tmp/etc/apt/source.list
    # 首先刪除全部內容,然後,粘貼上述ubuntu-ports的help中的內容 
    
  • 4、進入根文件系統進行操作

    • 可以使用下面的腳本ch-mount.sh將根目錄切換到tmp下:

      #!/bin/bash
      
      function 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 chroot ${2}
      }
      function umnt() {
          echo "UNMOUNTING"
          sudo umount ${2}proc
          sudo umount ${2}sys
          sudo umount ${2}dev
      }
      if [ "$1" == "-m" ] && [ -n "$2" ] ;
      then
          mnt $1 $2
      elif [ "$1" == "-u" ] && [ -n "$2" ];
      then
          umnt $1 $2
      else
          echo ""
          echo "Either 1'st, 2'nd or both parameters were missing"
          echo ""
          echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
          echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
          echo ""
          echo "For example: ch-mount -m /media/sdcard/"
          echo ""
          echo 1st parameter : ${1}
          echo 2nd parameter : ${2}
      fi
      
    • 切換根目錄:

      sudo ch-mount.sh -m tmp/
      
    • 更新

      apt update 
      apt upgrade
      
    • 安裝軟件包

      apt install udev         #否則ttyAMA0無法找到
      apt install vim          #vim編輯器
      apt install net-tools    #ifconfig,netstat,route,arp等
      apt install iputils-ping #ping
      apt install sudo         #sudo命令
      #apt install ssh         #ssh的client和server
      apt install ethtool      #ethtool命令,顯示、修改以太網設置
      #apt install wireless-tools    #iwconfig等,顯示、修改無線設置
      apt install ifupdown          #ifup,ifdown等工具
      #apt install network-manager   #Network Manager服務和框架,高級網絡管理
      apt install iputils-ping      #ping和ping6
      apt install rsyslog           #系統log服務
      apt install bash-completion   #bash命令行補全
      apt install htop              #htop工具,交互式進程查看器
      
    • 對於bash命令自動補全功能,需要安裝bash-completion,此外還需要修改/etc/bash.bashrc,將下面的命令的註釋去掉:

      # enable bash completion in interactive shells
      if ! shopt -oq posix; then
         if [ -f /usr/share/bash-completion/bash_completion ]; then
           . /usr/share/bash-completion/bash_completion
         elif [ -f /etc/bash_completion ]; then
           . /etc/bash_completion
         fi
      fi
      

      然後重新登錄即可。

    • 創建用戶

      全部安裝完之後,添加一個用戶zoen,並設置密碼,同時把root的密碼也修改一下:

      useradd -s '/bin/bash' -m -G adm,sudo zoen  #增加zoen用戶
      passwd zoen #給zoen用戶設置密碼 
      passwd root #修改root密碼
      
    • 爲zoen增加sudo權限,修改/etc/sudoers,增加:

      zoen ALL=(ALL:ALL) ALL
      
    • 設置ip

      編輯/etc/network/interfaces,添加如下內容:

      auto lo
      iface lo inet loopback
      
      auto eth0
      iface eth0 inet dhcp
      # iface eth0 inet static
      # address 192.168.1.5
      # netmask 255.255.255.0
      # gateway 192.168.1.1
      
    • 設置hostname

      # 設置主機名稱:
      echo "sahara">/etc/hostname
      
      # 設置本機入口ip:
      echo "127.0.0.1 localhost">>/etc/hosts
      echo "127.0.1.1 sahara">>/etc/hosts
      
    • 在軟件安裝完畢後,退出根目錄:ctrl+D 或者 exit

      執行umount:

      ./ch-mount.sh -u tmp/
      

4、製作根文件系統

  • 查看根文件系統的大小

    du -sh  tmp/
    351M    tmp/
    
  • 生成鏡像,並格式爲ext4

    dd if=/dev/zero  of=ubuntu.img   bs=1M   count=1024
    # mkfs.ext4 ubuntu.img
    mkfs.ext3   ubuntu.img
    mkdir mnt
    sudo mount  ubuntu.img mnt
    sudo cp -rfp tmp/* mnt
    sudo umount  mnt
    
    #檢查並修復ubuntu.img
    e2fsck -p -f ubuntu.img
    
  • 拷貝鏡像到CentOS 7

    # Vmware環境,掛載有/mnt/hgfs/temp目錄
    cp ubuntu.img /mnt/hgfs/temp
    # 然後,從temp目錄中將ubuntu.img拷貝到CentOS 7目標機器上
    

5、測試

  • 開機(在CentOS 7中):

    qemu-system-arm -M vexpress-a9 -m 1024M -kernel zImage -nographic -dtb vexpress-v2p-ca9.dtb \
        -append "root=/dev/mmcblk0 rw rootfstype=ext3 console=ttyAMA0,115200" \
        -net nic -net tap,ifname=tap1,script=/etc/qemu-ifup,downscript=no -sd ./ubuntu.img 
    
  • 關於-monitor的選項,這裏做如下說明:

    參考: 通過網絡連接到QEMU monitor (https://blog.csdn.net/wan_hust/article/details/31365331)

    • tcp – raw tcp sockets #下面第2點,我的舉例是RAW TCP socket
    • telnet – the telnet protocol is used instead of raw tcp sockets. This is the preferred option over tcp as you can break out of the monitor using Ctrl-] then typing quit. You can’t break out of the monitor like this after connecting with the raw socket option
    • 127.0.0.1 – Listen on this host/IP only. You can use 127.0.0.1 if you want to only allow connections locally. If you want to listen on any ip address on the server, just leave this blank so you end up with two consecutive colons ie “::” .
    • 4444 – port number to listen on.
    • server – listening in server mode
    • nowait – qemu will wait for a client socket application to connect to the port before continuing unless this option is used. In most cases you’ll want to use the nowait option.

6、填坑記

  • chroot, 報"failed to run command ‘/bin/bash’: Exec format error"

    這個坑是想直接在 CentOS 7 環境下,按照以上步驟製作 Ubuntu 16.04 armhf 的文件系統時發生的。說明:

    • 在CentOS 7 中,chroot 到 amd64 的 UBUNTU 沒有問題
    • 在CentOS 7 中,chroot 到 arm64 的 UBUNTU 也報上述錯誤
    • 在CentOS 7 中,首先chroot 到amd64 的UBUBTU, 在該UBUNTU 中chroot 到 arm64 的 UBUNTU 也報上述錯誤

    解決方法:

    • 按照參考,在UBUNTU 16.04 中製作armhf 的文件系統
  • apt-get update,報“Temporary failure resolving ‘ports.ubuntu.com

    # 原因是dns沒有配置,解決辦法 加入dns服務器地址
    vi /etc/resolv.conf
    nameserver 10.10.10.20
    nameserver 10.10.10.8
    
    
  • apt-get時,報“The method driver /usr/lib/apt/methods/http could not be found

    sudo apt-get install apt-transport-https
    
  • 報“Could not execute ‘apt-key’ to verify signature

    sudo rm /var/lib/apt/lists/* -vf
    sudo apt-get update
    # 若仍然有問題,如下試試
    apt-get update --allow-unauthenticated
    
  • QEMU中,通過proxy上網

    # vim /etc/profile
    http_proxy=192.168.1.3:80
    https_proxy=$http_proxy
    no_proxy=localhost,127.0.0.1
    export http_proxy https_proxy no_proxy
    

    若報告“Cannot initiate the connection to 80:80”,加http://,如下:

    # vim /etc/profile
    http_proxy=http://192.168.1.3:80
    https_proxy=http://192.168.1.3:80
    no_proxy=localhost,127.0.0.1
    export http_proxy https_proxy no_proxy
    
  • apt-get install 報告 “E: Internal Error, ordering was unable to handle the media swap

    sudo rm -fR /var/lib/apt/lists/*
    sudo apt-get update
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章