从0开始构建自己的U盘Linux(一)
从0开始构建自己的U盘Linux
前期知识储备
1.1本项目介绍
(1)开发环境
主机:Dell xps13 9360 , 操作系统Windows 10, 64-bit , USB3.0接口
虚拟机:ubuntu-18.04.2-desktop-amd64,运行在VMware® Workstation 15 Pro ,版本15.0.2 build-10952284
(2)项目内容
参考《嵌入式系统原理与设计》(浙大出版社 王勇编著)完成的本书后面一个“从0开始构建自己的U盘Linux”的实验,里面步骤中的linux内核比较老,和新的会有出入。即:
不使用U盘Linux工具,而是在Ubuntu中从0开始,自己一步步构建一个U盘存储的Linux操作系统,可以加深自己对Linux的基本开发过程的了解,这是学习嵌入式的很好的一个方法。
以下内容主要分为:Linux及其相关内容简介、构建Linux的详细过程、遇到的问题和解决方法(详见从0开始构建自己的U盘Linux(二))。
如果是第一次接触Linux系统,比如我,建议先了解Linux的以下内容,在网上搜索,都有很详细的内容,这里就不详细列出来了。
- Linux 系统启动过程
Linux启动时我们会看到许多启动信息。总体概括下来,其过程可以分为5个阶段:
(1)内核的引导
(2)运行 init :init程序的类型——SysV、Upstart、Systemd
(3)系统初始化
(4)建立终端
(5)用户登录系统 - Linux文件系统结构
- 分析源码目录
- .config文件
一些配置项;
make xx_defconfig和make menuconfig相配合 … 等等,例如make x86_64_defconfig - 常用命令介绍
第一次使用linux,对一些终端操作的命令不熟悉,可以在网上搜索相关的指令用法,在本实验中常用cd、vim/gedit、apt-get、tar、cp、make、touch(可新建文件夹)、fdisk、mkdir、mount等等
Linux内核源码下载
对于完全安装ubuntu的可以在/usr/src下找到linux源码,对于非完全安装(本人),需要手动下载源代码,有以下两种方式,我用过第二种和第三种:
A.在主机上从http://www.Linux.org官网下载,再拖到ubuntu中
B. ubuntu终端下载
apt-get install linux-source-4.18.0
C. 终端中访问服务端下载:
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.1.tar.xz
通过sudo -i 输入密码,进入root权限,再进行之后的操作。
-
首先看一下自己的内核版本,如果不想下载和自己正在使用的内核匹配的版本,可以忽略这一步
apt-cache search linux-source
-
下载内核代码,在做本次实验中,我下载过好几个版本的Linux内核,后来用的是4.11.1
apt-get install linux-source-4.18.0
或者wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.1.tar.xz
-
在哪个目录下执行上面操作的,就到该目录下查看你已经下载好的源码,我在/home/pumpkin中
-
解压源码,我选择解压到/home/pumpkin(用户名)下面:
1)后缀.bz2的解压(tar相关操作可自行搜索)tar -jxv -f linux-source-4.18.0.tar.bz2 -c /home/pumpkin
2)后缀.xz的解压xz -d linux-4.11.1.tar.xz
tar xvf linux-4.11.1.tar
等待其解压完成,现在可以到/home/pumpkin 目录下面进行查看:
Linux源码编译
- menuconfig准备
如果ubuntu安装时候没有选择全部安装,这个过程会遇到缺少很多包的问题,可能出现的错误:ncurses库没装、屏幕太小等等。所以建议一次性把可能需要的包在这里全部安装了:apt-get install libncurses5-dev libncursesw5-dev
apt-get install ncurses-devel
apt-get install bison -y
apt-get install flex
- 配置内核
.config决定了Make时的条件编译与连接。.config文件由两次配置,第一次make xxx_defconfig ,第二次menuconfig。自行百度linux内核、make xxx_defconfig作用等等,能够帮助我们理解之后的各个步骤。
(1)make x86_64_defconfig
输入:make x86_64_defconfig //64位元电脑
make xxx_defconfig这一步其实是参考别人已经做好的,这样做有很多好处:减少很多工作量,避开了很多自己不懂的配置项(譬如对内存管理的、调度系统的等模块的配置项),我们只用管自己需要管的。
最后只要出现:configuration written to .config
这句话,就证明我们的操作是正确的。如果没有出现这句话,就有错误:
(2)make menuconfig
不进行上面一步,直接make menuconfig也是可以,完全自定义配置,以下开始配置,建议自己多了解了解各个配置项,我做的时候对其中一些也不太了解… 网上多搜索,https://blog.****.net/linpuliang/article/details/38317367 博主详细地讲了一些配置项,《嵌入式》书中也有讲,但是里面是比较老的linux内核,和新的有些不同。
为了实现U盘Linux,必选:
·Device Drivers -> Block devices 下的 loopback device support, RAMblock device support
·Device Drivers ->SCSI Support 下的 SCSI device support 下的SCSI disk Support、 SCSI low-level drivers —> Buslogic SCSI support
· Device Drivers ->USB Support 下的Support for Host-side USB,Preliminary USB device filesystem ,USB Mass Storage support,xHCI HCD (USB 3.0) support(如果是电脑是USB2.0接口需要选2.0那个选项)
·File System -> ext3 // 文件系统的支持
后面要在U盘上面建立Linux文件系统,我建的是ext3,把ext3的选上了,默认是没有选的,第一个second extended fs support是ext2文件系统,建议都选…
Busybox工具
(1)从BusyBox的官方网站下载BusyBox的源代码
(2)将压缩文件放到/home/pumpkin/下载,注意/tmp是临时文件夹,在关机后里面的内容会丢失,所以尽量不要放到/tmp下面,此处选择放在用户目录下,可以再关机重启后继续使用。
(3)解压缩,可以在终端操作,也可以在这里直接在文件夹里面右键buzybox-1.30.0.tar.bz2解压到该目录下:
(4)配置Busybox,输入:make defconfig //使用默认配置,让busybox包含常用命令和工具
make menuconfig //在上述基础上,自己更改配置
开始配置,需要和建议选择的有:
BusyBox Setting->Build Options->[ ]Build Busybox as a static binary (no shared libs)
BusyBox Setting->Shells->chose your default shell(ash):
BusyBox Setting->Installation Options->[*]Don’t use /usr(否则busybox会安装到ubuntu的/usr下,会覆盖原系统原有的命令)
BusyBox Setting->Shells->chose your default shell(ash):
(5)编译和安装busybox:mak
make install
执行完后会产生_install/bin/ 和_install/sbin/后面会用到这些文件,ls一下会发现多了一个 _install 目录,里面是bin、sbin等,我们要用它来构建linux的根目录。
无盘构建根文件系统
这里没有直接在U盘中构建根目录,而是在虚拟机中构建一个根文件系统的镜像压缩,之后复制到U盘中。如果直接在U盘中构建,之后有什么错误需要格式化U盘,就没必要重新构建根文件系统,把压缩文件复制过去即可。
(1)在用户目录下新建rootfs,把_install目录中的内容复制进去,现在rootfs下已经有了bin、sbin目录
(2)一个完整linux系统还需要添加其他必要文件夹,进入/rootfs,输入:mkdir usr proc mnt var tmp dev sys etc
(3)同时在rootfs下还必须要有一个init文件,这个init文件可以是一个可执行的二进制文件,也可以是一个shell脚本,或者是指向前面两者的链接。init文件会在linux内核初始化就绪后被执行。方便起见,我们就把init做成一个指向bin/sh的软连接,在rootfs下输入:ln -s bin/sh init
(4)dev目录下还必须有几个必要的设备console,null,ram,tty,tty1,tty2,这些tty就是和用户交互的终端:
cd 进入/rootfs/dev,建立必须的设备节点文件,并授权,输入:mknod tty c 5 0
mknod console c 5 1
mknod null c 1 3
mknod ram b 1 0
mknod tty1 c 4 1
mknod tty2 c 4 2
chmod 666 tty console null
chmod 666 tty1 tty2
chmod 600 ram
(5)制作压缩镜像,输入:cd .. // 回到rootfs目录下
find . | cpio -H newc -o > ../rootfs.img // 返回 块数目:5157 块
cd .. //回到用户目录
gzip rootfs.img -f //压缩镜像
在U盘上构建Linux根文件系统
-
前期准备——在U盘上建立Linux分区和ext3文件格式
分区表:
推荐使用DiskGenius软件,在把U盘连接到虚拟机之前查看U盘的分区表格式,有些U盘是GUID格式的,如果不是MBR,建议转为MBR格式:
硬盘分区格式为MBR格式,启动模式应该为Legacy:
硬盘分区格式为GUID(GPT)格式,启动模式应该为UEFI:
Linux分区和文件系统:
对于建立Linux分区和ext2/ext3/ext4文件系统的更改都可以在DiskGenius中进行,比较直观,容易理解。
1)分区->删除当前分区
2)分区->建立新分区->主磁盘分区->选择文件系统类型 ext3或者ext4均可,ext2/ext3/ext4有区别,可在网络上自行搜索了解。(图中的512MB 我设置了1G)
我建立的是ext3文件系统:
成功: -
把U盘挂载入文件系统,进行文件操作
(1)把U盘插入物理机,在vmware界面下插入U盘的应该会弹出“检测到新的USB设备”,让你选择连接到的位置,这个过程中可能存在的问题在文章结尾问题部分有对应解决办法。
如果没有弹出,可以在vmware右下角,点击U盘图标选择连接主机:
(2)检查是否分区成功和连接成功
fdisk -l
返回的最后一行出现和刚才自己分区结果一样的U盘(1G,类型Linux),设备为 /dev/sdb1
(3)U盘挂载
mkdir /mnt/usb2 //新建一个usb文件夹 名字自己取
mount /dev/sdb1 /mnt/usb2 //然后把sdb1挂到usb2文件夹
(4)安装grub,显示最后一句话说明安装成功。这条命令会把grub安装到/dev/sdb中,即把grub的第一阶段(短于512字节的部分)放入/dev/sdb的第一扇区,并且把第二阶段要用到的各种文件放到当前目录(即/dev/sdb1分区承载的ext3文件系统)(更准确的说,是放在了/dev/sdb1/boot/grub下)
(5)把过去做好的bzImage和rootfs.img.gz复制到U盘的boot目录下
(6)配置grub.cfg
输入:
(7)卸载U盘,之后拔出U盘,即制作完成
测试
在虚拟机上测试。
- 更改虚拟机bios 的boot让它从U盘启动
(1)虚拟机设置->硬件 下方点击添加->硬盘->SCSI(推荐)
->使用物理硬盘
->drive0是主机的物理盘,不要选,一般都是drive1或drive2
-> 进入bios
->设置虚拟机bios 的引导顺序,用“+/-”把boot中Hard Drive(0:1) 即U盘放到第一个(红色下划线)
8.2 成功启动
启动,小企鹅的出现是内核配置了framebuffer原因,然而出现了两个…
·命令测试ls /cd /mkdir
命令测试ping:
·列出/bin下面支持的操作: