实践:一步一步安装 ArchLinux,并编译、安装【RT-Preempt】实时内核

IOT物联网小镇

共 7799字,需浏览 16分钟

 · 2022-05-31

目录

  • 制作U盘启动系统

  • 从 U盘启动,安装 ArchLinux

    • 1. U盘启动

    • 2. 硬盘分区

    • 3. 网络配置

    • 4. 更换软件管理套件的镜像地址

    • 5. 挂载文件系统,进行安装

    • 6. 系统配置

    • 7. 安装 grub bootloader

  • 安装软件包管理软件Pacaur

    • 通过源码来安装

    • 通过Yaourt来安装

  • 更换实时内核(RT-Preempt)

    • 1. 下载Linux内核和Preempt补丁文件

    • 2. 配置实时策略Fully Preemptible Kernel (Real-Time)

    • 3. 编译和安装内核

    • 4. 制作和安装RAM Disk

    • 5. 复制System.map文件

    • 6. 更新GRUB配置文件

不知不觉使用Ubuntu系统已经好多年了,在Linux所有发行版中,使用最多的估计仍旧是Ubuntu,主要的原因就是稳定,使用的人多,遇到问题了也很容易找到解决方案。

最近看到一句话:入门ubuntu,不满足manjaro,得心应手之后arch,还想折腾就上gentoo

看来我仍然在入门的一亩三分地里折腾着,正好家里有一台淘汰下来的台式机,正好可以用来折腾一下。

调研了一番之后,决定安装ArchLinux,这篇文章就记录一下安装过程,遇到的一些坑,以及在更换带有 RT-Preempt 补丁的内核时,遇到的几个内核配置问题。

  1. manjaro 是 ArchLinux 的一个发行版,使用的人也不少;

  2. 如果想对 Linux 的搭建有更底层的掌握,可以花 1-2 周的时间,按照 LFS 的操作步骤走一遍。

本文主要参考:https://itsfoss.com/install-arch-linux/

官方给出的电脑硬件要求是:

制作U盘启动系统

下载 ISO 文件

