欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用U盘在电脑端启动linux内核(kernel)最小系统

程序员文章站 2022-03-05 16:54:24
...

本文记录我制作u盘驱动的过程,按照这篇教程,你可以得到一个装有kernel 版本linux-5.8.9操作系统的u盘,可以启动x86架构的主板,文件系统使用busybox制作。


o制作u盘启动linux系统
o所需工具
o第一步为u盘分区
o第二步为u盘安装grub
o第三步编译kernel
o第四步制作文件系统

所需工具

高质量u盘一个,容量大于4G
linux-5.8.9.tar.xz源码
busybox-1.32.0.tar.bz2源码
装有ubuntu系统pc一台

注意:

u盘不能使用那种扩容的劣质u盘,因为可能找不到u盘的mbr;

内核源码下载地址https://www.kernel.org/
busybox源码下载https://busybox.net/

第一步、为u盘分区

宿主机可以使用ubuntu也可以是装有vmware的win7,有一个linux运行环境即可,因为要使用linux命令fdisk为u盘分区;按照以下步骤做保证能成功。

1.在ubuntu中使用fdisk -l找到我们的u盘,例如根据大小判定我们的u盘为/dev/sdb

2.使用fdisk /dev/sdb进入fdisk界面,m打印帮助信息

3.使用o命令清除分区信息,使用n命令为u盘分两个区,200M+4G+剩余空间,200M用于boot分区,4G用于交换分区,剩余空间自己使用;(其实有一个分区就可以了,因为我们的u盘启动后,直接就可以拔掉了,kernel是运行在内存中的)

4.使用a命令设置1分区为活动分区

5.使用t命令设置2分区为82交换分区(没有就可以不用设置)

6.使用w命令保存并退出

7.有了分区了,但是分区里还没有文件系统,也就不能使用,我们使用mkfs.ext3 /dev/sdb1将我们的boot分区格式化,也可以使用mkfs.ntfs /dev/sdb3将其余空间格式化为win7可识别分区

第二步、为u盘安装grub

下面为u盘安装grub,其实就是在u盘前512字节写入我们想要的mbr,电脑启动后经过bios引导,识别到u盘为第一启动盘后,读取u盘前512字节,这512字节记录了u盘分区信息;这样就知道了活动分区,然后根据活动分区中装有的grub和grub配置信息找到kernel和initrd涉及到的grub命令有grub-install和update-grub

接下来的步骤

1.将u盘boot分区挂在到一个目录,例如我的:mount /dev/sdb1 /mnt/rootfs

2.grub-install –root-directory=/mnt/rootfs /dev/sdb

3.添加grub.cfg文件,该文件就是开机选择启动项的配置文件

路径在u盘boot分区的/boot/grub/grub.cfg,下面是我的grub.cfg

menuentry ‘Name of the kernel,u can edit by yourself’ --class ubuntu --class gnu-linux --class gnu {
insmod gzio
insmod ext2
search --no-floppy --fs-uuid --set=root 00a1d7dc-9221-4237-a7b7-cf20c8ad98ac
linux /vmlinux
initrd /initrd
}

解释:
search 开头行的root后面空格接你boot分区的uuid
vmlinux文件是你boot目录里将要放的kernel
initrd文件是boot目录将要放的linux系统文件
uuid查看方法是使用blkid命令找到对应的启动分区的编号。
至此,你可以将u盘插入电脑,设置bios的u盘为第一启动,我是用的是宏碁台式机,开机后按F12进入选择boot 的device,此时选择对应U盘的按回车就OK了,进入引导程序grub界面,根据提示 输入e 进入编辑模式,如果没有错误的话将看到你grub.cfg中的menuentry中的命令了,也可以临时更改里边的命令,改完后之间按F10 boot,就会加载kernel和initrd,不想更改grub.cfg的话可以直接按回车boot,但是回车后还不能进入,so 还没有拷贝kernel和initrd啊!

