linux自己制作卸载u盘程序,定制自己的U盘Linux系统

接触Linux很长时间了,一直没有什么长进,每次遇到问题解决完了就扔到一边,导致现在很多事情都无法手到即来。定制自己的U盘Linux,从去年就已经完工了,但是一直没有心思整理,过完年好不容易有点时间,抓紧整理一遍,以备不时之需。

总的来说,定制Linux系统的步骤还是比较简单的,因为还是在x86体系下,不用交叉编译,所以可以划分为五个部分:准备U盘,安装grub,编译busybox,编译内核,制作文件系统。其中grub我觉得是比较难以搞定的一件事情,很早前用的0.97版本,后来升级到2.0版本,都是稀里糊涂的就做成了,这次重新整理,详细记录一下方法步骤,也算在Linux的海洋里刨过水了。由于时间过去太久,此次全部下载最新版本的工具重新开始。

1.准备U盘

这一步其实算不上是制作过程中的核心步骤,但是既然用U盘承载Linux系统,还是应该给其留出一席之地的。准备工作就是给U盘分区并创建文件系统,用到fdisk和mkfs两个工具,比较简单。分区大小自己设定,因为一开始系统都不会太大所以Linux分区有500M足够用了,再大也不嫌弃,文件系统暂时用ext2,如果为了让U盘还能在windows上使唤,可以再划出一个Fat32分区,例如下图这样:19a3d2b278c40506490fdd0a0cc84fe0.png

2.安装grub

grub官网地址:https://www.gnu.org/software/grub/  (可恨在百度和bing搜索grub,第一条都不是此链接,最终还是google的作风正派),目前最新版本是grub2,官方ftp提供的下载文件创建时期是2012.06.28,看来一直也没有改动过。下载包后依照正常模式configure,make,make install,这一步也不是必须的,因为像Ubuntu系统上就已经安装了grub,直接用就行了。这次既然重新来,就编译试试,因为遇到了一些错误,所以也记录在案:

configure的时候可能会提示缺少包,好在现在用的是Ubuntu,所以缺什么装什么,不成问题。

make的时候提示两个错误:

./stdio.h:456:1: error: 'gets' undeclared here (not in a function)

_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");

解决方法是在stdio.h文件中,添加下面两句(蓝色部分)

#ifdef gets

#undef gets

_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");

#endif

另外一个错误:

grub_script.yy.c:2351:13: error: 'yy_fatal_error' defined but not used

解决方法是重新配置,添加蓝色部分选项: ./configure --disable-werror

