一、基于HOST(宿主机)制作一个简单的可启动的linux
1、给目标磁盘分区
两个:
宿主机上:/dev/sdb1,/dev/sdb2
/dev/sdb1挂载至/mnt/boot,/dev/sdb2挂载至/mnt/sysroot
2、安装grub至目标磁盘
# grub-install --root-directory=/mnt /dev/sdb
3、复制内核和initrd文件
# cp /boot/vmlinz-VERSION /mnt/boot/vmlinuz
# cp /boot/initramfs-VERSION.img /mnt/boot/initramfs.img
注意:复制到目标机的文件为方便在这里才没有写版本,建议写版本也要写上
4、创建目标主机的根文件系统
# mkdir -pv /mnt/sysroot/{etc/rc.d,usr,var,proc,sys,dev,lib,lib64,bin,sbin,boot,srv,mnt,media,home,root}
接着移植bash,ls,cat等常用命令至目标主机的根文件系统
5、为grub提供配置文件
# vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title Magedu Little linux
root (hd0,0)
kernel /vmlinuz ro root=/dev/sda2 quiet selinux=0 init=/bin/bash
initrd /initramfs.img
就完成了基于HOST制作一个简单的可启动的linux,将此硬盘拆下安装到别的机器上(因为没有驱动,只能在虚拟机上运行),测试启动
6、用脚本代替/sbin/init
使用脚本替代/sbin/init实现简单的功能:
如打印欢迎信息,以读写方式重新挂载根文件系统,挂载/etc/fstab文件中定义的需要挂载的设备,最后执行/bin/bash
实战:
[root@Note5 ~]# fdisk -l /dev/sdbDisk /dev/sdb: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0xf3b882a4 Device Boot Start End Blocks Id System/dev/sdb1 1 500 4016218+ 83 Linux/dev/sdb2 501 632 1060290 83 Linux[root@Note5 ~]# mkdir /mnt/{boot,sysroot}[root@Note5 ~]# mount /dev/sdb1 /mnt/boot[root@Note5 ~]# mount /dev/sdb2 /mnt/sysroot[root@Note5 ~]# df -THFilesystem Type Size Used Avail Use% Mounted on/dev/sda2 ext4 20G 4.9G 14G 27% /tmpfs tmpfs 981M 0 981M 0% /dev/shm/dev/sda1 ext4 508M 34M 448M 7% /boot/dev/sdc1 ext4 3.0T 211M 2.9T 1% /mnt/dev/sdb1 ext4 4.1G 76M 3.8G 2% /mnt/boot/dev/sdb2 ext4 1.1G 35M 980M 4% /mnt/sysroot[root@Note5 ~]# cp /boot/vmlinuz-2.6.32-431.el6.x86_64 /mnt/boot/vmlinuz[root@Note5 ~]# cp /boot/initramfs-2.6.32-431.el6.x86_64.img /mnt/boot/initramfs[root@Note5 ~]# grub-install --root-directory=/mnt /dev/sdbProbing devices to guess BIOS drives. This may take a long time.Installation finished. No error reported.This is the contents of the device map /mnt/boot/grub/device.map.Check if this is correct or not. If any of the lines is incorrect,fix it and re-run the script `grub-install'.(fd0) /dev/fd0(hd0) /dev/sda(hd1) /dev/sdb(hd2) /dev/sdc[root@Note5 ~]# ls /mnt/bootgrub initramfs lost+found vmlinuz[root@Note3 ~]# vim /mnt/boot/grub/grub.conf[root@Note3 ~]# cat /mnt/boot/grub/grub.conf #boot分区就完成了default=0 timeout=10titile Anyfish Linux root (hd0,0) kernel /vmlinuz ro root=/dev/sda2 quiet selinux=0 init=/bin/bash initrd /initramfs#init=bash指定kernel不再去查询init,直接启动bash,不设置kernel找不到init就会报错,这里quiet不能写在selinue=0或init=/bin/bash之后,否则系统还是会去查找init#下面开始准备根文件系统[root@Note5 ~]# mkdir -pv /mnt/sysroot/{etc/rc.d,usr,var,proc,sys,dev,lib,lib64,bin,sbin,boot,home,mnt}mkdir: 已创建目录 "/mnt/sysroot/etc"mkdir: 已创建目录 "/mnt/sysroot/etc/rc.d"mkdir: 已创建目录 "/mnt/sysroot/usr"mkdir: 已创建目录 "/mnt/sysroot/var"mkdir: 已创建目录 "/mnt/sysroot/proc"mkdir: 已创建目录 "/mnt/sysroot/sys"mkdir: 已创建目录 "/mnt/sysroot/dev"mkdir: 已创建目录 "/mnt/sysroot/lib"mkdir: 已创建目录 "/mnt/sysroot/lib64"mkdir: 已创建目录 "/mnt/sysroot/bin"mkdir: 已创建目录 "/mnt/sysroot/sbin"mkdir: 已创建目录 "/mnt/sysroot/boot"mkdir: 已创建目录 "/mnt/sysroot/home"mkdir: 已创建目录 "/mnt/sysroot/mnt"[root@Note5 ~]# cp /bin/bash /mnt/sysroot/bin[root@Note5 ~]# chroot /mnt/sysrootchroot: failed to run command `/bin/bash': No such file or directory[root@Note3 ~]# ls /mnt/sysroot/bin/bash /mnt/sysroot/bin/bash[root@Note5 ~]# ldd /bin/bash linux-vdso.so.1 => (0x00007fff43b8e000) libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f08cb011000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f08cae0d000) libc.so.6 => /lib64/libc.so.6 (0x00007f08caa78000) /lib64/ld-linux-x86-64.so.2 (0x00007f08cb242000)[root@Note5 ~]# ldd /bin/bash|grep -o '/[[:alnum:]/.-]\+'/lib64/libtinfo.so.5/lib64/libdl.so.2/lib64/libc.so.6/lib64/ld-linux-x86-64.so.2[root@Note5 ~]# for i in `ldd /bin/bash|grep -o '/[[:alnum:]/.-]\+'|cut -d/ -f3`;do cp /lib64/$i /mnt/sysroot/lib64/;done[root@Note3 ~]# ls /mnt/sysroot/lib64/ld-linux-x86-64.so.2 libc.so.6 libdl.so.2 libtinfo.so.5[root@Note5 ~]# chroot /mnt/sysrootbash-4.1# lsbash: ls: command not foundbash-4.1# bash-4.1# quitbash: quit: command not foundbash-4.1# exitexit#这里需要注意:chroot切换根目录的目录下一定要有bin/bash才能切换成功,命令成功运行需要自身依赖的库文件[root@Note5 ~]# cp /bin/ls /bin/cat /mnt/sysroot/bin[root@Note5 ~]# ls /mnt/sysroot/binbash cat ls[root@Note5 ~]# ldd /bin/cat #cat依赖的库文件和bash一样,已经有了 linux-vdso.so.1 => (0x00007fff219ff000) libc.so.6 => /lib64/libc.so.6 (0x00007fcfd1c9b000) /lib64/ld-linux-x86-64.so.2 (0x00007fcfd203f000)[root@Note5 ~]# cp /lib64/libc.so.6 ^C[root@Note5 ~]# ldd /bin/ls linux-vdso.so.1 => (0x00007fffa578d000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fbac4e29000) librt.so.1 => /lib64/librt.so.1 (0x00007fbac4c21000) libcap.so.2 => /lib64/libcap.so.2 (0x00007fbac4a1c000) libacl.so.1 => /lib64/libacl.so.1 (0x00007fbac4814000) libc.so.6 => /lib64/libc.so.6 (0x00007fbac4480000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fbac427b000) /lib64/ld-linux-x86-64.so.2 (0x00007fbac5058000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbac405e000) libattr.so.1 => /lib64/libattr.so.1 (0x00007fbac3e59000)[root@Note5 ~]# for i in `ldd /bin/ls|grep -o '/[[:alnum:]/.-]\+'|cut -d/ -f3`;do cp /lib64/$i /mnt/sysroot/lib64/;donecp:是否覆盖"/mnt/sysroot/lib64/libc.so.6"? ycp:是否覆盖"/mnt/sysroot/lib64/libdl.so.2"? ycp:是否覆盖"/mnt/sysroot/lib64/ld-linux-x86-64.so.2"? y[root@Note5 ~]# ls /mnt/sysroot/lib64ld-linux-x86-64.so.2 libcap.so.2 libpthread.so.0 libtinfo.so.5libacl.so.1 libc.so.6 librt.so.1libattr.so.1 libdl.so.2 libselinux.so.1[root@Note5 ~]# chroot /mnt/sysrootbash-4.1# lsbin dev home lib64 mnt sbin usrboot etc lib lost+found proc sys var
boot + rootfs都完成了,然后新建虚拟机(目标机),使用此硬盘当作启动盘启动(宿主机(也是虚拟机)要关闭,一个硬盘不能同时被2个虚拟机使用)
目标机启动后的界面:
进入系统后的界面:
二、linux的内核模块
lcpci 查看PCI设备的命令
lsmod 查看当前系统加载的模块
modinfo MOD_NAME 查看某模块的详细信息
动态装载某模块:
modprobe MOD_NAME
insmod /path/to/module_file #insmod安装模块,需要指定模块文件的路径
动态卸载某模块:
modprobe -r MOD_NAME
rmmod MOD_NAME
[root@Note3 ~]# ls /libalsa cpp firmware kbd lsb modules security terminfo udev[root@Note3 ~]# cd /lib/modules/[root@Note3 modules]# ls2.6.32-431.el6.x86_64[root@Note3 modules]# cd 2.6.32-431.el6.x86_64/[root@Note3 2.6.32-431.el6.x86_64]# lsbuild modules.dep.bin modules.pcimapextra modules.drm modules.seriomapkernel modules.ieee1394map modules.symbolsmisc modules.inputmap modules.symbols.binmodules.alias modules.isapnpmap modules.usbmapmodules.alias.bin modules.modesetting sourcemodules.block modules.networking updatesmodules.ccwmap modules.ofmap vdsomodules.dep modules.order weak-updates
modules.alias:模块别名的列表
modules.dep.bin:模块间的依赖关系,是使用depmod命令生成的
[root@Note3 2.6.32-431.el6.x86_64]# ls kernel/arch crypto drivers fs kernel lib mm net sound
arch:硬件平台架构
crypto:常用的加密算法
drivers:硬件驱动
fs:文件系统
通过上面的命令学习就可以把宿主机上的模块文件也复制到目标机上,增加目标机的功能
例如:复制宿主机上的e1000网卡驱动模块到目标机上,实现目标机的联网功能
#宿主机上为目标机添加e1000的驱动模块,ping,ifconfig,insmode,rmmode,modprobe命令[root@Node5 ~]# mkdir -v /mnt/sysroot/lib/modulesmkdir: created directory `/mnt/sysroot/lib/modules'[root@Node5 ~]# cp /lib/modules/2.6.32-431.el6.x86_64/kernel/drivers/net/e1000/e1000.ko /mnt/sysroot/lib/modules[root@Node5 ~]# ls /mnt/sysroot/lib/modulese1000.ko[root@Node5 ~]# ldd /sbin/ifconfig linux-vdso.so.1 => (0x00007fff123d9000) libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003da1200000) libc.so.6 => /lib64/libc.so.6 (0x0000003d9fa00000) libdl.so.2 => /lib64/libdl.so.2 (0x0000003d9f600000) /lib64/ld-linux-x86-64.so.2 (0x0000003d9f200000)[root@Node5 ~]# cp /sbin/ifconfig /mnt/sysroot/sbin/[root@Node5 ~]# ls /mnt/sysroot/sbin/ifconfig[root@Node5 ~]# ls /mnt/sysroot/lib64 #ifconfig命令所需的库文件都有ld-linux-x86-64.so.2 libcap.so.2 libpthread.so.0 libtinfo.so.5libacl.so.1 libc.so.6 librt.so.1libattr.so.1 libdl.so.2 libselinux.so.1[root@Node5 ~]# ldd /bin/ping linux-vdso.so.1 => (0x00007fff9f5ff000) libidn.so.11 => /lib64/libidn.so.11 (0x00007f3d275b5000) libc.so.6 => /lib64/libc.so.6 (0x00007f3d27221000) /lib64/ld-linux-x86-64.so.2 (0x0000003d9f200000)[root@Node5 ~]# ls /mnt/sysroot/lib64ld-linux-x86-64.so.2 libcap.so.2 libpthread.so.0 libtinfo.so.5libacl.so.1 libc.so.6 librt.so.1libattr.so.1 libdl.so.2 libselinux.so.1[root@Node5 ~]# cp /lib64/libidn.so.11 /mnt/sysroot/lib64[root@Node5 ~]# cp /bin/ping /mnt/sysroot/bin/[root@Node5 ~]# cp /sbin/{insmod,rmmod,modprobe} /mnt/sysroot/sbin[root@Node5 ~]# ls /mnt/sysroot/sbinifconfig insmod modprobe rmmod
启动目标机:
可以看到没装载网卡驱动的时候eth0是没有显示的
modeprobe装载模块只需指定模块名,不需要指定模块文件的路径但需要环境支持,所以这里我们使用insmod命令装载网卡驱动模块。
三、定制最小化的内核
上一个实验中,使用的是宿主机的内核,这次我们使用make allnoconfig + 所需要的功能,定制一个最小化的内核。
步骤和上一个实验一样,就不重复了,只是内核配置不同:
# make allnoconfig# make menuconfig #使用make allconfig编译完成后生成.config文件后,再在.config配置文件基础上使用make menuconfig配置所需的cpu、总线、存储的驱动,网络功能,网卡驱动;文件系统和可执行文件格式驱动;IO驱动,USB驱动;启用devtmpfs功能# make bzImage #仅编译压缩格式的内核核心,不编译模块 [root@Node5 linux]# cp arch/x86/boot/bzImage /mnt/boot #将生成的内核文件复制到/mnt/boot/目录下
四、利用busybox构建根文件系统
系统启动历程:
POST-->Boot Sequence(MBR)+BootLoader + kernel(initramfs(initrd)) + /sbin/init(/etc/inittab + /etc/init/*.conf)
/sbin/init
设定默认系统级别
系统初始化:rc.sysinit
启动级别下的服务(rcN.d)所有已S开头的脚本,关闭所有K开头的服务
s99 --> /etc/rc.d/rc.local
启动虚拟终端(login)
启动图形终端
1、busybox简介
busybox:繁忙的盒子
包括shell,init,getty,login
BusyBox 是一个集成了一百多个最常用linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士×××。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了Android系统的自带的shell。
BusyBox 最初是由 Bruce Perens 在 1996 年为Debian GNU/Linux安装盘编写的。其目标是在一张软盘上创建一个可引导的 GNU/Linux 系统,这可以用作安装盘和急救盘。
2、busybox编译
编译安装busybox
# make menuconfig # 这里需要选上静态编译(需要先安装glibc-static)# make # make install
dropbear
1、编译文件并移植
2、生成密钥文件
3、提供devpts文件系统
4、nsswatich
5、安全shell
大体步骤:
1、准备目标磁盘
2、提供bzymage
3、提供busybox
建议静态编译
4、准备根文件系统
复制编译安装完成的busybox
补全所需要的其他目录
5、为init提供配置文件
/etc/inittab
/etc/rc.d/rc.sysinit
6、提供虚拟终端,同时体统帐号密钥等文件
7、主机名和banner
8、提供ssh服务
9、提供nginx服务