1、自制linux系统
[root@centos6 app]#lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 5.8G 0 rom
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 48.8G 0 part /
├─sda3 8:3 0 48.8G 0 part /app
├─sda4 8:4 0 1K 0 part
└─sda5 8:5 0 4G 0 part
sdb 8:16 0 20G 0 disk ---准备一个20G 的干净的磁盘
[root@centos6 app]#fdisk /dev/sdb ---创建两个分区
[root@centos6 app]#lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 5.8G 0 rom
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 48.8G 0 part /
├─sda3 8:3 0 48.8G 0 part /app
├─sda4 8:4 0 1K 0 part
└─sda5 8:5 0 4G 0 part
sdb 8:16 0 20G 0 disk
├─sdb1 8:17 0 1G 0 part ---存放boot
└─sdb2 8:18 0 19G 0 part -----用于存放根
[root@centos6 app]#mkfs.ext4 /dev/sdb1
[root@centos6 app]#mkfs.ext4 /dev/sdb2
[root@centos6 app]#blkid ---在两个分区上创建文件系统
/dev/sda2: UUID="6350f737-89cd-4f10-b687-13672099dae5" TYPE="ext4"
/dev/sda1: UUID="bdfd5835-10c1-4a83-ac25-710153002d1e" TYPE="ext4"
/dev/sda3: UUID="388cdbbd-3813-412d-8748-51924f774474" TYPE="ext4"
/dev/sda5: UUID="c8b816ab-a2f2-4d18-9f91-b50794a91cef" TYPE="swap"
/dev/sdb1: UUID="fc122ac3-61a2-44bc-b599-375cb739ace5" TYPE="ext4"
/dev/sdb2: UUID="9489a316-3cce-4787-a79d-c9f7cdeab3fe" TYPE="ext4"
[root@centos6 app]#mkdir /mnt/boot ---创建一个临时目录,注意子目录必须为boot
[root@centos6 app]#mount /dev/sdb1 /mnt/boot/ ---挂载
[root@centos6 app]#df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 50264772 1035892 46668880 3% /
/dev/sda1 999320 34668 912224 4% /boot
/dev/sda3 50264772 53208 47651564 1% /app
/dev/sdb1 1010780 1304 956464 1% /mnt/boot
[root@centos6 app]#grub-install --root-directory=/mnt /dev/sdb
---安装grub,安装时要指明根所在的目录,安装grub时boot是根
[root@centos6 app]#cp /boot/vmlinuz-2.6.32-696.el6.x86_64 /boot/initramfs-2.6.32-696.el6.x86_64.img /mnt/boot/ ---将内核文件和inintrd文件拷贝到/mnt/boot/目录下
[root@centos6 app]#cd /mnt/boot/
[root@centos6 boot]#ls ---文件已经拷贝过
grub lost+found
initramfs-2.6.32-696.el6.x86_64.img vmlinuz-2.6.32-696.el6.x86_64
[root@centos6 boot]#cd grub/
[root@centos6 grub]#ls ---grub文件已经生成
device.map iso9660_stage1_5 stage1 xfs_stage1_5
e2fs_stage1_5 jfs_stage1_5 stage2
fat_stage1_5 minix_stage1_5 ufs2_stage1_5
ffs_stage1_5 reiserfs_stage1_5 vstafs_stage1_5
[root@centos6 grub]#vim grub.conf ---编辑grub.conf文件
default=0
timeout=5
title zhanglinux
root (hd0,0)
kernel /vmlinuz-2.6.32-696.el6.x86_64 root=/dev/sda2 selinux=0 init=/bin/bash ---定义根下的一个程序是/bin/bash
initrd /initramfs-2.6.32-696.el6.x86_64.img
[root@centos6 grub]#mkdir /mnt/sysroot ---创建一个根的临时目录
[root@centos6 grub]#mount /dev/sdb2 /mnt/sysroot/ ---将根挂载到这个目录下
[root@centos6 grub]#df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 50264772 1035916 46668856 3% /
/dev/sda1 999320 34668 912224 4% /boot
/dev/sda3 50264772 53208 47651564 1% /app
/dev/sdb1 1010780 31360 926408 4% /mnt/boot
/dev/sdb2 19460816 44992 18420600 1% /mnt/sysroot
[root@centos6 grub]#cd /mnt/sysroot/ ---进入根目录
[root@centos6 sysroot]#ls ---现在里面什么都没有
lost+found
[root@centos6 sysroot]#cat copycmd.sh ---下一步就是运行这个脚
本,将一些外部命令的文件和所依赖的库文件拷贝到/mnt/sysroot/目
录下
#!/bin/bash
#
read -p "please input a excute cmd(eg:cat|bash|quit):" command
[ -a /mnt/sysroot ]||mkdir /mnt/sysroot &>/dev/null
cpdir () {
cmd=`which --skip-alias $command`
if [ -f /mnt/sysroot$cmd ];then
echo "the $cmd has been cp before"
else
local dir=`dirname $cmd`
mkdir -p /mnt/sysroot$dir
cp $cmd /mnt/sysroot$cmd
echo "cp $cmd finished"
fi
}
cplib () {
cmd=`which --skip-alias $command`
ldd $cmd |egrep -o "/lib64.* "|while read i;do
if [ ! -f /mnt/sysroot$i ];then
local dir=`dirname $i`
mkdir -p /mnt/sysroot$dir
cp $i /mnt/sysroot$i
echo "cp $i finished"
else
echo "$i has been cp before"
fi
done
}
type $command&>/dev/null||{ echo the command is not exsit;exit 100; }
until [ $command == quit ];do
type $command&>/dev/null||{ echo the command is not exsit;exit 100; }
cpdir
cplib
read -p "please input new excute cmd(eg:cat|bash|quit):" command
cmd=`which --skip-alias $command`
done
利用以上脚本将常用的外部命令的文件和所依赖的库文件拷贝根目录
下,如bash,ls,ifconfig,ping,hostname,cat,mount,
umount,ps,pstree,这样自制的linux系统就可以在bash里面执行
这行命令。
为了让自制的linux系统具有网络功能,需要利用脚本将安装网卡驱动模块的命令的文件和所依赖的库文件拷贝到根目录下,这个命令是
insmod
[root@centos6 sysroot]#modinfo e1000 ---查看驱动模块信息
filename: /lib/modules/2.6.32-696.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
可以知道这个模块来自于哪个文件
[root@centos6 sysroot]#cp /lib/modules/2.6.32-696.el6.x86_64/kernel/drivers/net/e1000/e1000.ko lib64/
复制这个模块文件到lib64目录下
[root@centos6 sysroot]#tree --查看一下目录树,看看是否所有的
文件都已经拷贝完成
.
├── bin
│ ├── bash
│ ├── cat
│ ├── hostname
│ ├── ls
│ ├── mount
│ ├── ping
│ ├── ps
│ └── umount
├── lib64
│ ├── e1000.ko
│ ├── ld-linux-x86-64.so.2
│ ├── libacl.so.1
│ ├── libattr.so.1
│ ├── libblkid.so.1
│ ├── libcap.so.2
│ ├── libcrypt.so.1
│ ├── libc.so.6
│ ├── libdl.so.2
│ ├── libfreebl3.so
│ ├── libidn.so.11
│ ├── libm.so.6
│ ├── libnsl.so.1
│ ├── libproc-3.2.8.so
│ ├── libpthread.so.0
│ ├── libresolv.so.2
│ ├── librt.so.1
│ ├── libselinux.so.1
│ ├── libsepol.so.1
│ ├── libtinfo.so.5
│ ├── libutil.so.1
│ ├── libuuid.so.1
│ └── perl5
│ └── CORE
├── lost+found
├── sbin
│ ├── ifconfig
│ └── insmod
└── usr
└── bin
├── pstree
└── vim
8 directories, 34 files
[root@centos6 sysroot]#mkdir {etc,dec,proc,sys,boot,home,var,root,mnt,tmp,lib} ----创建根下对应
的目录
[root@centos6 sysroot]#ls
bin dec home lib64 mnt root sys usr
boot etc lib lost+found proc sbin tmp var
[root@centos6 sysroot]#chroot /mnt/sysroot/ ---切换根看一下
[I have no name!@centos6 /]#ls ---看到根下的目录都准备好了
bin dec home lib64 mnt root sys usr
boot etc lib lost+found proc sbin tmp var
[I have no name!@centos6 /]#pwd
/
[I have no name!@centos6 /]#sync
bash: sync: command not found
[I have no name!@centos6 /]#exit --退出来
exit
[root@centos6 sysroot]#sync ---同步一下磁盘,确保刚才的操作都
写到磁盘里了
[root@centos6 sysroot]#sync
[root@centos6 sysroot]#sync
[root@centos6 sysroot]#halt ---关机后把sdb这块硬盘拆下来
在vmware里新创建一个虚拟机,然后将这
块硬盘装载到这个虚拟机下,执行情况如
下图
开启此虚拟机
到此一个小的自制的linux系统就完成了,也可以在bash下输入一些命令使用了。
2、/proc目录和/sys目录
- /proc目录:
内核把自己内部状态信息及统计信息,以及可配置参数通
过proc伪文件系统加以输出
/proc/sys
sysctl命令用于查看或设定此目录中诸多参数
[root@centos6 ~]#cat /proc/sys/net/ipv4/icmp_echo_ignore_all
---查看是否禁ping,0是没有开启,1是开启禁ping
0
[root@centos6 ~]#cat /proc/sys/net/ipv4/ip_forward ---查看是否开
启路由功能,0表示没有开启,1是开启
0
[root@centos6 ~]#echo 1 > /proc/sys/net/ipv4/ip_forward ---通过
echo重定向的方法可以开启路由功能
[root@centos6 ~]#cat /proc/sys/net/ipv4/ip_forward
1
[root@centos6 ~]#sysctl -w net.ipv4.ip_forward=0---也可以用sysctl
命令去查看或设定此/proc/sys目录中的诸多参数,格式要注意,中间
是用点隔开,而不是/,并且前面的/proc/sys/也不用谢
net.ipv4.ip_forward = 0
[root@centos6 ~]#cat /proc/sys/net/ipv4/ip_forward
0
以上两种方法设置/proc/sys目录中的诸多参数都是临时设定,重启就
会丢失,要想不丢失,需要写到配置文件里
配置文件是 /etc/sysctl.conf ---可以修改配置文件的内容来修
改/proc/sys目录中的诸多参数,如果这个参数没有,可以在里面增加
一行就可以了
[root@centos6 ~]#sysctl -p ---读取配置文件设置的参数,也即是让
配置文件生效
[root@centos6 ~]#sysctl -a |grep net.ipv4.ip_forward ---查看所有生
效的参数,可以用grep过滤一下,只看某个修改的参数
[root@centos6 ~]#free
total used free shared buffers cached
Mem: 1004112 141764 862348 252 312 8508
-/+ buffers/cache: 132944 871168
Swap: 0 0 0
[root@centos6 ~]#echo 1 > /proc/sys/vm/drop_caches ---0表示不
释放缓存,可以用这种方式释放缓存,只是释放了一部分
[root@centos6 ~]#free -h
total used free shared buffers cached
Mem: 980M 138M 841M 252K 304K 8.3M
-/+ buffers/cache: 130M 850M
Swap: 0B 0B 0B
[root@centos6 ~]#sysctl -a |grep "fs.file"
fs.file-nr = 544 0 96220
fs.file-max = 96220 ---生产中有的时候也会修改这个参数,表示系
统允许同时打开的文件个数,这个文件在
[root@centos6 ~]#cat /proc/sys/fs/file-max
96220
[root@centos6 ~]#cat /etc/sysctl.conf ---配置文件中的这两行有的时
候也需要更改
# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736 --表示系统允许利用的最大内存,如
果企业里面用的是128G的内存,就会造成内存空间的浪费,空有硬
件而利用不起来,所以根据服务器的硬件配置更改这个参数
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296 ---表示允许利用的最大内存的页数,
内存空间是分页的,一页是4k大小。
- /sys目录
此目录用于输出内核识别出的各种硬件设备的相关属性信息。
/sys目录:
sysfs:为用户使用的伪文件系统,输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性的设定信息;有些参数是可以修改的,用于调整硬件工作特性
udev通过此路径下输出的信息动态为各设备创建所需要设备文件,udev是运行用户空间程序
专用工具:udevadmin, hotplug
udev为设备创建设备文件时,会读取其事先定义好的规则文件,一般在/etc/udev/rules.d及/usr/lib/udev/rules.d目录下
比如更改usb设备的名称,系统在usb插入的时候会自动识别出设备名,我们可以定义一个规则文件,去修改usb设备的设备名
修改文件的格式如下图
[root@centos6 ~]#udevadm trigger ---让上面的文件生效
[root@centos6 ~]#ll /dev/wangusb ---可以看到软链接已经建好了
lrwxrwxrwx. 1 root root 5 Sep 2 21:04 /dev/wangusb -> myusb
此时如果插入一个usb设备,就会被识别为设备名为myusb。
3、源码编译安装内核
- 内核编译
单内核体系设计、但充分借鉴了微内核设计体系的优点,为内核引入模块化机制
内核组成部分:
kernel: 内核核心,一般为bzImage,通常在/boot目录下,名称为vmlinuz-VERSION-RELEASE
kernel object: 内核对象,一般放置于
/lib/modules/VERSION-RELEASE/
也就是说用rpm方式安装的内核包,生成的文件一个是内核文件,另一部分文件存放在/lib/modules/目录下
make menuconfig 可以配置内核选项,哪些功能启用,哪些功能不启用
[ ]: N ---表示不启用
[M]: M ---表示启用的功能存放在/lib/modules/目录下
[*]: Y --表示启用的功能写到内核文件vmlinuz-uname-r
中
/boot/config-2.6.32-696.el6.x86_64
这个文件中规定了哪些内核选项功能启用,哪些不启用,启用时是到内核文件中还是保存到/lib/modules/目录下
CONFIG_CRC_T10DIF=m ---表示启用并存放在/lib/modules/目录下
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y ---启用并写在内核文件中
# CONFIG_CRC32_SELFTEST is not set ---表示不启用
CONFIG_CRC7=m
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_LZO_COMPRESS=m
辅助文件:ramdisk
initrd
initramfs
- 内核模块命令
lsmod命令:
显示由核心已经装载的内核模块,显示的是已经加载的模块
显示的内容来自于: /proc/modules文件
modinfo命令:
显示模块的详细描述信息
modinfo[ -k kernel ] [ modulename|filename... ]
-n: 只显示模块文件路径
-p: 显示模块参数
-a: author
-d: description
-l: license
[root@centos6 boot]#lsmod ---显示已经加载的模块
[root@centos6 boot]#modinfo e1000 ---显示模块信息,没有加载的
也会显示,只要有这个模块
[root@centos6 boot]#modinfo -n e1000 ---显示模块文件的路径
/lib/modules/2.6.32-696.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
modprobe ---装载模块
moprobe -r ---卸载模块
insmod命令:也可以装载模块,不自动解决依赖模块,假如这个模块
依赖于别的模块,也只会安装这一个模块,不会安装它依赖的模块,
而modprobe不同,它会解决依赖性,如果发现要安装的模块依赖于
某个模块,它会自动解决依赖性,去把依赖的模块和这个模块都安装
了
命令的是后面跟模块文件的路径而不是模块的名称
lnsmod /lib/modules/2.6.32-696.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
rmmod命令:也可以卸载模块
rmmod e1000
- 编译安装过程
安装开发包组
下载源码文件
.config:准备文本配置文件
make menuconfig:配置内核选项
make [-j #]
make modules_install:安装模块
make install :安装内核相关文件
安装bzImage为/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
编辑grub的配置文件
实例
[root@redhat7 app]#ls
f1 linux-4.12.10.tar.xz reset.sh scp.sh script ssh1.exp
[root@redhat7 app]#tar xf linux-4.12.10.tar.xz ---解包
[root@redhat7 app]#ls
f1 linux-4.12.10 linux-4.12.10.tar.xz reset.sh scp.sh script ssh1.exp
[root@redhat7 app]#cd linux-4.12.10/ ---进入这个目录
[root@redhat7 linux-4.12.10]#ls
arch crypto include kernel net sound
block Documentation init lib README tools
certs drivers ipc MAINTAINERS samples usr
COPYING firmware Kbuild Makefile scripts virt
CREDITS fs Kconfig mm security
[root@redhat7 linux-4.12.10]#cp /boot/config-3.10.0-693.el7.x86_64 .config
---准备.conf文件,可以从/boot目录中拷
贝,也就是在原有的基础上修改,也可以
不准备这个文件,直接执行make
menuconfig自己配置内核选项
[root@redhat7 linux-4.12.10]#ls -a
. CREDITS .gitignore .mailmap security
.. crypto include MAINTAINERS sound
arch Documentation init Makefile tools
block drivers ipc mm usr
certs firmware Kbuild net virt
.cocciconfig fs Kconfig README
.config .get_maintainer.ignore kernel samples
COPYING .gitattributes lib scripts
[root@redhat7 linux-4.12.10]#yum groupinstall "Development Tools"
---安装开发包组
[root@redhat7 linux-4.12.10]#yum install ncurses-devel ---安装这个包
[root@redhat7 linux-4.12.10]#make menuconfig 配置内核选项
进入如下图界面,进行选择内核选项
设置内核编译者自己加的版本号
返回进入修改文件系统,我们是想让编译的新内核也支持NTFS文件系统,目前的内核是不支持的
将这一项打成M,表示支持NTFS文件系统,并保存至/lib/modules目录下,这里选择的时候按y、m、n进行选择
退出保存即可
[root@centos6 linux-4.12.10]#vim .config
搜索一下NTFS,看这一项是否已经被修改
5205 CONFIG_NTFS_FS=m --发现已经被修改
5206 # CONFIG_NTFS_DEBUG is not set
5207 CONFIG_NTFS_RW=y
5208
[root@centos6 linux-4.12.10]#make -j 4 && echo -e '\a' ---表示4颗
cpu并行运行
安装,并且安装完后发出声音
[root@centos6 linux-4.12.10]#yum install openssl-devel ---安装的
时候会提示安装
这个包,安装后再执行以下上面的命令即
可
[root@centos6 linux-4.12.10]#make -j 4 && echo -e '\a' ---发现可以
继续安装了,安装过程比较长
[root@centos6 linux-4.12.10]#make modules_install ---安装模块
[root@centos6 linux-4.12.10]#make install ---安装内核相关文件
重启后就可以用新安装的内核了。
- 在已经执行过编译操作的内核源码树做重新编译
需要事先清理操作:
make clean:清理大多数编译生成的文件,但会保留config文件等
make mrproper: 清理所有编译生成的文件、config及某些备份文件
make distclean:mrproper、patches以及编辑器备份文件 - 卸载内核
删除/lib/modules/目录下不需要的内核库文件
删除/app/ linux-4.12.10/这个目录
删除/boot目录下启动的内核和内核映像文件
更改grub的配置文件,删除不需要的内核启动列表