在 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、增加软件源

    扫描二维码关注公众号,回复: 11961315 查看本文章

    中科大镜像站 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
    

猜你喜欢

转载自blog.csdn.net/hylaking/article/details/88799778