Qemu模拟ARM之制作根文件系统

Qemu模拟ARM之制作根文件系统

系统:Ubuntu16.04.4 32bit
交叉编译器:arm-linux-gnueabihf-gcc
VMware:VMware Workstation 14 Pro
u-boot:u-boot-2018.03
linux:linux-4.16.2

1.下载busybox

官网:https://busybox.net/

cd ~/qemu
wget http://busybox.net/downloads/busybox-1.28.3.tar.bz2

2.配置busybox

tar xvf busybox-1.28.3.tar.bz2
cd busybox-1.28.3
make menuconfig

这里写图片描述
遇到上面错误,由于缺少相应的库导致的

#libncursesw5-dev
sudo apt-get install libncurses5-dev

在这里选择编译编译静态库不依赖与任何动态链接库
Settings —>
这里写图片描述
交叉编译工具链的选择
Settings —>
这里写图片描述
安装目录的选择
Settings —>
这里写图片描述
支持vi风格的命令行
Settings—>
这里写图片描述

3.编译安装

make -j4
make install

4.构建根文件系统

mkdir  ~/qemu/rootfs
cd ~/qemu/rootfs

创建根文件系统的目录

mkdir bin etc dev home lib mnt opt proc root sbin sys tmp usr var

拷贝busybox安装目录下的文件到rootfs中

sudo cp -a ~/qemu/busybox-1.28.3/_install/* ./

拷贝交叉编译器动态库到rootfs/lib目录下

cp -a /opt/gcc-linaro-7.2.1-2017.11-i686_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/* ./lib/

对库文件进行瘦身(去除符号表和调试信息):

arm-linux-gnueabihf-strip ./lib/*

将busybox源码里的etc拷贝到rootfs目录下的etc下

cp -a ~/qemu/busybox-1.28.3/examples/bootfloppy/etc/* ./etc

在dev目录下创建设备节点

sudo mknod -m 666 ./dev/console c 5 1
sudo mknod -m 666 ./dev/null c 5 1

拷贝宿主机/etc/passwd,/etc/group,/etc/shadow到rootfs的etc下

sudo cp /etc/passwd ./etc
sudo cp /etc/group ./etc
sudo cp /etc/shadow ./etc

把passwd文件中的第一行:root:x:0:0:root:/root:/bin/bash中的/bin/bash,改成/bin/sh.因为文件系统的bin目录下没有bash这个命令,而是用sh代替bash,所以在用用户名密码登录时候(如telnet),会出现“cannot run /bin/bash:No such file or directory”的错误。

如果修改目录/root/,那么root用户登陆的时候不会进入root目录下而是进入根目录。


init进程解析的配置文件,通过这个配置文件决定执行哪个进程
修改etc/inittab文件:

内容如下:

console::sysinit:/etc/init.d/rcS
#::respawn:-/bin/sh #之前由于启动了两个sh,所以执行命令是会出错(两个sh抢着执行)
ttyAMA0::askfirst:-/bin/sh #"-"表示该shell为 login shell
::once:/usr/sbin/telnetd -l /bin/login
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r                             
::restart:/sbin/init   
描述
<id> 进程要使用的控制台,不设置则使用和init一样的控制台
<runlevels> 对于Busybox提供init程序,此字段可省略
<action> 表示init进程如何控制该子进程
<process> 要执行的程序或脚本
活动名称 含义
Sysinit 为init程序提供初始化命令脚本的路径
Wait 告诉init程序必须等待相应程序执行完后才能继续执行
Once 程序只执行一次,且不会等待它执行完成
Respawn 当程序终止执行时,重新启动该程序
Askfirst 和respawn类似,不过init程序先输出”Please press Enter to active this console”,等待用户按回车键后,才启动子进程
Shutdown 系统关机时执行相应的程序
Restart 当init程序重启时,执行相应程序,通常是init程序本身
Ctrlatldel 按下Ctrl + Alt + Delete组合键时,执行相应程序

fstab中是存放系统中文件系统的信息,这些信息是用来控制mount命令的行为

要挂载的设备 挂载点 文件系统的类型 挂载参数 dump(备份程序) fsckorder(检查磁盘程序)
proc /proc proc defaults 0 0

修改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
var /dev tmpfs defaults 0 0     

修改etc/init.d/rcS文件(系统最先执行的,也可称为初始化脚本)
内容如下:

#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
mkdir /dev/pts #dev/pts用来支持外部网络连接(telnet)的虚拟终端
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug #设置内核,当有设备插拔时调用/sbin/mdev程序
mdev -s #在/dev目录下生成内核支持所有设备的结点
mkdir -p /var/lock
/bin/hostname -F/etc/sysconfig/HOSTNAME
#设置ip
ifconfig lo 127.0.0.1
ifconfig eth0 192.168.1.222

其中HOSTNAME即命令提示符前面所显示的名字[root@hostname]中的hostname。而在init.d/rcS脚本中/bin/hostname -F /etc/sysconfig/HOSTNAME指定到/etc/sysconfig/HOSTNAME中找这个名称。

所以在/etc下新建sysconfig文件夹,在里面新建HOSTNAME文件,内容为:qemu

umask

  1. umask是022的时候,默认touch创建一个文件的权限是644
  2. umask是044的时候,默认touch创建一个文件的权限是622
  3. umask是444的时候,默认touch创建一个文件的权限是222

Linux系统有7个运行级别(runlevel)

  1. 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
  2. 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
  3. 运行级别2:多用户状态(没有NFS)
  4. 运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
  5. 运行级别4:系统未使用,保留
  6. 运行级别5:X11控制台,登陆后进入图形GUI模式
  7. 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动

运行级别的原理:

  1. 在目录/etc/rc.d/init.d下有许多服务器脚本程序,一般称为服务(service)
  2. 在/etc/rc.d下有7个名为rcN.d的目录,对应系统的7个运行级别
  3. rcN.d目录下都是一些符号链接文件,这些链接文件都指向init.d目录下的service脚本文件,命名规则为K+nn+服务名或S+nn+服务名,其中nn为两位数字。
  4. 系统会根据指定的运行级别进入对应的rcN.d目录,并按照文件名顺序检索目录下的链接文件

    • 对于以K开头的文件,系统将终止对应的服务
    • 对于以S开头的文件,系统将启动对应的服务
  5. 查看运行级别用:runlevel

  6. 进入其它运行级别用:(sudo) init N
  7. 另外init0为关机,init 6为重启系统

另外,当使用runlevel查看运行级别时,结果会显示前一次的运行级别和现在的运行级别,如果前次的运行级别为N,那么说明前次没有运行级别(可能刚刚power on)


修改etc/profile文件(也是个脚本文件,不过是我们按下回车后才执行的)
内容如下:

#sh profile
#vim: syntax=sh

#NO core files by default
#ulimit -S -c 0 > /dev/null 2>&1

USER="'id-un'"  #/*双引号,单引号-单引号,双引号*/
LOGNAME=$USER
PS1='[\u@\h \W]#'
PATH=$PATH

