在上次的话题中我们通过安装引导MBR与移植主要二进制文件(bash),完成了
最基础的linux内核定制初步的工作,至此我们也可以总结一下linux的启动流程
为接下来的更为自助化的定制打下基础.
用一张图来关注一下流程:
用一张表来了解一下每个方块的作用
我们接下来的步骤将会围绕这两幅图来展开, 我们将会以宿主机添加磁盘定制
之后实验机装载磁盘的方式进行测试工作
1. 整理磁盘分区操作
# 此段遵循 上一篇文章 前 (8 步的操作
# 安装grub文件
1
|
grub-
install
root-directory=
/mnt
/dev/sdb
|
# 编写grub.conf文件
1
2
3
4
5
|
default=0
timeout=5
title
"Mini Linux"
root (hd0,0)
kernel
/bzImage
ro root=
/dev/sda2
init=
/sbin/init
|
2. 编译内核
# 下载内核源码 请 内核下载
1
2
3
4
5
6
7
8
9
|
tar
xf linux-3.13.6.
tar
.xz -C
/usr/src
cd
/usr/src
# 创建链接
ln
-sv linux-3.13.6 linux
cd
linux
# 安装开发包组
yum groupinstall
"Development Tools"
make
allnoconfig
make
menuconfig
|
# 进入到内核选择将所有项编译进内核,符号 * , 选项如下, 缩进即为选项的层次关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
-> 64 bit kernel (64位支持)
-> gerernal setup
->
local
version (当前编译版本号)
-> Enable loadable modual support (允许模块加载)
-> Progressor
type
and features
-> Processor Family(Core2) (架构类型)
-> Symmetric multi-processing support(多核支持)
-> SMT (超线程 可选)
-> Bus Options(PCI etc.)
-> PCI support (pci总线支持)
-> Device Drivers
-> SCSI device support
-> SCSI deveice support
-> SCSI disk support
-> Fusion MPT device support (虚拟磁盘支持)
-> Fusion MPT logging facility (虚拟磁盘日志 可选)
-> Fusion MPT ScsiHost drivers
for
SPI (虚拟磁盘)
-> Fusion MPT misc device (ioctl) driver (磁盘可做初始化)
-> Input Device support
-> Keyboards (键盘支持)
-> Mice (
ps
/2
支持)
-> Mouse interface (鼠标接口 可选)
-> USB support
-> Support
for
Host-side USB
-> EHCI HCD (USB 2.0) support (usb 2.0)
-> xHCI HCD (USB 3.0) support (usb 3.0可选)
-> OHCI HCD (USB 1.1) support (usb 1.1)
-> UHCI HCD (most Intel and VIA) support (可选)
-> Gernal Driver Options
-> Maintain a devtmpfs filesystem to
mount
at
/dev
(使用devtmpfs机制挂载设备文件)
-> Automount devtmpfs at
/dev
, after the kernel mounted the rootfs (内核自动探测自动挂载)
-> Network device support
-> Network core driver support (网络核心驱动程序)
-> Ethernet driver support (以太网卡驱动程序)
-> Intel devices
-> Intel(R) PRO
/1000
Gigabit Ethernet support ()
-> Intel(R) PRO
/1000
PCI-Express Gigabit Ethernet support (板载网卡驱动)
-> File system
-> The Extended 4 (ext) filesystem
-> Executable
file
formats / Emulations (可执行文件系统)
-> Kernel support
for
ELF binaries (支持ELF二进制程序)
-> Kernel support
for
scripts starting with
#! (支持bash脚本)
-> Networking support
-> Networking options
-> Unix domain sockets
-> UNIX: socket monitoring interface
-> TCP
/IP
networking
-> IP: multicasting (ip多播协议)
-> IP: advanced router (高级路由协议)
-> IP: kernel level autoconfiguration (内核级别配置)
-> IP: DHCP support (DHCP服务)
-> IP: BOOTP support (早起DHCP服务)
-> IP: RARP Support (局域网ip,mac转换协议)
-> IP: TCP syncookie support (tcp同步状态支持)
|
# 选择结束后,make menuconfig会生成.config文件在当前目录下
1
2
3
4
|
# 仅编译内核,使用4线程编译
make
bzImage -j 4
# 编译完毕,拷贝内核到/mnt/boot中,这将是未来我们要使用的新内核
cp
/usr/src/linux/arch/x86_64/boot/bzImage
/mnt/boot/
|
3. 安装busybox
# 下载busybox, 请 busybox下载
# 依赖环境 glibc-static 下载 , 请 http://rpmfind.net/linux/rpm2html/search.php?query=glibc-static&submit=Search+...
1
2
3
4
5
6
7
8
9
10
|
# 为busybox安装解决依赖
rpm -ivh glibc-static.rpm
# 解压busybox到当前目录
tar
xf busybox-1.21.1.
tar
.bz2
# 类似与内核的选择框,需要选择 *
Busybox Settings --->
Build Options --->
---> Build BusyBox as a static binary (no shared libs)
# 选择完毕退出后安装busybox
make
&&
make
install
|
# 在安装完毕后busybox当前目录会生成 _install 文件
1
2
3
4
5
|
# 完成后将当前目录 _install 中所有文件复制到 /mnt/sysroot 中
cp
-rd _install/*
/mnt/sysroot
# 由最开始的图中我们知道,精简内核的运行依靠 busybox, 那busybox运行
# 需要依赖某些二进制文件及库文件,因此可以使用 上一篇 10步骤的脚本移植
# busybox 的二进制及库文件
|
4. 依次提供下列文件,为精简内核的运行做准备 etc/fstab etc/rc.d/rc.sysinit etc/inittab
# 我们的内核在启动时 脚本 rc.sysinit 中会 mount -a 加载这里所写的一切设备
[root@King200 sysroot]# cat etc/fstab
/dev/sda1 /boot ext4 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
/dev/sda2 / ext4 defaults 0 0
/dev/sda3 swap swap defaults 0 0
# 服务启动脚本,/etc/inittab 会在开机启动时调用这个脚本
1
|
[root@King200 sysroot]
# vim etc/rc.d/rc.sysinit
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#!/bin/bash
#
# 打印内核准备过程中的提示信息
echo
-e
"\t Welcome to \033[33m Mini \033[0m Linux"
# 显示主机信息设置
[ -r
/etc/sysconfig/network
] && .
/etc/sysconfig/network
[ -z
"$HOSTNAME"
-o
"$HOSTNAME"
==
"(none)"
] && HOSTNAME=localhost
/bin/hostname
$HOSTNAME
# 挂载proc文件系统
echo
"proc filesystem"
mount
-t proc proc
/proc
# 挂载sys文件系统
echo
"sysfs filesystem"
mount
-t sysfs sysfs
/sys
# 挂载内核所需的设备文件,这里的udev是busybox特有的
mdev -s
# 配置网卡信息
ifconfig
lo 127.0.0.1
ifconfig
eth0 172.16.43.1
# 按照上面fstab文件中定义的设备文件重新挂载所有设备
mount
-a
# 可读写挂载 根文件 系统,还记得grub中引导系统时,我们的根时只读状态吗?
mount
-o remount -rw /
# 挂载虚拟终端设备,为后面的ssh登陆做准备
mkdir
/dev/pts
mount
-t devpts devpts
/dev/pts
# 导出PS1和PATH路径
export
PS1=
"[\u@\h \w]$ "
export
PATH=
"/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
# 这里将会执行rc3.d中所有以 .start 文件结尾的脚本,这样我们就可以做到
# 在精简的内核上启动我们所需的服务了
/etc/rc
.d
/rc3
.d/*.start start
|
# 内核 /sbin/init 启动的第一个文件就是 inittab
1
2
3
4
5
6
7
8
9
10
|
[root@King200 sysroot]
# cat etc/inittab
::sysinit:
/etc/rc
.d
/rc
.sysinit
::respawn:
/sbin/getty
19200 tty1
::respawn:
/sbin/getty
19200 tty2
::respawn:
/sbin/getty
19200 tty3
::respawn:
/sbin/getty
19200 tty4
::respawn:
/sbin/getty
19200 tty5
::respawn:
/sbin/getty
19200 tty6
::ctrlaltdel:
/sbin/reboot
::
shutdown
:
/etc/rc
.d
/rc
.sysstop
|
5. 提供 密码,shadow,group信息 还有nsswitch文件及库文件(登陆准备)
1
2
3
4
5
6
7
|
[root@King200 /]
# head -1 /etc/passwd > /mnt/sysroot/etc/passwd
[root@King200 /]
# tail -1 /etc/passwd >> /mnt/sysroot/etc/passwd
[root@King200 /]
# head -1 /etc/group > /mnt/sysroot/etc/group
[root@King200 /]
# tail -1 /etc/group >> /mnt/sysroot/etc/group
[root@King200 /]
# head -l /etc/shadow > /mnt/sysroot/etc/shadow
[root@King200 /]
# head -1 /etc/shadow > /mnt/sysroot/etc/shadow
[root@King200 /]
# tail -1 /etc/shadow >> /mnt/sysroot/etc/shadow
|
1
2
3
4
5
6
7
8
9
|
[root@King200 lib64]
# ls libnss # /usr/lib64
libnss3.so libnssdbm3.so libnss_nisplus.so libnssutil3.so
libnssckbi.so libnss_dns.so libnss_nis.so libnss_winbind.so
libnss_compat.so libnss_files.so libnsspem.so libnss_wins.so
libnssdbm3.chk libnss_hesiod.so libnsssysinit.so
[root@King200 lib64]
# cp libnss3.so /mnt/sysroot/usr/lib64/
[root@King200 lib64]
# cp libnssutil3.so /mnt/sysroot/usr/lib64/
[root@King200 lib64]
# cp libnss_files.so /mnt/sysroot/usr/lib64/
[root@King200 lib64]
# cp -d /lib64/libnss_files* /mnt/sysroot/lib64/
|
6. 最后检查是否已准备好所有所需文件
1
2
|
cp
/etc/issue
/mnt/sysroot/etc/
cp
/etc/shells
/mnt/sysroot/etc/
|
# etc 下这些文件或目录请确保完备
fstab inittab nsswitch.conf shadow sysconfig
group issue passwd rc.d shells
7. 为定制的内核中安装第一个服务dropbear用于远程登陆
#下载dropbear 请 dropbear下载
1
2
3
4
5
6
|
# 编译安装
.
/configure
make
PROGRAMS=
"dropbear dbclient dropbearkey scp"
make
PROGRAMS=
"dropbear dbclient dropbearkey scp"
install
# 使用移植脚本将 dropbear dbclient dropbearkey scp 二进制文件及
# 库文件全部移植到 /mnt/sysroot下
|
# dropbear生成密钥
1
2
3
|
mkdir
/mnt/sysroot/etc/dropbear
dropbearkey -t rsa -f
/mnt/sysroot/etc/dropbear/dropbear_rsa_host_key
-s 2048
dropbearkey -t dss -f
/mnt/sysroot/etc/dropbear/dropbear_dss_host_key
|
8. 将当前宿主机关闭,开始测试
# 我们可以看到定制的欢迎界面和登陆后开启dropbear服务器的端口信息
9) 开机启动dropbear
1
2
3
4
5
6
|
# 在 /mnt/sysroot/etc/rs.c/rs.sysinit 最后一行加入
/etc/rc
.d
/rc3
.d/*.start start
mkdir
/mnt/sysroot/var/lock/subsys
-p
mkdir
/mnt/sysroot/etc/rc
.d
/init
.d
# 编写服务脚本
vim
/mnt/sysroot/etc/rc
.d
/init
.d
/dropbear
|
服务脚本如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#!/bin/sh
#
# description: dropbear ssh daemon
# chkconfig: 2345 66 33
#
dsskey=
/etc/dropbear/dropbear_dss_host_key
rsakey=
/etc/dropbear/dropbear_rsa_host_key
lockfile=
/var/lock/subsys/dropbear
dropbear=
/usr/local/sbin/dropbear
dropbearkey=
/usr/local/bin/dropbearkey
keysize=1024
port=22
gendsskey() {
[ -d
/etc/dropbear
] ||
mkdir
/etc/dropbear
echo
"Starting generate the dss key: "
$dropbearkey -t dss -f $dsskey &>
/dev/null
RETVAL=$?
if
[ $RETVAL -
eq
0 ];
then
return
0
else
return
1
fi
}
genrsakey() {
[ -d
/etc/dropbear
] ||
mkdir
/etc/dropbear
echo
"Starting generate the rsa key: "
$dropbearkey -t rsa -s $keysize -f $rsakey &>
/dev/null
RETVAL=$?
if
[ $RETVAL -
eq
0 ];
then
return
0
else
return
1
fi
}
start() {
[ -e $dsskey ] || gendsskey
[ -e $rsakey ] || genrsakey
if
[ -e $lockfile ];
then
echo
"dropbear is already running: "
exit
0
fi
echo
-n
"Starting dropbear: "
$dropbear -p $port -d $dsskey -r $rsakey
RETVAL=$?
echo
if
[ $RETVAL -
eq
0 ];
then
touch
$lockfile
return
0
else
rm
-f $lockfile
return
1
fi
}
stop() {
if
[ ! -e $lockfile ];
then
echo
"dropbear service is stopped: "
exit
1
fi
echo
"Stopping dropbear daemon: "
killall -p dropbear
RETVAL=$?
echo
if
[ $RETVAL -
eq
0 ];
then
rm
-f $pidfile
return
0
else
return
1
fi
}
status() {
if
[ -e $lockfile ];
then
echo
"dropbear is running..."
else
echo
"dropbear is stopped..."
fi
}
usage() {
echo
"Usage: dropbear {start|stop|restart|status|gendsskey|genrsakey}"
}
case
$1
in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
gendsskey)
gendsskey
;;
genrsakey)
genrsakey
;;
*)
usage
;;
esac
|
1
2
3
4
5
6
7
8
|
# 将上面写的脚本赋予可执行权限
chmod
+x
/mnt/sysroot/etc/rc
.d
/init
.d
/dropbear
# 将服务脚本链接为 dropbear.start dropbear.stop 实现开机关机启动与关闭
mkdir
/mnt/sysroot/etc/rc
.d
/rc3
.d
# 这里需要相对链接到目录,或者制作好后的系统链接会让你欲哭无泪 :)
cd
/mnt/sysroot/etc/rc
.d
/rc3
.d
ln
-sv ..
/dropbear
.
/dropbear
.start
ln
-sv ..
/dropbear
.
/dropbear
.stop
|
最终开机如8) 图所示,可以实现在精简内核上服务的开机启动
10) 关机脚本
1
2
3
4
5
6
|
vim
/mnt/sysroot/etc/rc
.d
/rc
.sysstop
#!/bin/bash
#
/etc/rc
.d
/rc3
.d/*.stop stop
umount
-a
chmod
+x
/mnt/sysroot/etc/rc
.d
/rc
.sysstop
|
接下来的事情计划:
Step3 交叉编译将Centos跑在 Raspberry pi 上
Step4 编译安卓源码,定制个性化的android 上
Step5 完成异构平台的并行计算
本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1389340,如需转载请自行联系原作者