如何基于linux制作系统 (自制linux系统)

环境:

OS:Ubuntu 20.04
gcc: gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)
Linux Kernel: linux-5.4.50(2020-07-01 08:50)
busybox: busybox-1.32.0(2020-06-26 19:30)
qemu: qemu-system-x86_64 4.2.0

前言本文将带你体验30分钟自制属于自己的Linux系统

30分钟自制属于自己的Linux系统

自制linux系统

1.*载下**和编译Linux kernel

1.1 *载下**Linux内核

Linux内核官网:https://www.kernel.org/

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.50.tar.xz

wget https://mirror.bjtu.edu.cn/kernel/linux/kernel/v5.x/linux-5.4.50.tar.xz

1.2 安装所需前置软件

sudo apt-get install fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

1.3 设置CPU架构(★)

这里以x86_64架构为例。常用的架构还有arm64(鲲鹏、飞腾)、mips(龙芯)、alpha(申威)

# 设置CPU架构
$ export ARCH=x86_64

# 设置交叉编译工具链前缀
$ export CROSS_COMPILE=x86_64-linux-gnu-

1.4 设置系统选项

# 生成x86_64的默认.config
$ make  x86_64_defconfig

# 设置系统选项
$ make menuconfig

以下的配置选项是为了支持ramdisk根文件系统:

    General setup  --->
        ...
        [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
        ...
    ...
    Device Drivers  ---> 
        ...
        [*] Block devices  ---> 
            ....
            <*>   RAM block device support
            (16)    Default number of RAM disks  
            (65536) Default RAM disk size (kbytes)
            ....
        ...
    ....

1.5 编译

AMD 4800H CPU 8G内存16线程大约需要3分钟编译

# 根据CPU线程数设置
$ make -j 16

最后编译完成的内核位于arch/x86/boot/bzImage

$ ls -l arch/x86/boot/bzImage
-rw-rw-r-- 1 dev dev 8897920 8月   1 16:08 arch/x86/boot/bzImage

至此,Linux kernel编译完成

linux-5.4.50文件夹编译完的磁盘占用情况

$ du -lh --max-depth=1
208K	./LICENSES
48M	./Documentation
12M	./lib
43M	./sound
41M	./tools
824K	./init
6.7M	./crypto
780K	./virt
8.9M	./mm
48M	./include
25M	./kernel
5.5M	./scripts
120K	./certs
61M	./fs
215M	./arch
1.6M	./samples
6.1M	./security
63M	./net
128K	./usr
4.4M	./block
1020K	./ipc
681M	./drivers
1.5G	.

2.*载下**和编译busybox

busybox 将许多具有共性的小版本的UNIX工具结合到一个单一的可执行文件。这样的集合可以替代大部分常用工具比如的GNU fileutils,shellutils等工具,busybox提供了一个比较完善的环境,可以适用于任何小的嵌入式系统。

2.1 *载下**busybox

*载下**地址:https://busybox.net/downloads/

wget https://busybox.net/downloads/busybox-1.32.0.tar.bz2

2.2 设置CPU架构(★)

这里以x86_64架构为例。

# 设置CPU架构
$ export ARCH=x86_64

# 设置交叉编译工具链前缀
$ export CROSS_COMPILE=x86_64-linux-gnu-

2.3 设置系统选项

# 生成默认.config
$ make  defconfig

# 设置busybox选项
$ make menuconfig

修改选项

    ...
    Settings  ---> 
        ...
        # 静态编译busybox
        --- Build Options  
        [*] Build static binary (no shared libs) 
        ...
    ...

2.4 编译

# 根据CPU线程数设置
$ make -j 16

安装busybox,默认路径为当期目录的_install文件夹

make install

至此,busybox静态编译完成

busybox-1.32.0文件夹编译完的磁盘占用情况

$ du -lh --max-depth=1
636K	./examples
256K	./mailutils
268K	./findutils
2.3M	./archival
236K	./init
460K	./console-tools
5.2M	./networking
232K	./e2fsprogs
7.4M	./include
916K	./procps
1.4M	./docs
2.6M	./_install
216K	./sysklogd
4.0K	./.tmp_versions
1.7M	./scripts
520K	./applets
108K	./selinux
352K	./modutils
492K	./loginutils
180K	./debianutils
3.5M	./util-linux
28K	./arch
924K	./editors
6.9M	./shell
2.2M	./miscutils
2.9M	./coreutils
36K	./qemu_multiarch_testing
120K	./printutils
12K	./applets_sh
4.5M	./libbb
108K	./klibc-utils
112K	./libpwdgrp
252K	./configs
1.7M	./testsuite
408K	./runit
57M	.

3.制作ramdisk根文件系统rootfs

基于busybox制作ramdisk根文件系统rootfs.

基于busybox的文件系统启动过程:

/sbin/init => /etc/inittab => /etc/init.d/rdS => /etc/fstab ...

3.1 创建根目录所需的目录

$ cd busybox-1.32.0/_install

$ ls
bin  linuxrc  sbin  usr

$ mkdir -p dev etc home lib mnt proc root sys tmp var

$ ls
bin  dev  etc  home  lib  linuxrc  mnt  proc  root  sbin  sys  tmp  usr  var

根文件系统目录说明

/bin: 系统管理员和用户均可使用的命令

/sbin: 系统管理员使用的系统命令

/dev: 存储特殊文件或设备文件;设备两种类型:字符设备、块设备/etc: 系统配置文件/home: 普通用户目录

/root:root用户目录/lib: 为系统启动或根文件上的应用程序(/bin,/sbin等)提供共享库,以及为内核提供内核模块

/mnt:临时挂载点/tmp: 临时文件存储目录

/usr:usr hierarchy,全局共享的只读数据路径

/var:存储常发生变化的数据目录:cache、log等/proc: 基于内存的虚拟文件系统,用于为内核及进程存储其相关信息

/sys:sysfs虚拟文件系统提供了一种比proc更为理想的访问内核数据的途径:其主要作用在于为管理linux设备提供一种统一模型的接口;

3.2 创建根目录所需的必要文件

  • etc/inittab
$ cd busybox-1.32.0/_install
$ vim etc/inittab
$ chmod 755 etc/inittab

etc/inittab内容:

::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::cttlaltdel:/bin/umount -a -r

inittab语法:

<id>:<runlevels>:<action>:<process>

id : /dev/id
runlevels : 忽略
action : 何时执行,有以下选项 sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, and shutdown
process : 应用程序或脚本
  • etc/init.d/rcS
$ cd busybox-1.32.0/_install
$ mkdir -p etc/init.d/
$ vim etc/init.d/rcS
$ chmod 755 etc/init.d/rcS

etc/init.d/rcS内容:

echo "----------mount all in fstab----------------"
/bin/mount -a #读取/etc/fstab,加载文件系统
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
echo "****************Hello itas109******************"
echo "Kernel Version:linux-5.4.50"
echo "***********************************************"
  • etc/fstab
$ cd busybox-1.32.0/_install
vim etc/fstab

etc/fstab内容:

#device mount-point type option dump fsck
proc  /proc proc  defaults 0 0
temps /tmp  rpoc  defaults 0 0
none  /tmp  ramfs defaults 0 0
sysfs /sys  sysfs defaults 0 0
mdev  /dev  ramfs defaults 0 0
  • 添加设备文件
$ cd busybox-1.32.0/_install
$ cd dev
$ sudo mknod console c 5 1
$ sudo mknod null c 1 3
$ sudo mknod tty1 c 4 1

制作根文件系统镜像文件rootfs.img.gz

$ cd busybox-1.32.0
$ vim makeRootfs.sh
$ chmod +x makeRootfs.sh
$ ./makeRootfs.sh
记录了32+0 的读入
记录了32+0 的写出
33554432 bytes (34 MB, 32 MiB) copied, 0.0351642 s, 954 MB/s
mke2fs 1.45.5 (07-Jan-2020)
丢弃设备块: 完成                            
创建含有 8192 个块(每块 4k)和 8192 个inode的文件系统

正在分配组表: 完成                            
正在写入inode表: 完成                            
创建日志(1024 个块) 完成
写入超级块和文件系统账户统计信息: 已完成

makeRootfs.sh内容

#!/bin/bash

sudo rm -rf rootfs.ext3
sudo rm -rf fs
dd if=/dev/zero of=./rootfs.ext3 bs=1M count=32
mkfs.ext3 rootfs.ext3
mkdir fs
sudo mount -o loop rootfs.ext3 ./fs
sudo cp -rf ./_install/* ./fs
sudo umount ./fs
gzip --best -c rootfs.ext3 > rootfs.img.gz

4.Linux系统运行

cd ~
$ qemu-system-x86_64 \
  -kernel ./linux-5.4.50/arch/x86_64/boot/bzImage  \
  -initrd ./busybox-1.32.0/rootfs.img.gz   \
  -append "root=/dev/ram init=/linuxrc"

启动结果:

[    0.000000] Linux version 5.4.50 (dev@dev) (gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #1 SMP Sat Aug 1 16:05:18 CST 2020

...

****************Hello itas109******************
Kernel Version:linux-5.4.50
***********************************************

Please press Enter to activate this console. 
/ # uname -a
Linux (none) 5.4.50 #1 SMP Sat Aug 1 16:05:18 CST 2020 x86_64 GNU/Linux