ArchLinux官网上(https://archlinux.org/download/)给出了很多的镜像下载链接,可以从163网站(http://mirrors.163.com/archlinux/iso/)下载。

选择一个版本:archlinux-2022.05.01-x86_64.iso

下一步就是把镜像文件制作成U盘启动系统,在WindowsLinux上都可以。

Windows上可以使用rufus软件来制作启动U盘启动系统(我选择的也是这个方式)。

如果在Linux系统上,可以使用dd命令来制作:

sudo dd bs=4M if=/path/to/archlinux.iso of=/dev/sdx status=progress && sync

从 U盘启动,安装 ArchLinux

1. U盘启动

把U盘插入电脑,重启之后选择从U盘启动(根据自己电脑的设置,在启动时按下F2、F7或其它按键)。

这个图片是参考文档中的,根据系统的不同,选项的内容也可能稍有区别。

在我的系统中,选择 Arch Linux install medium (x86_64, UEFI)选项进入 live U盘中的系统。

这一步其实就相当于是安装Ubuntu系统中时的Try Ubuntu

一切顺利的话,系统加载运行之后,进入命令行界面,下面就开始一步一步安装ArchLinux操作系统了。

首先,通过查看文件efivars来确认系统是否支持 EFI

执行命令:ls /sys/firmware/efi/efivars,如果能看到一大堆的输出信息,就说明支持。

关于 EFI 系统以及系统引导流程(主要是与 MBR 那一套的区别),可以去搜索一些资料。

2. 硬盘分区

使用fdisk -l来确定一下硬盘设备名称,例如:/dev/sda

也可以使用其它的分区工具,例如:gdisk,cgdisk,sgdisk。

在硬盘上,很可能已经存在了分区表,因为之前可能在这个硬盘上安装过操作系统啊。

建议先把这些分区表全部删除掉,然后重新进行分区。

分区操作通过指令:fdisk /dev/sda来操作。

如今大部分系统支持的都是UEFI系统,因此需要创建一个EFI分区,建议分 512 MB

创建这个分区之后,需要把分区类型修改为EFI类型。

具体操作是:输入指令 t,再输入 EFI前面对应的序号。

参考文档中的序号是:

但是,如果选择的系统版本不同,这里的序号可能是不一样的。在我选择的系统中,EFI类型的编号是数字 1

EFI分区创建好之后,再创建一个根分区就可以了,与安装其它的发行版一样。

最终创建的两个分区名称是:

  1. EFI 分区:/dev/sda1

  2. 根分区:/dev/sda2

硬盘分区的最后操作就是格式化这两个分区:

  1. mkfs.fat -F32 /dev/sda1

  2. mkfs.ext4 /dev/sda2

3. 网络配置

为了在后面的步骤中顺利的在线安装,官方文档中对WiFi进行了设置。

由于我的电脑使用的RJ45有线连接,所以就没有进行这一步的操作。

4. 更换软件管理套件的镜像地址

我们在安装Ubuntu操作系统之后的第一步,一般都是更改apt的软件源,设置为国内比较知名的软件源。

ArchLinux默认的官方软件管理套件是pacman(还有其它的管理套件,下面会讨论到),为了加快下载速度,也需要根据我们所处的地理位置修改为比较快的软件源。

依次执行如下命令:

同步仓库:pacman -Syy

获取所有的仓库列表:pacman -S reflector;

备份一下原始文件:cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak;

选择合适的仓库:reflector -c "ZH" -f 12 -l 10 -n 12 --save /etc/pacman.d/mirrorlist

5. 挂载文件系统,进行安装

此刻执行的是位于U盘中的系统,现在需要做的是把操作系统安装在刚才创建的分区 /dev/sda2

首先把分区挂载一下: mount /dev/sda2 /mnt

挂载之后,就可以使用pacstrap脚本来安装ArchLinux以及一些软件包了:

pacstrap /mnt base linux linux-firmware vim

安装过程需要的时间,根据电脑性能和网络情况而定,总之还是比较快的。如果在安装过程中因为网络等原因中断了,再次执行即可。

6. 系统配置

系统配置包括:文件系统挂载文件fstab,设置系统时区,设置密码等等,一步一步来操作。

首先创建fstab文件:genfstab -U /mnt >> /mnt/etc/fstab

然后把根文件系统切换到分区/dev/sda2对应的挂载点/mnt,因为现在要配置的是刚才被安装的根文件系统,所以需要切换进去。

切换命令是:arch-chroot /mnt

执行命令:timedatectl list-timezones 列出支持的所有时区。

然后执行命令 timedatectl set-timezone Asia/Shanghai把时区设置为自己的实际位置。

最后,进行语系设置。使用vim命令打开文件 /etc/locale.gen,打开下面2个选项:

en_US.UTF-8 UTF-8
zh_CN.UTF-8 UTF-8

然后执行命令:locale-gen

创建文件:/etc/locale.conf, 添加如下内容:

LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8

创建文件:/etc/hostname,添加如下内容:

myarch

创建文件:/etc/hosts,添加如下内容:

127.0.0.1   localhost
::1 localhost
127.0.1.1 myarch

最后,通过指令 passwd来设置root密码。

7. 安装 grub bootloader

这一步比较关键,确保当前的根目录是处于/dev/sda2中(也就是上一步chroot所做的动作)。

首先,安装需要的软件:pacman -S grub efibootmgr

在之前的分区表中,/dev/sda1分区类型已经被设置为EFI System,并且被格式化成FAT32文件格式。

现在,需要grub引导程序安装到这个分区上,所以首先需要把这个分区挂载一下。

创建挂载点目录:mkdir /boot/efi,然后执行挂载命令:mount /dev/sda1 /boot/efi

安装grub引导程序也是通过软件来执行的,命令如下:

grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi

安装成功之后,执行如下命令来更新grub的配置文件:

grub-mkconfig -o /boot/grub/grub.cfg

进行到这一步的时候,ArchLinux就安装完成了。

在参考文档中还执行了其他的一些操作,比如:添加用户,安装桌面系统,这些都根据个人的实际需要来操作。

因为我不需要桌面,所以在这里重启系统就完事了。

注意:在重启之前先退出chroot

exit
reboot

【本文作者】公-众-号:“Linux茶馆”,是我在工作之余个人维护的分享平台,十多年的嵌入式开发老兵,专注于嵌入式 + Linux 领域,玩过单片机、搞过智能家居、研究过 PLC工业机器人。厚积薄发、换位思考,以读者的角度来总结文章。每一篇输出,不仅仅是干货的呈现,更是引导你一步一步的深入思考,从底层逻辑来提升自己。

安装软件包管理软件Pacaur

ArchLinux中默认的软件管理套件是pacman,可以在官网中看到所有的软件列表 https://archlinux.org/packages/

另外,还有一个软件管理套件也比较流行:PacaurArchlinux自带的 pacman不能直接安装Pacaur

有两种方式来进行安装:通过源码安装和通过其它工具(Yaourt)来安装

在通过源码安装这个管理套件的时候,我遇到了一些麻烦。虽然没有成功,还是记录于此,以后有机会再试一下。

通过源码来安装

1. 安装必要的软件

pacman -S binutils make gcc fakeroot expac yajl git --noconfirm

2. 安装Cower:用于从AUR获取信息并下载软件包

curl -o PKGBUILD https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=cower
makepkg PKGBUILD --skippgpcheck
pacman -U cower*.tar.xz --noconfirm

3. 安装Pacaur

curl -o PKGBUILD https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=pacaur
makepkg PKGBUILD
pacman -U pacaur*.tar.xz --noconfirm

通过Yaourt来安装

1. 安装Yaoourt

sudo pacman -S --needed base-devel git wget yajl
cd /tmp
git clone https://aur.archlinux.org/package-query.git
cd package-query/
makepkg -si && cd /tmp/
git clone https://aur.archlinux.org/yaourt.git
cd yaourt/
makepkg -si

2. 通过Yaourt来安装Pacaur

yaourt -S --noconfirm pacaur

更换实时内核(RT-Preempt)

现在的Linux内核一般都是面向桌面系统的,在一些工控场景中需要打上软实时内核补丁RT-Preempt,并且选择Fully Preemptible Kernel (Real-Time)这个实施策略

如果您不需要实时内核,仅仅想把内核升级成新的版本,那么可以直接通过 pacman,在线安装、更新 Linux 内核。

在编译、更换实时内核的时候,我也遇到了几个问题下面一一记录于此,主要参考文档:https://wiki.archlinux.org/title/Kernel/Traditional_compilation

在编译内核之前,需要安装几个必要的软件:

pacman -S cpio pahole pacman-contrib asp

1. 下载Linux内核和Preempt补丁文件

Linux 内核选择版本linux-5.15.36.tar.gz ,下载地址:https://www.kernel.org/

RT-Preempt 补丁选择与内核对应的版本:patch-5.15.36-rt41.patch.gz,下载地址:https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.15/older/

或者也可以直接下载已经打好补丁的内核版本:linux-stable-rt-5.15.36-rt41.tar.gz

创建工作目录:mkdir ~/kernelbuild,把下载好的内核和补丁放在其中,并且各自解压出来。

cd 进入~/kernelbuild/linux-5.15.36目录,执行如下命令打上实时补丁:

patch -p1 < ../patch-5.15.36-rt41.patch

2. 配置实时策略Fully Preemptible Kernel (Real-Time)

打上补丁之后,首先执行 make mrproper清除历史编译记录,让内核保持干净的状态。

配置内核,最终目的就是得到.config这个文件,在下面进行内核编译的时候,内核中的Makefile就会根据.config中的配置,来执行对应的编译动作。

常用且保险的方式就是:以当前正在使用的操作系统所使用的配置文件作为蓝本,进行适当的修改配置,来得到最终的.config文件

首先执行如下命令来得到当前系统的内核配置文件:

$ zcat /proc/config.gz > .config

然后执行指令:make menuconfig,进入内核配置界面。

实时策略配置项一般位于路径:【General setup】-【Preemption Model】中。

但是进入之后会发现:只有3个选项,没有预期的 【Fuly Preemptible Kernel(Real-Time)】这个选项。

在查阅资料的时候,有一个解决方案说:打开 【 General Setup 】 -> 【 Embedded System 】之后,就可以选择实时策略了。

的确如此!但是这个打开这个配置之后,编译出的内核无法启动

我没有对比打开【 Embedded System 】这个选项之后对配置文件的改动,以后可以再研究一下。

正确的解决方案是:

把【General setup】->【Confiure standard kernel features (expert users)】勾选之后,实时策略选项就显示出来了。

配置好实时策略之后,我就开始编译、安装了,但是重启之后,选择新内核无法启动,提示如下错误:

mount: /sys/firmware/efi/efivars: unknown filesystem type 'efivarfs'

在尝试了两个错误的解决方案之后,最终通过下面这个方案解决了这个问题:


3. 编译和安装内核

实时策略问题解决了,然后依次执行如下指令来编译内核:

make -j4
make modules -j4

编译内核的时间比较久,主要取决于电脑的性能。

编译成功之后,执行安装命令:

make modules_install
cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux515

bzImage文件仅仅是一个软链接,最终指向的是 arch/x86_64/boot 目录下的同名文件。

4. 制作和安装RAM Disk

这一步的主要目的就是生成initramfs-linux515.img虚拟内存文件,并复制到/boot目录中。

initramfs的主要作用就不赘述了,主要就是在操作系统挂载真正的根文件系统(/dev/sda2)之间,作为临时的根文件系统来使用。

制作 initramfs文件需要使用工具 mkinitcpio 和必要的配位文件。

首先把系统中当前的配置文件备份一下:

cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux515.preset

然后编译该配置文件:vim /etc/mkinitcpio.d/linux515.preset,修改下面的三行内容:

ALL_kver="/boot/vmlinuz-linux515"
default_image="/boot/initramfs-linux515.img"
fallback_image="/boot/initramfs-linux515-fallback.img"

最后,执行mkinitcpio,来生成initramfs-linux515.img文件。

mkinitcpio -p linux515

5. 复制System.map文件

System.map文件是在编译linux内核的时候生成的,直接把它复制到/boot目录下即可:

cp System.map /boot/System.map

参考链接中做了一个软链接,效果是一样的。

6. 更新GRUB配置文件

这一步千万不要忘记了!更新命令是:

grub-mkconfig -o /boot/grub/grub.cfg

至此,更换实时内核的所有操作就全部结束了!

重启之后,选择新的实时内核来启动(在内核启动列表中,带有-rt字眼的),即可顺利进入系统!

如果想看一下实时系统对任务处理的实时性,可以通过rt-tests这个软件包来测试(可以与非实时系统对比一下)

pacman -S rt-tests            // 安装测试软件
cyclictest --smp -p 100 -m // 执行测试命令

------ End ------

既然看到这里了,如果觉得不错,请您随手点个【赞】和【在看】吧!

如果转载本文,文末务必注明:“转自微信公众号:IOT物联网小镇”。


推荐阅读

【1】《Linux 从头学》系列文章

【2】C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻

【3】原来gdb的底层调试原理这么简单

【4】Linux中对【库函数】的调用进行跟踪的3种【插桩】技巧

【5】内联汇编很可怕吗?看完这篇文章,终结它!

【6】gcc编译时,链接器安排的【虚拟地址】是如何计算出来的?

【7】GCC 链接过程中的【重定位】过程分析

【8】Linux 动态链接过程中的【重定位】底层原理

其他系列专辑:精选文章应用程序设计物联网C语言


星标公众号,第一时间看文章!


浏览 46
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报