第三步、编译kernel

将下载好的kernel解压,使用tar -xvf ./linux-5.8.9.tar.xz;然后进入到kernel目录cd linux-5.8.9,下面开始编译 因为我的busybox使用的是64位的所以要做以下的操作:

1、make x86_64_defconfig
2、Make menuconfig
(1)General setup  ---> 
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support  
(2)Device Drivers  --->
[*] Block devices  --->
<*>   RAM block device support
(16)   Default number of RAM disks 
(8196) Default RAM disk size (kbytes)
(3)
File systems  --->
<*> Second extended fs support
<*> The Extended 3 (ext3) filesystem 

相关的文件系统类型要选择好。
配置完,使用make命令生成bzimage镜像
至此在linux-5.8.9的/arch/x86/boot/bzImage 文件是存在的
然后将bzImage拷贝到u盘的boot分区,并改名字为vmlinux

第四步、制作文件系统

解压busybox源码,cd到解压后的目录中,使用make menuconfig配置,至于配置选项,采用默认即可,需要知道与注意的选项是busybox生成的文件系统有静态链接方式和动态链接方式,所谓静态库就是在bin目录下的busybox程序不需要库文件,因为库文件已经静态编译到程序中了;动态链接方式不能直接运行/bin目录下busybox程序,因为busybox需要动态库支持,这就需要将busybox所需的库文件和链接文件copy到lib目录。为了简单期间可以采用静态链接方式( [*] Build static binary (no shared libs))。这样在busybox源码根目录下make后,make install 在当前目录会生成一个_install目录,直接将该目录下的内容复制出来即可。
我们制作的u盘启动项可以在kernel运行起来后拔掉u盘,这是因为我们采用intrd的内存加载方式运行kernel,那么怎么制作initrd呢?

1.在你的电脑上创建一个目录用来制作initrd文件系统,mkdir homeDir
2.将busybox生成的_install目录下的所有内容拷贝到homeDIr目录
3.注意将homeDIr中的linuxrc改名为init
4.在homeDir目录中的etc目录下创建inittab文件,文件内容:

::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:reboot
::shutdown:/etc/init.d/shutdown.sh

5.在homeDir/etc/init.d/目录下创建rcS文件,文件内容为创建所需目录,创建dev目录节点,mount虚拟文件系统等。

#! /bin/sh
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

6.在homeDir目录下创建一个脚本,用来生成initrd文件,文件内容:

#!/bin/sh
rootDir=/tmp
rm -rf $rootDir/initrd
find .|cpio -o -H newc |gzip -9 > $rootDir/initrd
echo “create initrd successed !!

7.将生成initrd文件拷贝到u盘的boot分区根目录下。

这里需要注意的知识点如下:
弄清楚三个文件之间的调用关系,initrc/inittab/rcS。kernel启动后在kernel_start中调用init等函数,函数会执行boot分区根目录下的initrc,initrc会调用/etc/inittab,然后inittab执行/etc/init.d/rcS,至此进入了命令行终端,系统就起来了。其实还有其他很多细节需要处理,例如需要在rcS中设置网络ip,设置登录帐号密码,设置用户名,设置自动磁盘挂载,设置驱动动态加载等等。
弄清楚busybox的udev和mdev区别,以及两个命令与hotplug的机制;简单说就是当有热插拔时间成生时,kernel发送事件的给hotplug注册的函数,如果使用udev的话,udev会根据接受到的事件和自己的配置信息执行特定的同做,例如在dev目录下创建节点,执行驱动程序的动态加载等操作。具体信息建议自行百度.
fstab文件和mount -a/umount -a命令的使用
passwd和shadow文件的作用以及使用如下命令

[[email protected] ~]# openssl passwd -1 -salt $(< /dev/urandom tr -dc ‘[:alnum:]| head -c 32)

感谢以及参考:
https://blog.csdn.net/mr_zhaojy/article/details/51438199

相关标签: 嵌入式系统