linux内核编程-qemu环境搭建

linux内核编程-qemu环境搭建

1.背景

	最近想学习linux内核和驱动开发,但是不想买开发板,其实我觉得买了也买时间玩耍。以前读书的时候买过2440,后面到杭州买了6410和4412,买的时候兴致勃勃,买了之后新鲜了两天,由于各种原因还是放弃了,现在看到有虚拟环境,工作之余希望可以学习一下。

2.目的

 深入学习linux内核和驱动。

3.虚拟机+Ubuntu

虚拟机可以装15/6;
ubuntu可以装16/18/20的,需要安装两块网卡都是NAT桥接。
虚拟机装了之后会覆盖原先的旧版本,但是原来的系统也可以使用。

4.Git

主要是为了代码管理,业界公认的。

5.qemu

5.1方式1:

	系统镜像源自带,版本较低,但是入门够用。

5.1.1安装

	sudo apt-get install qemu

5.1.2检测

	qemu-system-arm -M help

5.2 方式2:

	自己编译安装。

6. 测试镜像下载

https://github.com/wanglitao2020/doc
https://gitee.com/wang_litao/doc

linux内核编程-qemu环境搭建_第1张图片

7.qemu启动测试

7.1 zImage启动

touch boot.sh

gedit boot.sh
	qemu-system-arm  \
    -M vexpress-a9 \
    -m 512M \
     -nographic \
    -dtb ./vexpress-v2p-ca9.dtb \
    -kernel ./zImage \
    -append "root=/dev/mmcblk0 rw console=ttyAMA0" \
    -sd rootfs.ext3
    
chmod +x boot.sh

./boot.sh

7.2 zImage 控制台启动

qemu-system-arm  \
-M vexpress-a9 \
-m 512M \
-nographic \
-dtb ./vexpress-v2p-ca9.dtb \
-kernel ./zImage \
-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
-sd rootfs.ext3

7.3 uboot引导启动

安装依赖包

 sudo apt install net-tools
 sudo apt install net-tools uml-utilities bridge-utils

ifconfig 查看网络

ens33:192.168.230.135
ens34:192.168.230.136

修改/etc/network/interfaces文件

auto lo
iface lo inet loopback
auto ens33
​auto br0
iface br0 inet dhcp
bridge_ports ens33

重启网络服务后ifconfig

