自制小型linux系统
分析得知:
- 引导grub,内核和initramfs三样不可缺乏。
- 执行的第一个进程/sbin/init由于须要的配置文件太多也不必,咱们能够直接进入系统后第一个进程改成bash shell(让/sbin/init指向它)
- 安装(拷贝)须要的软件程序到这个linux系统中(包括它须要的库文件等),这样一个简单的liunx系统便完成了。
具体步骤
- 分区并建立文件系统
fdisk /dev/sdb
分两个必要的分区
/dev/sdb1对应/boot /dev/sdb2对应根 /
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
(mkswap /dev/sdb3)
- 挂载boot
mkdir /mnt/boot
- 子目录的目录名必须为boot,父目录没要求但下面要指明父目录(由于要用--root,详细查看man帮助grub)
mount /dev/sdb1 /mnt/boot (能够不挂载根/dev/sdb2)
- 安装grub
grub-install --root-directory=/mnt /dev/sdb
- 恢复内核和initramfs文件
- 也能够kernel安装包安装,rpm --root=/dev/sdb2 --nodeps,不过这样会没有initramfs文件,由于脚本会执行错误,因此还得手动生成它,不如直接拷贝
- 或者更好的方法是yum --installroot=/dev/sdb2 install kernel.x86_64 ,前提是配置了yum源,这样作不只能装好根和initramfs等,还能建立好许多必要的文件夹。
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/
cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot
- 创建grub.conf
vim /mnt/boot/grub/grub.conf
- 注意有细微的几项差异,以及注意了在这里写的root是sda2(虽然当前是sdb2,可是拆掉此设备到其余机器上时就是sda2了)
title simple_linux
root (hd0,0)
kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2
selinux=0 :selinux关闭
init=/bin/bash :指定bash
initrd /initramfs-2.6.32-642.el6.x86_64.img
chroot /mnt/sysroot
- 建立一级目录
mkdir /mnt/sysroot
mount /dev/sdb2 /mnt/sysroot
mkdir –pv /mnt/sysroot/{etc,lib,lib64,bin,sbin,tmp,var,usr,sys,proc,opt,home,root,boot,dev,mnt,media}
- 复制bash和相关库文件(利用编写的cpcmd脚本)
- 复制相关命令及相关库文件
如:ifconfig,insmod,ping,mount,ls,cat,df,lsblk,blkid等
- 注意复制的时候也是要建立一个文件夹,而后把未来要做为根分区的分区(sdb2)挂载上去,而后把cpcmd脚本中的目标目录改成此文件夹,进行拷贝便可。
- 固然最好仍是用busybox。
注意点
- 仍是用yum安装内核的方式比较好,由于它会把全部的模块也给安装上,这样的话网络功能也可以启用,只须要进入bash shell以后把网络驱动给载入便可(能够尝试下用init启动)。
- insmod e1000.ko 命令来加载模块,注意要提早拷贝这个模块。
- 若是想要开机以后能把除了根以外的boot分区挂载上(包括其余分区),以及启动网络功能进行各类初始化操做。能够直接在grub.conf中的init=/bin/bash中本身写一个bash脚本,而后添加上各类初始化设置,让init指向它便可(固然也要把本来的bash给添加到这个脚本里面,就至关于再原来的bash脚本基础上增添一些操做)
内核编译
单内核体系设计、但充分借鉴了微内核设计体系的优势,为内核引入模块化机制node
- 内核组成部分:
kernel:内核核心,通常为bzImage,一般在/boot目录下名称为 vmlinuz-VERSION-RELEASE
kernel object:内核对象,通常放置于/lib/modules/VERSION-RELEASE/
[ ]: N :表明不启用此功能
[M]: M :启用此功能可是会把模块放在lib/modules中
[*]: Y :启用功能并将模块放在vmlinuz中
- 辅助文件:ramdisk
initrd
initramfs
前提:
(1) 准备好开发环境
(2) 获取目标主机上硬件设备的相关信息
(3) 获取目标主机系统功能的相关信息
例如:须要启用相应的文件系统
(4) 获取内核源代码包
www.kernel.orglinux
开发环境准备
- 包组
Development Tools
- 目标主机硬件设备相关信息
CPU:
cat /proc/cpuinfo
x86info -a
lscpu
硬件设备
- PCI设备:
lspci
-v
-vv
lsusb
-v
-vv
lsblk 块设备
- 了解所有硬件设备信息
hal-device:CentOS 6
安装系统
安装开发包组
下载源码文件
.config:准备文本配置文件
make menuconfig:配置内核选项
make [-j #]
make modules_install:安装模块
make install :安装内核相关文件
安装bzImage为/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
编辑grub的配置文件c++
编译内核示例
tar xf linux-VERSION.tar.xz -C /usr/src
cd /usr/src
#n -sv linux-4.20.2 linux
cd /usr/src/linux-VERSION
cp /boot/config-$(uname -r) ./.config
make help
make menuconfig :须要安装一些包才能执行此命令
make -j 2
make modules_install
make install
reboot
编译内核
-
配置内核选项
支持“更新”模式进行配置:make help
(a) make config:基于命令行以遍历的方式配置内核中可配置的每一个选项
(b) make menuconfig:基于curses的文本窗口界面
(c) make gconfig:基于GTK (GNOME)环境窗口界面
(d) make xconfig:基于QT(KDE)环境的窗口界面
支持“全新配置”模式进行配置
(a) make defconfig:基于内核为目标平台提供的“默认”配置进行配置
(b) make allyesconfig: 全部选项均回答为“yes“
(c) make allnoconfig: 全部选项均回答为“no“shell
- 编译
全编译:make [-j #]
编译内核的一部分功能:
(a) 只编译某子目录中的相关代码
cd /usr/src/linux
make dir/
(b) 只编译一个特定的模块
cd /usr/src/linux
make dir/file.ko
示例:只为e1000编译驱动:
make drivers/net/ethernet/intel/e1000/e1000.ko
如何交叉编译内核:
编译的目标平台与当前平台不相同
make ARCH=arch_namevim
- 要获取特定目标平台的使用帮助
make ARCH=arch_name help
示例:
make ARCH=arm help
在已经执行过编译操做的内核源码树作从新编译
须要事先清理操做:
make clean:清理大多数编译生成的文件,但会保留config文件等
make mrproper: 清理全部编译生成的文件、 config及某些备份文件
make distclean:mrproper、清理patches以及编辑器备份文件bash
卸载内核
删除/lib/modules/目录下不须要的内核(对应内核的module)库文件
(删除/usr/src/linux/目录下不须要的内核源码:根据本身装的源码位置来删除)
删除/boot目录下启动的内核和内核映像文件
更改grub的配置文件,删除不须要的内核启动列表(6中手写title的项目删除,而7中在完成了前面步骤以后直接grub2-mkconfig从新生成就会自动删除掉去掉的内核项)网络
注意点:
- 内核由于配置项太多,所以用菜单模式来选择。咱们能够参考已有的文本配置文件来生成菜单并进行修改。
- 这个已有的文本配置文件就是在已经编译安装好的linux内核中boot文件夹中的config_VERSION文件
- 其中y表明打入内核,m表明模块中,not set并注释就表明没有启动此功能。
- 将此已经存在的配置文件拷贝并命名为.config做为参考来执行下一步的make menuconfig
- 本身编译内核可将NTFS文件系统功能给启用,修改的时候用菜单方式修改(须要利用1中说的参考的文本配置文件,否则项目太多一个一个改也麻烦也不现实)
- 安装时分为安装模块和安装内核两步。
- 一个linux系统中能够同时装多个内核,所以直接编译安装新内核便可。
- 以前作过rpm安装内核包的实验,boot中会出现两个内核文件和相对应的initramfs.img,以及lib/modules中也会出现两个内核版本文件夹。
- 开机的时候选择载入哪一个内核便可,(若是是手动添加的内核,固然这须要修改grub.conf中的设置,新加一个title便可。用命令make modules_install和make install命令添加的自动就会添加到grub.conf(或grub.cfg)文件中)
- make menuconfig须要安装一些依赖的包才能执行,根据提示一个一个装
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel
openssl openssl-devel systemd-devel zlib-devel vim lrzsz tree screen lsof tcpdump wget ntpdate net-tools iotop bc zip unzip nfs-utils
- menu通用设置中的local version能够本身书写一下,其中写的就是内核中前面主版本号后面写的内容。注意最开头处加上横杠-比较好,好比-myversion-1.0.
- 修改须要修改的项目好比NTFS以后保存,而后就会修改掉.config文件。以后便会根据它进行编译。能够查看一下它是否确实修改了。
- 以后make -j N && echo -e "\a"进行编译 便可(最好session或者nohup).若是报错须要某些文件包则先装好,而后再尝试。
- 若是只为了NTFS,NTFS文件格式的支持在epel源中有包能够进行操做。会多一个mount.ntfs命令,对NTFS格式文件系统的分区进行挂载以后即可可读可写。
Busybox
定制小型的Linux操做系统:linux内核+busybox(安卓手机就是相似如此)
官方网站:https://busybox.net/
busybox命令可能选项比较少,不过也基本够用。同时它还集成了库文件,不用再另外安装拷贝了。session
Busybox使用
busybox 的编译过程与Linux内核的编译相似
busybox的使用有三种方式:tcp
- busybox后直接跟命令,如 busybox ls
- 直接将busybox重命名,如 cp busybox tar
- 建立符号连接,如 ln -s busybox rm
busybox的安装
以上方法中,第三种方法最方便,但为busybox中每一个命令都建立一个软连接,至关费事,busybox提供自动方法:busybox编译成功后,执行make install,则会产生一个_install目录,其中包含了busybox及每一个命令的软连接编辑器
编译Busybox
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel libmcrypt-devel glibc-static ncurses-devel
wget https://busybox.net/downloads/busybox-1.30.0.tar.bz2
tar xvf busybox-1.30.0.tar.bz2
cd busybox-1.30.0/
make menuconfig
- 注意,在menu中按下面选择,把busybox编译成静态二进制、不用共享库,这样的话这些二进制文件所须要的库文件就会被打包集成在busybox中了而不是在当前操做系统的lib中
- busybox自己就是一个程序,只不过功能众多而已,被视为多个程序的组合。实质上就是一个程序,要理解静态编译在这里的做用)
- 此时直接拷贝在其它机器上这个busybox也能执行了:
Busybox Settings -->Build Options -->[*] Build BusyBox as a static binary (no shared libs)
而后继续下面命令
make :只生成二进制文件不生成软连接
make install :把软连接也生成,之后执行命令就方便了
- 若是出错,执行make clean后,从新执行上面命令
mkdir /mnt/sysroot/
cp -a _install/* /mnt/sysroot/ :真正的busybox就在_install/bin/busybox 其余的在此目录内的命令都是软连接
Busybox也可直接下载编译好的二进制,在官网上有。