Total Pageviews

Monday, 14 August 2017

用qemu搭建linux kernel环境

先看看维基百科的解释,什么是qemu

    QEMU是一套由Fabrice Bellard所编写的模拟处理器的自由软件。它与Bochs,PearPC近似,但其具有某些后两者所不具备的特性,如高速度及跨平台的特性。经由KVM(早期为kqemu加速器,现在kqemu已被KVM替换)这个开源的加速器,QEMU能模拟至接近真实电脑的速度。QEMU有两种主要运作模式:

User mode模拟模式,亦即是用户模式。QEMU能引导那些为不同中央处理器编译的Linux程序。而Wine及Dosemu是其主要目标。
System mode模拟模式,亦即是系统模式。QEMU能模拟整个电脑系统,包括中央处理器及其他周边设备。它使得为系统源代码进行测试及除错工作变得容易。其亦能用来在一部主机上虚拟数部不同虚拟电脑。
简而言之,qemu就是一个虚拟机软件,我们可以在里边跑自己构建的操作系统,这对于学习内核或者驱动开发来说真的是相当方便,可以抛开开发板,单拿一台笔记本电脑就可以学习内核测试模块代码,甚至直接做开发。真的是非常方便,废话不多说,开工。

下载安装qemu

笔者测试过ubuntu 12.10 和 ubuntu 16.04两个版本,ubuntu 12.10apt提供的qemu版本较老对arm verpress板子支持的不够好(网友前辈说的,具体哪里不好,我也不知道)。
而ubuntu 16.04 apt提供的是2.5版本的qemu,版本比较新,就不用自己编译安装了。
两种方式全凭个人喜好。
root-># lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04 LTS
Release:    16.04
Codename:   xenial

root-># qemu-system-arm -version
QEMU emulator version 2.5.0 (Debian 1:2.5+dfsg-5ubuntu10.4), Copyright (c) 2003-2008 Fabrice Bellard

ubuntu apt-get方式安装

  root-># apt-get install qemu-system-arm
使用此命令会自动解决依赖关系完成安装过程,安装完成可以通过qemu-system-arm -version
测试安装是否成功。

自己下载安装

ubuntu 的apt其实有qemu的安装包,但是版本较低对vexpress的支持不好,此处直接下载较高版本的qemu自己手动安装。
wget http://wiki.qemu-project.org/download/qemu-2.0.2.tar.bz2
首先需要安装qemu依赖的环境
apt-get install libglib2.0-dev zlib1g-dev
下载完成后安装前需要进行配置,使其支持ARM架构下的所有单板
cd qemu/
./configure --target-list=arm-softmmu --audio-drv-list=
make 
make install
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

下载编译内核

下载内核

可以自行到www.kernel.org上下载最新版内核
  root-># wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.tar.gz

编译内核

  root-># apt-get install libncurses5-dev   

  root->#tar -zxvf linux-3.16.tar.gz 
  root-># cd linux-3.16
  root-># cp arch/arm/configs/vexpress_defconfig  .config
  root-># make menuconfig CROSS_COMPILE=arm-linux- ARCH=arm
  root-># make -j4 CROSS_COMPILE=arm-linux- ARCH=arm
qemu模拟最好的arm芯片是ARM亲生的vexpress A9,本文搭建环境就以此为基础。

测试qemu和内核启动是否成功

qemu-system-arm  -M vexpress-a9 -m 512M -nographic -append "console=ttyAMA0" -kernel  /root/zImage-3.0
  • 1
  • 1
这里简单介绍下qemu命令的参数:
-M vexpress-a9 模拟vexpress-a9单板,你可以使用-M ?参数来获取该qemu版本支持的所有单板
-m 512M 单板运行物理内存512M
-kernel /root/zImage-3.16  告诉qemu单板运行内核镜像路径
-nographic 不使用图形化界面,只使用串口
-append "console=ttyAMA0" 内核启动参数,这里告诉内核vexpress单板运行,串口设备是哪个tty。 
发现启动到挂载根文件系统的时候出现kernel painc,说明内核已经正常启动了。然后需要制作根文件系统。

制作根文件系统

编译busybox

