从最开始用红旗linux到现在,玩linux大概也有4年了,但总觉得自己对linux这个系统缺乏足够的了解,解决问题总是半懂不懂的使用别人那里抄来的命令,虽然自己看了一些书,总觉得对linux了解的不够多。这次由于需要,决定自己“组装”一个linux系统(有点制作发行版的意思),在这个过程中,网上经常查不到对应的资料,有些东西表述也不方便,故遇到了比较多的障碍,所以决定将过程中遇到的各种问题整理发布,也有助于后来人。
不过,这个系统目前仍在成长的过程中,有些地方我自己的表述也不太好,有些可能是错误的理解,希望大家不吝赐教。
好,言归正传。
目的:依靠现已成熟的开源软件,不依靠特定的发行版和软件包管理系统,组建一个具有完整应用功能的GNU/linux操作系统。
其实目的很类似与Linux fromscratch(LFS)但是由于我在玩LFS的痛苦经历,让我明白,LFS对新手来说还是太高不可攀了,所以我才想提供一个更简单的制作linux的方法,就算是Linuxfrom scratch的 express版吧
学习目的:linux的启动过程,以及各种软件的工作方式和与协作方式。
下面简要介绍以下我的环境(内核配置的时候会涉及到驱动的问题,所以列出来,介绍的时候我尽量不局限于具体的平台)
ACER 4554G-N972G50GMnkk N970(2.2GHz * 4)CPU,2G DDR3内存,WD500G硬盘,AMDReadon HD 6470M(1G)显卡 ,Atheros AR9287 无线网卡,Broadcom BCM57780网卡。
OS:Fedora 17 x86_64
软件:其实我也不是很清楚,安装的时候附上了很多developer软件包,在编译过程中倒是很少遇到库缺失的问题,如果编译报错的的话,网上应该搜的解决方法,如果不知道要装什么软件包的话,可以参考我的rpm-qa的结果 http://s.yunio.com/pWhKtw
我们先来制作一个最最简陋的linux系统
需要的软件包
1、首先你的电脑必须已经安装了grub,这个现在绝大多数的linux发行版用的都是grub吧?
2、内核源文件。在 http://kernel.org/可以很容易的下到,我这时候的最新版本是3.5.3,下载下来是一个linux-3.5.3.tar.bz2 压缩文件
3、busybox。在http://www.busybox.net/可以下到,我现在的版本是1.20.2下在下来是一个busybox-1.20.2.tar.bz2文件。
解释一下
首先,grub在以后并不是必须的,但是鉴于我们才刚刚开始,还是先借用主机上的grub比较方便。
还有就是,我这里是自己编译一个内核来使用,如果你有以前已经编译好的内核,就可以省去这一步,或者希望用系统现有的内核,这个考虑到驱动的问题,并不推荐。我这边从头编译一个内核,是基于某种定制的心理(系统洁癖吧,哈哈)。
至于busybox,有些人可能并不熟悉。简单的说,busybox就是linux所必须的各种基础程序的一个集合。其中包括ls,cd,mount,tar,gettty等等的命令,一般我们制作一个系统都是要分别编译coreutils,binutils等等的软件包,而busybox则独立承担这么多软件包的责任。作为系统软件的一个简化版本。
我们理一下思路:启动装载程序+内核+系统软件,是不是就构成了一个完整的系统?
那么下面我们开始。
首先是编译内核
对初学者来说,编译内核可不是一件简单的事情,几乎不存在第一次就成功的可能性,就拿我来说,最初玩LFS的时候,其他软件都弄好了,就是内核怎么也搞不定,不知是什么问题,最后草草收场,不过,如果你成功了一次,以后都可以在这个基础上改进,就很方便了。后来,就是在我弄这个系统的时候,大约是我第六次我编译内核,终于成功了(如果要总结原因的话,那时候基础不够LFS有略显复杂,问题出在哪里至今也不了解,这也是我写这篇文章的初衷)。我当时学习内核的配置,主要就是依靠这两篇文章
http://blog.chinaunix.net/space.php?uid=11979177&do=blog&id=2794545
http://tmdnet.nothave.com/man/Linux 2_6_19_x 内核编译配置选项简介.htm
顺便感谢两位对我的帮助,尤其是这位金步国先生,他的好几篇文章都给了我非常大的帮助。
言归正传
先新建一个文件夹,方便管理,名字,位置都是我所谓的,把两个压缩文件先放进去。
打开终端(后面全是在终端里完成的,一下不再重复。不会用终端?那您还是先学一下吧,这是基础知识)
cd到这个文件夹
cd linux-3.5.3
make menuconfig
根据需要你也可以选择
make xconfig
make gconfig
甚至make config
按自己的需要来配置内核
我第一次的情况大概是,关闭了绝大部分功能甚至关闭了模块加载支持,仅仅保留了pci,保留了ext2,vfat,ntfs和iso的文件系统支持,和Generalsetup中一些基本的支持,具体可以参见我的.config http://s.yunio.com/kOvSvk导入我的config的方法是将他复制到linux-3.5.3下并重命名为.config然后执行命令makeoldconfig
配置完成后执行
make -j 5
5根据自己计算机的核心数修改,一般是核心数加1,我是4核的cpu所以是5,这个仅仅会影响编译的速度,对实际结果没有影响。
如果内核配置的当的话,这个过程大约需要3-5min,设置不好的话可能会需要20min,如果再长的话,建议看一下你是不是加入了某些debug选项,不然一个精简的内核不会这么慢的。
结果会产生一个内核文件,存储在arch/x86/boot/下,名叫bzImage,一般在4-8M左右,过大的话,之前的内核设置应该有问题。
如果产生了bzmage,那么表示你的内核已经生成成功了。
下面开始busybox
同理
进入busybox
make menuconfig
大部分都可以默认,有几个选项需要改一下
busybox setting/General Configuration/Don't use /usr 需要选上
busybox setting/Build Options/ Build BusyBox as a static binary (noshared libs)也需要选上
然后把Linux Module Utilities
Networking Utilities
Print Utilities
Mail Utilities
Login/Password Management Utilities
中所有的选项全部去掉
然后退出
make -j 5
make install
如果顺利的话,恭喜你,你的系统已经接近完成了。
在外面再建个文件夹,比如叫rootfs
现在把busybox-1.20.2/_install下两个文件夹都复制到rootfs下
然后在rootfs下再创建几个文件夹,分别叫dev,etc,root,proc,sys
在etc下创建个文件夹,叫init.d
在init.d下创建一个叫rcS的文件,在其中输入
#!/bin/sh
mount -a
在etc下创建两个文件
一个叫inittab
内容
#/etc/inittab
::sysinit:/etc/init.d/rcS
console::respawn:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
一个叫fstab
内容
#device
proc
sysfs
并在dev文件夹中执行命令
mknod console c 5 1
mknod console c 1 3
然后用命令行进入rootfs文件夹,输入命令
find .|cpio -o -H newc |gzip > ../initrd.gz
然后你就会看到多出来一个initrd.gz文件
现在把initrd.gz和之前生成的bzImage复制到/boot下,并将bzImage重命名为vmlinuz-3.5.3-my,initrd.gz重命名为initramfs-3.5.3-my
然后运行命令update-grub
完成后重启,你就会看到你多了一个启动项,选择进入,应该很快就会进入系统,不过,如果之前的配置出现什么问题的话,你可能会看到kernelpanic,那你就需要从头检查一遍,看一下你的问题出在哪里。
其实,一般来说,编内核之类的事情,一遍过的概率是很小的,kernelpanic也算是很常见的事情,而且大家碰到的问题各异,如果遇上了什么神奇的问题,那就要靠你自己google了阿。
上次,我们已经完成了最基本的内核以及文件系统的创建,这就构成了一个极简的操作系统,下面我们来讲讲怎么把这个操作系统制作成一个iso,方便我们刻录(到光盘略浪费,可以是U盘)或者在虚拟机里启动。主要原因是目前这个系统功能还不够强,开了做不了太多的事每开一次还需要重启,如果在试验过程中出错,不断重启确实是一件很纠心的事,所以我们要把他做成iso镜像。
首先,我们需要创建一个工作目录,创一个文件夹,比如我这里叫CD_root,把之前做好的内核以及文件系统复制到这里,并在里面建一个文件夹isolinux.
这里我们使用isolinux来制作。首先我们要获得isolinux,你当然可以选择下载源代码编译,但是考虑到光盘启动程序是直接跑在裸机上的,大家用的都是x86平台,不存在什么兼容性问题,所以我们可以直接使用别人制作好的isolinux,这里我们只需要一个isolinux.bin大家可以直接从各个linux发行版的安装光盘里复制出来,一般都在isolinux目录下,我是从Fedora17DVD的安装盘里拿出了isolinux。同样也是拷到我们的工作目录(CD_root)下刚在建好的isolinux文件夹里,然后我们来写一个启动配置文件isolinux.cfg。他的作用大致相当于grub的grub.cfg。
isolinux.cfg的内容大致如下
default MyOS
label MyOS
kernel /bzImage
append initrd=/initrd.gz
我来解释以下第一行告诉isolinux默认启动MyOS(这个名字是随便取得),然后下面告诉系统MyOS是什么。
内核在(工作目录的)根下,叫bzImage,文件系统叫initrd.gz
这样我们的光盘目录就成形了
如下
CD_root
+--isolinux
+--+--isolinux.bin
+--+--isolinux.cfg
+--bzImage
+--initrd.gz
现在我们来做最后的一步,打开命令行,来到CD_root的上层目录,执行命令
mkisofs -o myiso.iso -b isolinux/isolinux.bin -c isolinux/boot.cat-no-emul-boot -boot-load-size 4 -boot-info-table -input-charsetutf-8 CD_root
很快我们就可以看到生成的myiso.iso文件,在虚拟机里用他启动,效果是不是一样的,是不是方便多了?
好久没有写博客了,某种程度上是因为我是一个懒人,一直忘记,某种程度上也是因为最近比较忙。以后的目标,每周写一篇,就当是工作总结了。
其实这个微型linux后来就没怎么更新,取而代之,是实验室一个基于S3C6410(ARM1174JZF-S)的一个智能小车项目,而我主要就是在开发板上构建一个linux环境。说来也是很巧,之前搞这个微型系统纯属兴趣,最后能和导师的任务不谋而合,哈哈,比那些做图形界面的人爽多了。。。
虽然是在开发板上做,但是除了需要交叉编译外,其实和我们普通的x86系统没什么差别,所以,这个系列还可以延续下去
这段时间其实在开发板上对这个系统做了很多的改进,容我一一道来(估计够写3-5篇了)
下面言归正传
-------------------------------------------------------------------------------------------------
首先我们要讲一下用户和权限的问题,也许你会觉得开发板放的是一个精简的系统,用户权限可能比较多余。但是在我看来,首先,我们是抱着学习linux系统的原理的想法来得,多学点东西总是好的,还有就是,我们的项目其实会用到很多网络服务telnet
这里主要会涉及到两个文件/etc/passwd和/etc/shadow
最初的linux系统,只需要passwd,其中存储了几乎所有的用户权限信息,不过,这种方法把密码以明文形式存储还有其他一些安全性问题(想想前阶段CSDN泄漏的密码吧),后来改成加密,但是这个文件需要给太多用户读权限,不够安全,所以会将密码加密并存储在shadow中,至于/etc/group,用户组目前对我们的意义不大,就不作讨论了。首先,晒出我开发板上的这两个文件。
/etc/passwd
root:x:0:0:root:/root:/bin/sh
/etc/shadow
root:$6$7kuDbVvljoH2boDb$/xcwz91bgd3OYqy4nL4E9H67Y
在我的另一块开发板上,用的是单个passwd的方法,这也是可以的
/etc/passwd
root:$1$F0DlBCNG$22weoCI6bsYjCJ/JrrT2Y1:0:0:root:/:/bin/sh
很明显都只有一个root用户,密码不妨告诉大家 341,是我们实验室的门牌号
我稍微解释一下
passwd里
一行一个用户,格式是
用户名:密码:UID:GID:备注:用户根目录:shell
如果使用shadow密码为x
但是要生成这个密文却不是太容易,最简单的当然是在自己电脑上使用passwd命令先改好密码,在复制过去,或者先不设密码(密码项留空),第一次开机后再改。前一种方法会影响主机而且不方便,后一种在只读文件系统里不可用,这里我来介绍一种方法来把他算出来。
其实系统已经封装好了一个加密函数,调用十分方便,下面给大家看一下C语言源代码(玩linux的有人不会C吗?)
#include<stdio.h>
#include<unistd.h>
int main()
{
}
其实只有一行代码,这里我们用了sha-512,所以另外还要一个随机串来防止破解MD5常用的碰撞法,这个串完全是随机的,允许0-9A-Z a-z 以及./共32个字符,长度为16个字符(实际上就是一个512bit的数),你也可以选则别的加密算法,具体还是看man
这样,把生成的串加在后面.
至于shadow里的其他一些串,主要是涉及一些密码策略,大家的设定一般比较宽松,可以直接复制我的。
这样,我们基础的用户配置文件就写好了,如果之前busybox里编译了telnetd就可以在设置网络之后使用telnet远程管理这个系统,这在参与开发的人比较多的情况下会比用串口调试方便的多。
如果你希望,即使本地的用户也需要的登陆的话(就像我们普通的电脑那样)可以通过修改/etc/inittab来实现
具体方法是删掉其中的console::respawn:-/bin/sh一行
在后面加入
::respawn:/sbin/getty 9600 tty1
::respawn:/sbin/getty 9600 tty2
需要几个控制台就加几个(Ctrl+Alt+Fx)切换。
这样我们的系统已经初步具备投入使用的能力,我也曾经在类似的状态下做过项目,只不过再加些驱动,合理定制下内核而已。
-----------------------------------------------------------------------------------------------------------------------------------------
这一次连载就算暂时搁下了,其他的东西已经超出微型系统的范围了,我也不喜欢长的连载。
我还会把我最近做的各种东西不断发到网上,作为一个笔记,也希望对大家有所帮助。