br0: flags=4163  mtu 1500
inet 192.168.230.135  netmask 255.255.255.0  broadcast 192.168.230.255
    inet6 fe80::20c:29ff:fed7:c2d9  prefixlen 64  scopeid 0x20
    ether 00:0c:29:d7:c2:d9  txqueuelen 1000  (Ethernet)
    RX packets 7614  bytes 925743 (925.7 KB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 7461  bytes 10786796 (10.7 MB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

启动U-boot的脚本如下:

qemu-system-arm  \
    -M vexpress-a9 \
    -m 512M \
    -nographic \
    -kernel ./u-boot \
    -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
    -sd rootfs.ext3

uboot环境设置地址

=> setenv ipaddr 192.168.230.130
=> setenv serverip 192.168.230.135
=> ping 192.168.230.135

主机安装TFTP服务

$ sudo apt-get install tftp-hpa tftpd-hpa xinetd
在Ubuntu下修改配置文件:/etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/wit/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"


sudo mkdir /home/wit/tftpboot
sudo chmod 777 /home/wit/tftpboot
sudo /etc/init.d/tftpd-hpa restart

启动加载

=> setenv ipaddr 192.168.230.130
=> setenv serverip 192.168.230.135
=> tftp 0x60003000 uImage
=> tftp 0x60500000  vexpress-v2p-ca9.dtb
=> bootm 0x60003000 - 0x60500000

7.4自动化引导

下载uboot源码

修改:include/configs/vexpress_common.h:
/*Netmask*/
196 #define CONFIG_IPADDR 192.168.230.130
197 #define CONFIG_NETMASK 255.255.255.0
198 #define CONFIG_SERVERIP 192.168.230.135
安装ARM交叉编译器,并编译u-boot:

安装编译器:

$ sudo apt install gcc-arm-linux-gnueabi gcc make libncurses-dev bison flex

配置

CROSS_COMPILE=arm-linux-gnueabi-
export CROSS_COMPILE
make vexpress_ca9x4_defconfig

make menuconfig 菜单选项配置

在Architecture select选项中选择:ARM architecture

linux内核编程-qemu环境搭建_第2张图片

设置bootcmd命令:

linux内核编程-qemu环境搭建_第3张图片

tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0';bootm 0x60003000 - 0x60500000;

编译

make

运行

u-boot拷贝到/home/wit/tftpboot目录
运行脚本启动u-boot看是否能自动引导uImage启动。

7.5 NFS文件系统

主机配置NFS服务:

sudo apt install nfs-kernel-server
在/etc/exports文件中添加:
 /home/rootfs *(rw,sync,no_root_squash,no_subtree_check)
开启NFS服务:
sudo /etc/init.d/rpcbind restart
sudo /etc/init.d/nfs-kernel-server restart

主机制作文件系统

方式1
	解压nfs.tar.gz

方式2

  重新制作,参考附录

修改bootargs启动参数:

	方式1
	tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/nfs rw nfsroot=192.168.230.135:/home/wit/rootfs,proto=tcp,nfsvers=4,nolock init=/linuxrc ip=192.168.230.130 console=ttyAMA0';bootm 0x60003000 - 0x60500000;
	方式2
	配置uboot 重新编译

内核编译

修改Makefile:ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
make vexpress_defconfig

linux内核编程-qemu环境搭建_第4张图片

 make zImage
 apt install u-boot-tools
 make uImage  LOADADDR=0x60003000
 make dtbs

文件拷贝

将生成的arch/arm/boot/uImage和arch/arm/boot/dts/vexpress-v2p-ca9.dtb拷贝到/home/wit/tftpboot目录下,使用下面的命令启动内核:

qemu-system-arm  \
    -M vexpress-a9 \
    -m 512M \
    -nographic \
    -kernel ./u-boot \
    -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
    -sd rootfs.ext3

附录

制作NFS文件系统

编译busybox

nfs
Linux System Utilities  --->
    [*] mount (30 kb)
        [*]   Support mounting NFS file systems on Linux < 2.6.23

创建rootfs目录

>>mkdir etc
>>cd etc
>>vim inittab

::sysinit:/etc/init.d/rcS        // 执行rcS脚本
#::respawn:-/bin/sh
#tty2::askfirst:-/bin/sh
#::ctrlaltdel:/bin/umount -a -r

console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

>>vim init.d/rcS

#! /bin/sh
PATH=/sbin:/bin:/user/sbin:/usr/bin
LD_LIBRARY_PATH=/lib
export PATH LD_LIBRARY_PATH

mount -a        // 挂载根文件系统 fstab
mkdir -p /dev/pts
mount -t devpts devpts dev/pts
mdev -s
mkdir -p /var/lock
echo "......"

>>vim fstab
 
proc    /proc    proc    defaults    0    0
tmpfs    /tmp    tmpfs    default    0    0
sysfs    /sys    sysfs    default    0    0
tmpfs    /dev    tmpfs    default    0    0
var    /dev    tmpfs    default    0    0
ramfs    /dev    ramfs    default    0    0

>>vim profile

PS1='xiami@vexpress:\w #'
export PS1
也可以在~/.bashrc中修改或设置PS1

启动流程:

Linux内核启动之后,挂载根文件系统
开启init进程,bootargs init=/linuxrc,启动第一个用户进程
在用户进程中读取inittab脚本,

构建其他目录

>> cd rootfs
>>mkdir proc mnt tmp sys root\

制作SD文件系统

下载busybox工具

从https://busybox.net/downloads/下载最新的busybox。
同样,建议在windows系统下使用迅雷下载,先找到合适的busybox版本,再用右键,选择用迅雷下载,这样速度会很快;

解压busybox

tar -xvf busybox-1.31.1.tar.bz2

配置并编译busybox

 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
编译选择使用glibc动态库,因为静态库可能会出现一些未知的问题

>> make menuconfig
Settings  --->
    Build Options  --->
        [ ] Build static binary (no shared libs)
	默认的安装目录是./_install,如果需要指定安装目录,可以在下边修改:
	
Settings  --->
Installation Options ("make install" behavior)
(./_install) Destination path for 'make install'

>> make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

安装

 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install

提示下边信息,表示安装成功:

--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.

查看

>> ls _install/
bin  linuxrc  sbin  usr
或者直接使用CONFIG_PREFIX指定安装目录:

>>make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- CONFIG_PREFIX=/.../rootfs/ install

Tip 提前设置好编译默认值
编译安装过程中,一直输入ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-比较麻烦,可以在Makefile中设置好默认值;

修改Makefile:

>> vim Makefile
ARCH = arm
CROSS_COMPILE = arm-linux-gnueabi-
之后的编译、安装命令就简单了:

>>make
>> make install

创建根目录

将busybox编译生成的_install目录下的文件全部拷贝到根文件系统目标rootfs/目录:

>> mkdir rootfs
# cp /.../busybox-1.29.3/_install/* rootfs/ -rfd
也可以在指定busybox的安装目录直接安装:

# make CONFIG_PREFIX=/.../rootfs/ install

添加glibc库

在根文件系统中添加加载器和动态库:

>> mkdir rootfs/lib
#>>cp /usr/arm-linux-gnueabi/lib/* rootfs/lib/ -rfp

静态创建设备文件

>> mkdir rootfs/dev
>> cd rootfs/dev
>> mknod -m 666 tty1 c 4 1
>> mknod -m 666 tty2 c 4 2
>> mknod -m 666 tty3 c 4 3
>> mknod -m 666 tty4 c 4 4
>> mknod -m 666 console c 5 1
>> mknod -m 666 null c 1 3

制作SD卡文件系统镜像

	生成一个空的SD卡镜像:
		>> dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
		32+0 records in
		32+0 records out
		33554432 bytes (34 MB, 32 MiB) copied, 0.0236764 s, 1.4 GB/s
    将SD卡格式化为exts文件系统:
		mkfs.ext3 rootfs.ext3
		mke2fs 1.42.13 (17-May-2015)
		Discarding device blocks: done                            
		Creating filesystem with 32768 1k blocks and 8192 inodes
		Filesystem UUID: 51ab1063-a137-48e5-a6f4-4552dad3b898
		Superblock backups stored on blocks:
		    8193, 24577
		
		Allocating group tables: done                            
		Writing inode tables: done                            
		Creating journal (4096 blocks): done
		Writing superblocks and filesystem accounting information: done
		
	 将rootfs烧写到SD卡:
		>> sudo mount -t ext3 rootfs.ext3 /mnt -o loop
		>> sudo cp -rf rootfs/* /mnt/
		>> sudo umount /mnt

Tip 在开发过程中,如果需要修改SD卡中的内容,可以将SD卡的镜像rootfs.ext3挂载到/mnt目录下,直接操作/mnt来修改;

	>> sudo mount -t ext3 rootfs.ext3 /mnt -o loop
	>> cp rootfs.ext3 ~/qemu

参考链接

环境搭建
老师博客

你可能感兴趣的:(#,linux综合,#,Android综合,linux,arm开发,嵌入式)