自从在大学知道了Linux这玩意是可以定制的之后,一直想做出一版属于自己的Linux系统。最近工作比较闲,终于塌下心来好好学习了一下。
目前来说,我接触的定制Linux的方法主要有两种:
1、以busybox为核心,通过构建initrd+busybox做出的fs+内核这三大块,构建Linux
2、采用更底层方式,基于源代码级,通过编译&构建自己的工具链+编译&构建自己的lfs+内核这三大块,构建Linux,其中最典型的就是我刚刚完成的LFS系统。
关于两种方法的优缺点呢,由于我接触的还比较肤浅,所以认识可能有些错误。
方法1在速度上要比2快得多,更适合于小型嵌入式Linux。而方法2由于采用了更底层更直接的方式,适合用来学习Linux的架构,也有很好的拓展性和自由性,对定制比较灵活,打好基础后续还可以继续BLFS。
先不管那么多,我只是想做个笔记而已,以免做完了,过了两月,怎么做的都忘干净了= =!
方法一:
需要准备工具:
宿主机一台,硬盘一块(学习时可以使用虚拟机的虚拟磁盘),纯洁的内核一份,busybox源代码一份
1、将硬盘分两个区,一个boot用,一个当根文件系统用,之后分别挂载至宿主机的/mnt/boot和/mnt/sysroot目录。
将grub安装到boot目录:grub-install --root-directory=/mnt /dev/sda
2、编译busybox,这玩意做的menuconfig跟内核很像呢,在里面选上下面这项,即编译出来的busybox不与宿主机共享库文件,之后make install:
Busybox Settings --> Build Options --> Build BusyBox as a static binary (no shared libs)
3、制作initrd。initrd全称是init ram disk,在我理解就是在linux启动之前运行在ram中的临时根文件系统,用来挂载实际硬盘上的根文件系统。对于一些需要热关机的场合,initrd其实直接就可以当最终文件系统来使用。
制作方法是这样的,在宿主机/tmp目录下建一个initrd文件夹,将刚才busybox安装完毕出现的_install文件夹下内容全部拷贝到initrd文件夹下,此时其中已经包含了部分系统常用命令。
接下来建立系统常用的文件夹:mkdir -pv proc sys etc tmp dev mnt/sysroot
创建两个必要的设备文件:
mknod dev/console c 5 1
mknod dev/null c 1 3
建立init脚本,实现initrd启动后对rootfs的切换
[root@localhost initrd]# vim init
[root@localhost initrd]# cat init
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mdev -s
mount -t ext3 /dev/hda2 /mnt/sysroot
exec switch_root /mnt/sysroot /sbin/init
#给此脚本执行权限:
chmod +x init
这里需要注意一下,由于各种可能原因,init脚本启动无法挂载rootfs,尤其是在mdev -s这步,这里有一个调试办法,直接在initrd中启动shell。
/sbin/getty -n -l /bin/sh 38400 tty1
exec /bin/sh
以上的代码可以酌情加载init脚本中某个位置。
好,到这里initrd就制作完毕了,把它打包,待用。
find . | cpio --quiet -H newc -o | gzip -9 > /mnt/boot/initrd.gz
5、接下来制作真正的rootfs,其实方法原理跟制作initrd差不多了。以下为无脑转载:
#拷贝busybox中所有文件到/mnt/sysroot
cp -a busybox-1.20.2/_install/* /mnt/sysroot
#创建minilinux所需的目录
mkdir -pv /mnt/{boot/grub,sysroot/{boot,proc,sys,bin,sbin,lib/modules,usr/{bin,sbin,lib},var/{run,log,lock},etc/{init.d,rc.d},dev/pts,home,root,tmp}}
#创建两个必要的设备文件:
mknod dev/console c 5 1
mknod dev/null c 1 3
#配置init所需的inittab配置文件
cd /mnt/sysroot
rm -f linuxrc
[root@localhost sysroot]# vim etc/inittab
[root@localhost sysroot]# cat etc/inittab
::sysinit:/etc/rc.d/rc.sysinit
::respawn:/sbin/getty 9600 tty1
::respawn:/sbin/getty 9600 tty2
::respawn:/sbin/getty 9600 tty3
::shutdown:/bin/umount -a -r
::ctrlaltdel:/sbin/reboot
#配置系统初始化脚本etc/rc.d/rc.sysinit
[root@localhost sysroot]# vim etc/rc.d/rc.sysinit
[root@localhost sysroot]# cat etc/rc.d/rc.sysinit
#!/bin/sh
echo -e "\tWelcome to \033[31mMageEdu\033[0m Linux"
echo -e "Remounting the root filesystem ..."
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -o remount,rw /
echo -e "Creating the files of device ..."
mdev -s
echo -e "Mounting the filesystem ..."
mount -a
swapon -a
echo -e "Starting the log daemon ..."
syslogd
klogd
echo -e "Configuring loopback interface ..."
ifconfig lo 127.0.0.1/24
ifconfig eth0 172.16.100.100/16
#而后让此脚本具有执行权限:
chmod +x etc/rc.d/rc.sysinit
#为系统准备一个“文件系统表”配置文件etc/fstab
[root@localhost sysroot]# vim etc/fstab
[root@localhost sysroot]# cat etc/fstab
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
/dev/hda2 / ext3 defaults 1 1
————————————————————转载结束————————————————————————
需要注意的是,fstab这个文件十分重要,要配置符合成实际使用情况。
4、把纯洁的内核先给编译喽,可以精简部分选项.。第一次最好要做好完全准备,记得提前make mrproper。编译完成后,把编译好的bzImage文件拷到boot分区下。
5、现在既有了内核,又有了initrd,该配置grub.conf了,同样注意实际使用情况。
6、一定记得sync,之后新建一个虚拟机,用做好的硬盘应该就可以引导起来了。
关于busybox这个方法,网上有大量教程,很详细,思路都差不多,就说道这里。
方法二:
需要准备工具:
宿主机一台,硬盘一块(学习时可以使用虚拟机的虚拟磁盘),LFS-packeages,官方提供下载,我用的是stable7.3
其实关于这个方法,最好的还是去读官方教程,写的非常好,非常详细,也连带着许多知识点,我这就记录一个思路。
下面我说一下我的理解。
我们要做一个系统,最重要的一点是保证她的纯洁,即做完了的这个系统是个独立的系统,与宿主机毫无瓜葛,那么由于LFS是基于代码级的,所有程序都需要编译,这就意味着编译时依赖的编译器、glibc库等,是一个重点,也就是反复提到的工具链,如下。
宿主机工具链-》编译出LFS系统工具链-》进行自编译,形成独立-》构建rootfs
整个LFS的流程是这样的
1、还是将硬盘分区
2、新建一个用户,进入该目录,依附宿主机分别编译Binutils和Gcc,之后编译Glibc,接着,基于刚编译好的Glib重新编译Binutils和Gcc。其实工具链的布置就是这么个意思,摆脱了与宿主机的关系。当然,这三个是最基本的,除此之外,在布置工具链还需要大量的工具,而这些工具是基于这三个的。
3、下面chroot,进入纯净的LFS系统,从零开始。通过上面完成的工具链,一个一个安装需要的命令。
4、编译内核、配置fstab、配置grub,但是没有initrd。在网上查了一下原因,原来initrd存在的意义还可以缩小真正系统的内核大小,因为其中有一些系统启动时候需要的启动介质驱动、根文件系统驱动,所以一般发行版都有。但LFS一般只供单机使用,所以就没有这个步骤,当然想加也是可以加上的。
以上是一个初学者的(可能是
漏洞百出、错误连篇的)笔记。
- 基于 cobbler 实现自动安装 linux 系统
使用 cobbler 实现自动安装 centos 6.7系统 1.yum install cobbler -y 安装 cobbler ,有依赖关系,会自动把 TFTP .HTTP 服务安装上:cobb ...
- 基于PXE网络启动的Linux系统自动化安装
在实际工作中,传统纯手动安装操作系统的方式是有一定的局限性的,例如:现在大多数的服务器都不自带光驱,若要安装系统需要外接光驱插入光盘,整个安装过程中需要人工交互确认,手动设置每一个安装设置项,人必 ...
- 基于ARM9和嵌入式Linux系统的多功能综合通信控制系统的框架
基于ARM9硬件平台和嵌入式Linux系统的多功能综合通信控制系统的框架设计及各模块的功能.系统采用符合POSIX.1标准的C语言编写,实现了对下位机传送数据帧的采集.分析和存储,并能根据上位机的配置 ...
- 交叉编译HTOP并移植到ARM嵌入式Linux系统
原创作品,允许转载,转载时请务必以超链接形式标明文章.作者信息和本声明,否则将追究法律责任. 最近一直在完善基于Busybox做的ARM Linux的根文件系统,由于busybox是一个精简的指令集组 ...
- 《手把手教你构建自己的 Linux 系统》学习笔记(2)
Linux 系统定制原理 虚拟根目录 我们的目标是为了完成目标系统(也就是我们要做的系统),他是一个可以独立运行的系统,不依赖雨主系统和临时系统,根据 Linux 系统的特点它需要存放在根目录下面,但 ...
- 《手把手教你构建自己的 Linux 系统》学习笔记(1)
第二章.基础准备--Linux 系统定制原理 Linux 系统的组成及架构 共享库和静态库 在 Linux 系统中,函数库包含两种形式:共享库和静态库. 共享库 共享库在程序运行时,为其提供所需要的函 ...
- 基于busybox的Linux小系统制作 (initrd)
我们有时候有需要在busybox基础上,制作linux,可是却不知道具体怎么做,这里将对基于busybox的linux小系统制作做出详细的步骤说明.准备环境:1.一个Redhat完整系统的虚拟机,本次 ...
- 嵌入式之Linux系统裁剪和定制---(kernel+busyboxy+dropbear+nginx)
本文将介绍通过完全手动定制内核,在此基础上添加 busybox ,并实现远程登陆,使裁剪的 linux 能够运行 nginx . 在此之前介绍一下 linux 系统的启动流程. linux系统启动流程 ...
- 定制自己的linux系统
算是总结式文档,以备后忘 先说一下背景,一开始我就知道有这个任务,同时我自己也非常感兴趣,打算去研究研究 于是才同意接这个任务,但是我的原意是从头开始搭建系统,也就是lfs 但接到任务后,由于种种原因 ...
随机推荐
- (七)DAC0832 数模转换芯片的应用 以及运算放大器的学习 01
DAC0832是8分辨率的D/A转换集成芯片.与微处理器完全兼容.这个DA芯片以其价格低廉.接口简单.转换控制容易等优点,在单片机应用系统中得到广泛的应用.D/A转换器由8位输入锁存器.8位DAC寄存 ...
- 0421 实验二Step2-FCFS调度
一.目的和要求 1. 实验目的 (1)加深对作业调度算法的理解: (2)进行程序设计的训练. 2.实验要求 用高级语言编写一个或多个作业调度的模拟程序. 单道批处理系统的作业调度程序.作业一投入运行, ...
- nginx指定配制文件
nginx启动: 未指定配制文件: ./nginx 指定配制文件: /usr/local/nginx/sbin/nginx -c /home/deploy/nginx-wz/conf/nginx.co ...
- 10.Java设计模式 工厂模式,单例模式
Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...
- ajax中网页传输(三)XML——下拉列表显示练习
XML:页面之间传递数据,跨平台传递 HTML:超文本标记语言,核心标签 XML的形势为 <xml version='1.0'> <Nation> <one> &l ...
- 鸟哥的linux私房菜学习记录之档案权限与目录配置
在linux中可以通过ls来查看文件 如ls -al,可以看到类似以下的内容 给个例子来理解下 在目录中如果只有r权限没有x权限无法进入该目录
- java中==与equal()方法的区别
==比较的是对象的地址,也就是是否是同一个对象: equal比较的是对象的值. Integer r1 = new Integer(900);//定义r1整型对象Integer r2 = new Int ...
- 编译busybox-1.24.1 制作文件系统
arm-linux-gcc 3.4.5 busybox-1.24.1.tar.bz21, 修改 Makefile找到以下2处修改为ARCH ?= armCROSS_COMPILE ?= arm-li ...
- python logging 替代print 输出内容到控制台和重定向到文件
转自:http://blog.csdn.net/z_johnny/article/details/50740528
- 【python cookbook】【数据结构与算法】16.筛选序列中的元素
问题:提取出序列中的值或者根据某些标准对序列做删减 解决方案:列表推导式.生成器表达式.使用内建的filter()函数 1.列表推导式方法:存在一个潜在的缺点,如果输入数据非常大可能会产生一个庞大的结 ...