HOSTNAME='/bin/hostname'
echo "Processing /etc/profile..." #这两句可以改成你自己的信息
echo "*******************************************************"
echo "*                                                     *"
echo "*               made by xxxxxxxxxxxx                  *"
echo "*                    2018.4.28                        *"
echo "*                                                     *"
echo "*******************************************************"

export USER LOGNAME PS1 PATH

5.制作ext3文件系统

#生成镜像 count自定文件系统大小这里设置256M
cd ~/qemu
dd if=/dev/zero of=rootfs.ext3 bs=1M count=512
#格式化生成ext3文件系统
mkfs.ext3 rootfs.ext3

#将文件复制到镜像中
sudo mkdir tmpfs
sudo mount -t ext3 rootfs.ext3 tmpfs/ -o loop
sudo cp -r rootfs/* tmpfs/
sudo umount tmpfs

6.测试文件系统

cd ~/qemu/tftpboot

qemu-system-arm -M vexpress-a9 -nographic -kernel u-boot  -net nic,macaddr=52:54:00:11:22:33 -net tap,ifname=tap0,script=no,downscript=no -sd ~/qemu/rootfs.ext3
tftp 0x60003000 uImage

tftp 0x66000000 vexpress-v2p-ca9.dtb

setenv bootargs 'root=/dev/mmcblk0 rw console=ttyAMA0'

bootm 0x60003000 - 0x66000000

这里写图片描述

7.增加登陆界面

在linux启动后首先设置root的登陆密码

#设置密码为root
passwd root

修改/etc/inittab

#删除
ttyAMA0::askfirst:-/bin/sh
#增加
ttyAMA0::respawn:/sbin/getty -L ttyAMA0 115200 vt100

重启后就会出现登陆界面
这里写图片描述

猜你喜欢

转载自blog.csdn.net/wyy626562203/article/details/80115323