(参考https://lists.gnu.org/archive/html/grub-devel/2012-08/msg00006.html)

原来在ubuntu12.04和RedHat6中编译一切都很正常,可是到了ubuntu15.10就出现问题,根本原因还是gcc版本更新了的缘故,好在前人也都已经总结出了经验。make完成之后会在当前目录下产生很多可执行文件,执行make install安装即可。

开始正式给U盘安装grub:

挂载U盘:

#mount /dev/sdb2 /media

安装:

#grub-install --root-directory=/media /dev/sdb

Installing for i386-pc platform.

Installation finished. No error reported.

查看安装后目录:

#ls /media/boot/grub/

fonts grubenv i386-pc locale

对比ubuntu系统的grub目录,基本内容一致:

#ls /boot/grub/

fonts gfxblacklist.txt grub.cfg grubenv i386-pc locale unicode.pf2

至此grub就算安装成功了,为了验证,做一个U盘启动的虚拟机(关于如何U盘启动,请参考virtualbox使用U盘启动),虚拟机启动后只要能看到这个界面,就说明一切正常:9cab2d96d1cb51916765b9e8dcdcb5d8.png接着配置grub.cfg文件,让系统可以自动引导:

1

2

3

4

5

6

7

8

9

10

11

12

setdefault=0

insmodgzio

insmodjpeg

insmodpart_msdos

insmodext2

settimeout=10

setroot='hd0,2'

linux(hd0,2)/boot/vmlinuzrw

initrd(hd0,2)/boot/initrd.img

boot

配置很简单,一切从简,只要能工作,剩下的事就好办多了。此处唯一要注意的地方就是(hd0,2),因为在分区U盘的时候,默认linux分区在第二位,所以此处应该是(hd0,2)而不是(hd0,1),注意了! 而vmlinux是下面要编译出来的内核文件,initrd.img则是制作好的ramdisk文件。

3.busybox1.24.1

单纯编译busybox算是比较简单的一部分,tar -jxvf 解压tar.bz2包,然后执行make menuconfig,选择自己需要的内容,接着make,make install,一般都不会有太大的问题,要是没有错误会生成到当前./_install目录下,在制作文件系统时,将生成的所有文件夹通通拷贝过去即可。busybox选项中都是要选择的命令,很明了,option中只需要注意将busybox编译成static的模式即可,最后生成的内容如下:

d7541a880bcc2da90068a89358a85d1e.pngbusybox默认带有make defconfig选项,官方说可以支持几乎所有的功能,懒人专用。如果这种方式编译提示错误:

klogd should not be used together with syslog to kernel printk buffer

就将.config文件中CONFIG_KLOGD=y 一行注释掉,再重新make就可以通过,中途会提示是否使用KLOG,选择"n"

4.编译内核linux-4.4.1

内核编译也算比较长见识的一项工作,以前感觉很神秘,操作其实很简单的,因为内核的价值在于其内部实现和各种功能的选择和精简,而不是编译本身,当下只是舍本逐末而已。依然是make menuconfig,然后选择模块。最要命的是对U盘的支持,常见的错误就是在启动是提示:" VFS: unable to mount root fs on unkown-block(1,0)":8c59a422b846e374e0efd62c96fc820c.png出现这种错误这时最好能将启动过程录屏,然后慢慢播放查看之前的日志,会有详细的错误描述。官方也认为导致这个错误出现的原因是多种多样的,特别应该关注的就是file system,block device这两个地方。经验是下面的这几个选项必须得设置:

General setup -->Initial RAM filesystem and RAM disk (initramfs/initrd) support

-->Support initial ramdisks compressed using gzip

Device Drivers --> Block devices

--> RAM block device support -->

(4) Default number of RAM disks

(655360)Default RAM disk size (kbytes)

File system --> Second extended fs support

-->The Extend 3 (ext3) filesystem

总结一下就是block  device一定要选中RAM block device support,然后默认的RAM disk size的大小一定要比自己的ramdisk大一点,文件系统只要包含涉及到的文件系统即可,其他SCSI设备的支持选项都是默认选中的。在编译内核时,可以用make -j 4 的方式,这样能加快一些速度,关于是否用ccache,根据个人情况考虑,如果每次只改动很小部分或许有用。

最新的内核版本在make之后,会自动产生bzImage文件,在./arch/x86/boot目录下,将其拷贝到U盘:

#cp ./arc/x86/boot/bzImage /media/boot/vmlinuz

5.制作文件系统

目前暂时用RAMDisk,就是将所有的文件都放到虚拟出来的RAM磁盘方式来实现,这样做的好处就是简单。首先创建一个目录fsystem,用于存放所有要打包到ramdisk里面的内容,先将busybox产生的内容拷贝过来,然后再建立一些必须的系统目录:

#mkdir dev etc lib home opt proc sys var tmp

接着拷贝设备文件:

通过"cp -a"命令将系统 /dev/下面的设备:

cdrom,dvd,loop0,console,random,urandom,ram0,null,zero,tty,tty0 统统拷贝到fsystem/dev下面

拷贝一些系统库:

#cp  /lib/i386-linux-gnu/{libc.so.6,libm.so.6,libpthread.so.0,librt.so.1,ld-linux.so.2} ./

创建块文件:

#dd if=/dev/zero of=ramdisk.img2 bs=4000 count=20480

格式化分区:

#mkfs.ext4 -F -m 0 -b 1024 ramdisk.img

挂载块文件:

#sudo mount -t ext4 -o loop ramdisk.img /media/

将已经做好的文件文件系统全部拷贝到ramdisk中:

#cp -r fsystem/* /media

卸载文件系统:

#umount /media

用gzip压缩ramdisk:

#gzip -9 ramdisk.img

到此ramdisk就制作好了,拷贝到U盘上:

#cp ramdisk.img.gz /boot/initrd.img

一切准备就绪,启动虚拟机,如果正常进入命令提示符,就算成功了一大半了:

9c95d17cc0c10f890b2701a7f5adbff3.png

这次重新编译内核,断断续续的花了一周时间,"mount root fs"的错误比较恼人,重复编译/测试了十几次,才最终找到ramdisk大小配置的问题。另外etc目前是空置的(没错,没有任何配置文件内核也可以可以启动的:-(),但是一些依赖相关配置文件的功能可能就没法正常工作,例如fdisk和df等,这部分留在后面继续研究吧。

参考:

http://www.ibm.com/developerworks/cn/linux/l-initrd.html

相关

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值