wget http://www.busybox.net/downloads/busybox-1.20.2.tar.bz2 
make defconfig
make CROSS_COMPILE=arm-linux-gnueabi-
make install 
安装完成后,会在busybox目录下生成_install目录,该目录下的程序就是单板运行所需要的命令。

形成根文件系统

  1. 创建rootfs目录(根目录),根文件系统内的文件全部放到这里 
    sudo mkdir rootfs
  2. 拷贝busybox命令到根目录下 
    sudo cp busybox-1.20.2/_install/* -r rootfs/

制作根文件系统镜像

  1. 生成32M大小的镜像 
    dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
  2. 格式化成ext3文件系统 
    mkfs.ext3 a9rootfs.ext3
  3. 将文件拷贝到镜像中 
    sudo mkdir tmpfs 
    sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop 
    cp -r rootfs/* tmpfs/ 
    sudo umount tmpfs

使用qemu启动自定义系统

qemu-system-arm -M vexpress-a9 -m 512M -kernel /root/zImage-3.16 -nographic -append "root=/dev/mmcblk0  console=ttyAMA0" -sd a9rootfs.ext3 
  • 1
  • 1
从内核启动打印,到命令行提示符出现,到此qemu的arm环境就搭建完成了,可以 用来做内核学习了。
但是目前方式挂载的根文件系统使用起来很麻烦,每次修改完代码重新编译之后都需要重新制作文件系统镜像。因此更推荐后边的做法。

使用nfs文件系统启动

安装nfs服务程序

sudo apt-get install nfs-kernel-server

创建nfs共享文件夹

将前边创建的rootfs文件夹的权限修改为777
sudo chmod 777 /root/rootfs
修改/etc/exports文件
sudo vim /etc/exports
添加/root/rootfs *(rw,insecure,sync,no_root_squash)

启动nfs服务

sudo /etc/init.d/nfs-kernel-server start
测试一下nfs环境是否搭建成功
sudo mount -t 127.0.0.1:/root/rootfs /mnt/
ls /mnt查看是否挂载成功
sudo umount /mnt

qemu挂载nfs根文件系统

qemu-system-arm  -M vexpress-a9 -m 512M -nographic -append "console=ttyAMA0 root=/dev/nfs nfsroot=/root/rootfs rw ip=dhcp nousb" -kernel  /root/zImage-3.16
  • 1
  • 1
其中nfsroot=后边是nfs根文件系统位置
ip=dhcp指定qemu guest os 的ip分配方式
至此可以很方便的使用qemu挂载nfs文件系统进行内核学习和开发了。
本文错略的介绍了qemu搭建内核学习的过程,没有过多的关注细节,有兴趣的可以研究一些qemu的其他参数,qemu的网络配置,以及更详细的文件系统构建方法.
----------

用qemu运行linux

    • ubuntu16.04
    • 使用busybox编译最小文件系统,使用qemu运行起来。
    • 内容来自 奔跑吧linux内核第6章
    • 这里将输入代码过程集合到了几个.sh文件,不做重复的工作 !
    • 当然网好是前提,最好挂代理.

    安装工具

    • 首先需要安装qemu gcc, ubuntu16.04中自带的gcc版本较低,这里我们安装书中推荐的gcc-arm-linux-gnueabi
  • sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential
  • 下载busybox源码
    • 书中推荐版本是1.24,但最新版本已经到了busybox-1.27.2.这里我们使用最新版
      • wget https://busybox.net/downloads/busybox-1.27.2.tar.bz2
    • 解压到 busybox 文件夹
    • tar -jxvf busybox-1.27.2.tar.bz2
    • 下载linux内核源码
      • 还是以配套的4.0源码为例,(提醒:内核解压后大约占800MB,请预留出足够空间)
      • wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.0.tar.gz
    • 解压到linux文件夹
    • tar -jxvf linux-4.0.tar.gz

    编译最小文件系统

    * 别问我最小文件系统是什么,我也有点😵,但是先用起来.

    • 首先利用 busybox 手工编译一个最小文件系统。
      在busybox文件夹下
  • export ARCH=ARM
    export CROSS_COMPILE=arm-linux-gnueabi-
    make menuconfig
    make install
  • 进入menuconfig后,配置静态编译
  • Busybox Settings --->
    Build Options --->
    [*] Build BusyBox as a static binary (no shared libs)
  • 然后 make install 编译完成。编译完成后,把 busybox 根目录下面的_install 目录拷贝到 linux-4.0 下。
  • 进入_install 目录,创建 etc、dev 等目录。
  • mkdir etc
    mkdir dev
    mkdir mnt
    mkdir -p etc/init.d/
  • 在_install /etc/init.d/目录下创建 文件名rcS 的文件,写入以下内容:
  • mkdir –p /proc
    mkdir –p /tmp
    mkdir -p /sys
    mkdir –p /mnt
    /bin/mount -a
    mkdir -p /dev/pts
    mount -t devpts devpts /dev/pts
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev –s
    同时使用 chmod +x rcS修改rcS的可执行权限.
  • 在_install /etc 目录创建文件名 fstab 的文件,并写入以下内容。
  • proc /proc proc defaults 0 0
    tmpfs /tmp tmpfs defaults 0 0
    sysfs /sys sysfs defaults 0 0
    tmpfs /dev tmpfs defaults 0 0
    debugfs /sys/kernel/debug debugfs defaults 0 0
  • 在_install /etc 目录创建文件名 inittab 的文件,并写入如下内容。
  • ::sysinit:/etc/init.d/rcS
    ::respawn:-/bin/sh
    ::askfirst:-/bin/sh
    ::ctrlaltdel:/bin/umount -a –r
  • 在_install/dev 目录下创建如下设备节点,以root权限执行
    • cd _install/dev/
      sudo mknod console c 5 1
      sudo mknod null c 1 3

    .sh(配合chmod +x使用)

    • build.sh: 编译busybox
  • export ARCH=ARM
    export CROSS_COMPILE=arm-linux-gnueabi-
    make menuconfig
    make install
  • creat.sh: _install文件夹下处理
    • rm -rf etc
      rm -rf dev
      rm -rf mnt
      mkdir etc
      mkdir dev
      mkdir mnt
      mkdir -p etc/init.d/
      echo "mkdir -p /proc
      mkdir -p /tmp
      mkdir -p /sys
      mkdir -p /mnt
      /bin/mount -a
      mkdir -p /dev/pts
      mount -t devpts devpts /dev/pts
      echo /sbin/mdev > /proc/sys/kernel/hotplug
      mdev -s
      " > etc/init.d/rcS
      chmod +x etc/init.d/rcS
      echo "proc /proc proc defaults 0 0
      tmpfs /tmp tmpfs defaults 0 0
      sysfs /sys sysfs defaults 0 0
      tmpfs /dev tmpfs defaults 0 0
      debugfs /sys/kernel/debug debugfs defaults 0 0
      " > etc/fstab
      echo "::sysinit:/etc/init.d/rcS
      ::respawn:-/bin/sh
      ::askfirst:-/bin/sh
      ::ctrlaltdel:/bin/umount -a -r
      " > etc/inittab
      cd dev/
      sudo mknod console c 5 1
      sudo mknod null c 1 3

    编译内核

    • 编译内核
  • cd linux-4.0
    export ARCH=arm
    export CROSS_COMPILE=arm-linux-gnueabi-
    make vexpress_defconfig
    make menuconfig
  • 配置 initramfs,在 initramfs source file 中填入_install。另外需要把 Default kernel command string 清空。
  • General setup --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (_install) Initramfs source file(s)
    Boot options -->
    ()Default kernel command string
  • 配置 memory split 为“3G/1G user/kernel split”以及打开高端内存。
  • Kernel Features --->
    Memory split (3G/1G user/kernel split) --->
    [ *] High Memory Support
  • 开始编译 kernel
  • make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
    make dtbs
  • 运行 QEMU 来模拟 4 核 Cortex-A9 的 Versatile Express 开发平台。
    • qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic

    .sh(配合chmod +x)

    • build.sh : 编译内核
  • export ARCH=arm
    export CROSS_COMPILE=arm-linux-gnueabi-
    make vexpress_defconfig
    make menuconfig
    make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
    make dtbs
  • run.sh : 运行arm内核
  • qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographicyun

No comments:

Post a Comment