用 VMware 安装Linux虚拟机,还可以顺带做网安组的 Task,美滋滋。
安装准备
VMware 的安装
下载地址:https://www.nocmd.com/740.html
安装无脑下一步即可
Arch Linux 镜像
下载地址:http://mirrors.zju.edu.cn/archlinux/iso/2019.10.01/ (浙大源)
下载链接地址中的 archlinux-2019.10.01-x86_64.iso
若此地址下载缓慢,也可以进入官方的下载源集合:https://www.archlinux.org/download/
开始安装
VMware 配置
打开 VMware,首先点击文件选项 -> 新建虚拟机 -> 典型 -> 稍后安装操作系统 -> 选择 Linux 选项 -> 版本选择‘Linux4.x’,内存按需分配就可以,硬盘分配 40G 左右,根据自己需求来定,毕竟 Arch 一开始还算一个比较干净简洁轻量的 Linux release。网络类型选择 NAT,其他默认即可。
CD/DVD 选项记得选择 ArchLinux 镜像。
Arch Linux 安装准备
启动安装 archlinux
不论你使用的是 EFI 或 BIOS 引导,均选择 Boot Arch Linux(x86_64)这一选项
启动成功后就会进入命令行模式,此时如果你不清楚你用的是 EFI 引导还是 BIOS 引导,可以在此处列出 efivars 目录以验证启动模式来判断主板是以何种方式引导系统的(这对之后对硬盘的分区 十分有用):
1 | ls /sys/firmware/efi/efivars |
若该目录不存在,系统就可能以 BIOS 模式启动。
确认网络连接情况
如果你使用的是有线网络连接方式,那么 Arch Linux 在启动后,守护进程 dhcpcd 已被默认启用以探测有线设备,因此你只需验证网络是否正常即可
如果你使用的是无线网络连接方式,
Arch Linux 的安装必须使用网络才能完成,使用下面命令以验证网络是否正常:
1 | ping -c 4 www.baidu.com |
如果网络不正常,可能是由于 dhcp 服务没有开启,可以使用以下命令来开启此服务:
1 | systemctl enable dhcpcd.service |
更新系统时间
首先还是验证一下系统的时间是否正常:
1 | timedatectl status |
如果时间和当前时间对不上的话,使用下面命令来更新系统时间:
1 | timedatectl set-ntp true |
建立硬盘分区
硬盘如果被系统识别到,就会被分配为一个块设备,如/dev/sda;因此先查看一下硬盘的状态,以便于后续分区操作:
1 | lsblk |
屏幕显示如下:
这里 sda 即是我分配给虚拟机的 8GB 硬盘,因为此硬盘下还没有分区,所以 sda 节点下无任何显示;loop0 和 sr0 可以忽略。如果硬盘已经有分区,sda 节点下应当会显示如下图:
接下来我们要对这 8GB 的硬盘进行分区,能够创建分区的命令很多,如 fdisk,parted,cfdisk 等,这里使用 GUI 的 cfdisk 命令(在真机上分区时,请认真检查你的硬盘是否选择正确,如果你有多个硬盘,可能你要用来安装 Linux 的硬盘并不是如下所写的/dev/sda,而是/dev/sdb 也说不定。
1 | cfdisk /dev/sda |
对于一个硬盘,以下三个分区是必须要有的:
··· 一个根分区(挂载在根目录) /
··· 如果 UEFI 模式被启用,你还需要一个 EFI 系统分区,或者是通过 BIOS 启动,那么你需要建立的是 BIOS boot 分区
··· Swap 可以在一个独立的分区上设置,也可以直接建立交换文件
其中,Swap 分区的大小应与你物理机/虚拟机的内存大小相同,EFI 分区通常为 300M,BIOS boot 分区通常为 1G
具体 cfdisk 的使用命令,可以参考这篇文章:https://jingyan.baidu.com/article/ce09321bb922da2bff858fdd.html
分好区后确认写入分区到硬盘,然后退出分区工具,再次使用 lsblk 查看一下,显示如下图:
那么你就成功分好区了
格式化分区
分区完成后,需要对分区做格式化处理,如果你使用了 EFI 分区,因为 EFI 分区需要 FAT32 文件格式,所以需要将其格式化为 FAT32 格式;
EFI 引导分区推荐大小为 512M。
在这里我使用的是 BIOS 引导,但为了方便起见,我也将它格式化成 FAT32 文件格式。
根分区格式化为 ext4 格式;设置并开启 Swap 分区:
1 | mkfs.fat -F32 /dev/sda2 |
挂载分区
EFI 模式引导
格式化完成后,需要将分区挂载到 /mnt ,先挂载根分区(这里是/dev/sda2);再挂载 EFI 分区(这里是/dev/sda1),挂载 EFI 分区时,需要在/mnt 上先创建 boot/EFI 目录,然后将 EFI 分区挂载到/mnt/boot/EFI 上;Sawp 分区不需要挂载:
1 | mount /dev/sda3 /mnt |
BIOS 模式引导
1 | mount /dev/sda4 /mnt 注:sda4挂载为根 |
安装基本系统
选择软件镜像源
在安装基本系统之前,需要修改一下软件镜像源,不然安装基本系统时会安装不上。镜像源列表在 /etc/pacman.d/mirrorlist 文件中。
我们选择软件镜像源时,最好选择国内的镜像源,因为国内网络环境的关系,选择其他国家或地区的镜像源,安装时可能很慢或失败也不一定。
下面这段代码首先添加了阿里巴巴镜像源到一个新文件(此处为 mrlist),然后从 mirrolist 文件中选出所有国内镜像源追加到 mrlist 中,然后将 mirrorlist 文件的内容追加在 mrlist 的最后面,最后将 mrlist 重命名为 mirrorlsit:
1 | echo '## China\nServer = http://mirrors.aliyun.com/archlinux/$repo/os/$arch' > mrlist |
执行完以上命令后,可以使用以下命令来查看 mirrorlist 文件是否修改成功:
1 | nano /etc/pacman.d/mirrorlist |
按下 Ctrl+X 退出查看
若修改成功,会看到 mirrorlist 文件中的开头的内容全是国内的镜像源
开始安装系统
修改完软件镜像源后,然后就可以开始安装系统了:
1 | pacstrap -i /mnt base base-devel vim linux linux-firmware |
注意,在安装环节就需要安装 linux 和 linux-firmware 两个包,不然会导致内核没有安装导致 grub 引导失败进不去系统
使用-i 选项会在实际安装前进行确认;安装 base-devel 组,可以让我们通过 AUR (简体中文) 或者 ABS (简体中文) 编译安装软件包,如果不需要通过 AUR 或 ABS 安装软件包,则只需要安装 base 组就可以了 。
配置系统
Fstab
Linux 的文件结构是单个的树状结构。最顶部的为根目录,即/。在根目录下,分为多个子目录,包括/bin、/boot、/dev、/etc、/home、/lib、/media、/mnt、/opt、/proc、/root、/sbin、/tmp、/usr 和/var 等。
磁盘 Linux 分区都必须挂载到目录树中的某个具体的目录上才能进行读写操作,而 fstab 正是负责这一配置。
因此,在基本系统安装完成后,用以下命令生成 fstab 文件 (用 -U 或 -L 选项设置 UUID 或卷标):
1 | genfstab -U /mnt >> /mnt/etc/fstab |
然后使用以下命令检查一下生成的 fstab 文件是否正确:
1 | nano /mnt/etc/fstab |
如果生成的 fstab 文件正确,会看到之前分的 4 个分区的信息。
Chroot
chroot 命令用来在指定的根目录下运行指令
切换到新安装的系统:
1 | arch-chroot /mnt |
chroot 之后,当前目录就变成为 / 。此步会自动进行创建初始的 ramdisk 环境,但是如果以后更改了内核配置了的话,最好使用一下命令再重新生成 ramdisk 环境:
1 | mkinitcpio -p linux |
配置时区
将系统时区设为东八区:
1 | ln -sf /usr/share/zoneinfo/Asia/Chongqing /etc/localtime |
设置时间标准为 UTC,并调整时间漂移:
1 | hwclock --systohc --utc |
配置 Locale
locale 文件对系统的使用地区和语言等进行配置。在/etc/locale.gen 文件中进行配置。
locale.gen 是一个仅包含注释文档的文本文件。指定需要的本地化类型,只需移除对应行前面的注释符号(#)即可,使用下面命令打开 locale.gen 文件:
1 | nano /etc/locale.gen |
然后找到下面 2 项,去掉每项前面的#即可:
1 | en_US.UTF-8 UTF-8 |
使用 locale-gen 命令生成 Locale 信息,并列出所有启用的 Locale:
1 | locale-gen |
最后创建 locale.conf 文件,并提交所要使用的本地化选项,然后使用 locale 命令显示当前正在使用的 Locale 和相关的环境变量:
1 | echo LANG=en_US.UTF-8 > /etc/locale.conf |
/etc/locale.conf 用来配置整个系统所使用的 Loacle,而这也可以由用户通过用户自己的 /.config/locale.conf (表示当前用户的 Home 目录)来覆盖整个系统的 Locale 配置。
建立 /etc/skel/.config/locale.conf 文件,可以在新用户的建立(新用户的建立见下文)且同时创建用户主目录(useradd -m)时,自动应用其中的 Locale(会将此文件复制到新建用户的 ~/.config/locale.conf 中)。
不推荐此时设置任何中文 locale,因为这样做可能会导致 tty 显示乱码。
设置主机名
要设置主机名,创建 /etc/hostname 文件并将主机名写入该文件即可。我的主机名为 Zam-laptop:
1 | echo Zam-laptop > /etc/hostname |
然后配置主机名对应的 IP 到 /etc/hosts 中:
1 | nano /etc/hosts |
将其中的主机名改为你自己的主机名(我这里是 Zam-laptop):
1 | 127.0.0.1 localhost.localdomain localhost |
网络配置
若使用有线网络的话,由于在 Base 包里已经不包括联网所需的程序,所以需要下载 dhcp 客户端:
1 | pacman -S dhcpcd |
若使用无线网络的话,则安装以下几个软件包(因为我使用的是虚拟机,并未验证过):
1 | pacman -S iw wpa_supplicant dialog |
设置 Root 用户密码
设置 root 密码:
1 | passwd |
然后输入两次密码即可。
创建新用户
因为使用 root 用户登陆后,root 用户拥有系统的所有操作权限,这样对系统的操作非常不安全(如一不小心删库,你就要开始跑路),所以需要新建一个普通用户,让其对系统的操作受到一定限制,使用下面命令新建用户 zam:
1 | useradd -m -G wheel -s /bin/bash zam |
命令解释:
-m:创建用户主目录(/home/[用户名])
-G:用户要加入的附加组列表;此处将用户加到 wheel 组中,之后可以给这个组执行 sudo 命令的权限
-s:指定了用户默认登录 shell 的路径,此处设置为 bash 的路径
更多创建新用户的使用请查看官方 Arch Linux Wiki:https://wiki.archlinux.org/index.php/Users_and_groups_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
然后修改新创建用户的用户密码,和修改 Root 用户密码所使用的命令一样(只是需要指定要修改密码的用户名):
1 | passwd zam |
然后输入两次密码即可。
以后大部分时间我们都将使用此普通用户来工作,但由于此用户的操作权限有限,有时会对很多操作带来不便,因此需要给该用户在某些情况下提权,这就需要允许该用户所在的 wheel 组有执行 sudo 命令的权限,此时需要修改 /etc/sudoers 文件 ,但请不要直接修改此文件,而是用下面的命令修改:
1 | visudo |
使用上面命令打开 sudoers 文件后,删除 wheel 组前面的注释(#)即可:
1 | ## Uncomment to allow members of group wheel to execute any command |
若执行 visudo 时,提示找不到 vim,则请先安装 vim 后在执行上面的操作,执行下面指令安装 vim:
1 | pacman -S vim |
安装 grub
grub 是一个启动引导器,同时支持 EFI 和 BIOS 方式的启动。若使用的 UEFI 方式引导系统,则还需要安装 efibootmgr,如果是双系统的话,还需要安装 os-prober,且如果使用 Intel CPU 的话,则需要安装 intel-ucode 并启用 因特尔微码更新
嘤特尔微码更新并不是一定需要开启
- 微码
微码(microcode)就是由 Intel/AMD 提供的 CPU 固件。Linux 的内核可以在引导时更新 CPU 固件,而无需 BIOS 更新。处理器的微码保存在内存中,在每次启动系统时,内核可以更新这个微码。
这些来自 Intel/AMD 的微码的更新可以去修复 bug 或者使用补丁来防范 bug。例如前段时间爆出的幽灵(Spectre)与熔断(Meltdown)漏洞,就可以通过更新微码来解决
- 因此,最好还是启用因特尔微码更新,以保证自己的数据安全
因为我使用的是虚拟机和 BIOS 引导方式,因此只需要安装 grub:
1 | pacman -S grub |
然后,还需要将其安装到 BIOS boot 分区当中:
1 | grub-install --recheck /dev/sda |
注意:此处的 /dev/sda 后没有数字。
最后还需要生成一个 grub 的配置文件:
1 | grub-mkconfig -o /boot/grub/grub.cfg |
重启
执行以下命令:
1 | exit #退出chroot环境,切换到光盘系统 |
然后你就可以进入到 grub 的引导界面,选择 Arch Linux,enjoy it!
进阶安装
在重启之后,我们就已经成功地安装了 ArchLinux,但是这时系统处于一个非常精简的状态,为了日常使用,我们必须安装一些需要的组件,来完善我们的系统功能。
预先准备:启动 DHCP 服务
启动 dhcp 服务:
1 | systemctl enable dhcpcd.service |
以确保后续的下载软件包操作能够正常进行
安装图形界面
安装 Xorg
Xorg 是 Linux 下的一个著名的开源图形服务,我们的桌面环境需要 Xorg 的支持。
执行以下命令安装 Xorg 及相关组件:
1 | sudo pacman -S xorg |
安装 Deepin Desktop Environment(DDE)
作为国产的桌面操作环境,当然要滋磁一波
执行以下命令:
1 | sudo pacman -S deepin deepin-extra lightdm lightdm-deepin-greeter |
安装其余实用软件
deepin 还提供了解压、下载工具等实用工具的下载
执行以下命令:
1 | sudo pacman -S file-roller evince gedit thunderbird gpicview |
安装桌面管理器 sddm
经过某李姓学长提醒,了解了 sddm 和 lightdm 都是图形化的桌面管理器,因此若上面安装 deepin 时已经安装了 lightdm,接下来就不需要安装桌面管理器 sddm 了
安装好了桌面环境包以后,我们需要安装一个图形化的桌面管理器来帮助我们登录并且选择我们使用的桌面环境,sddm 就是这样的一款管理器。
执行以下命令来安装 sddm:
1 | sudo pacman -S sddm |
设置开机启动 sddm 服务
使用 systemctl 命令:sudo systemctl enable sddm
来启用 sddm 开机自启
设置 lightdm 开机自启同理
配置网络
到现在我们已经安装好了桌面环境,但是还有一件事情需要我们提前设置一下。由于我们之前使用的一直都是 netctl 这个自带的网络服务,而桌面环境使用的是 NetworkManager 这个网络服务,所以我们需要禁用 netctl 并启用 NetworkManager:
1 | sudo systemctl disable netctl |
同时你需要安装工具栏工具来显示网络设置图标:
1 | sudo pacman -S network-manager-applet |
安装完成
重启之后就可以尽情地 enjoy 了
下载编译安装最新最鬼酷的 Linux 内核
注:为了完成之后的 Patch 任务,我这里就下载 5.3 版本的内核。下载最新版的内核同理。
下载内核
首先,我们当然要先去把内核下载到虚拟机中
由于某些特殊原因,国内访问国外的 Kernel.org 速度偏慢
那么就需要从国内的开源镜像站去下载内核
地址:https://mirrors.tuna.tsinghua.edu.cn/kernel/
然后根据自己的喜好找到自己需要的内核,使用 wget 命令下载,并将其解压
1 | wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v5.x/linux-5.3.tar.xz |
编译内核
进入解压好的源码的根目录下,如果需要自定义选项,就执行以下命令:
1 | make menuconfig |
会进入一个菜单,让你定制你自己的内核。
当然,你也可以使用缺省配置,执行以下命令:
1 | zcat /proc/config.gz > .config #将当前内核的配置文件复制到此处 |
并且不要忘记在 General Setup —> 选项中或者复制来的 config 文件的”CONFIG_LOCALVERSION”一行的值来修改内核版本,这样可以避免编译的内核覆盖当前内核文件。
这样内核已经配置好了,下面就可以开始编译了
编译命令:
1 | make -j 线程数 |
安装内核模块
1 | sudo make modules_install ##把所有编译好的模块安装到正确的主目录/lib/modules下 |
该命令将编译好的模块拷贝至 /lib/modules/
拷贝内核到 /boot 目录
内核编译完成后会生成内核的 bzImage (big zImage) 文件,根据系统架构,将此文件复制到 /boot 目录,以 5.3 内核为例:
32-bit (i686) kernel:
1 | sudo cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux53 |
64-bit (x86_64) kernel:
1 | sudo cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-linux53 |
制作初始化内存盘
自动生成
复制和修改 mkinitcpio preset,就能用官方内核一样的方式生成自定义内核的 initramfs 镜像。下面例子中将已有的 preset 复制到 linux53 要使用的文件:
1 | sudo cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linux53.preset |
针对定制内核编辑和修改此文件,
1 | sudo vim /etc/mkinitcpio.d/linux53.preset |
ALL_kver= 应该和定制内核匹配:
1 | /etc/mkinitcpio.d/linux53.preset |
用官方内核一样的方式生成 initramfs 镜像:
1 | sudo mkinitcpio -p linux53 |
拷贝 System.map
将 System.map 复制到 /boot, 然后创建 /boot/System.map 软链接到 /boot/System.map-YourKernelName:
1 | sudo cp System.map /boot/System.map-YourKernelName |
更新 grub 配置信息
使用命令
1 | grub-mkconfig -o /boot/grub/grub.cfg |
来把我们刚刚配置好的内核添加到 grub 的启动配置中
然后 reboot 就可以享受最新(更老)的 kernel 了!
Patch 自己的内核
说实话,一开始看到要 patch 自己的内核,能够给出现象证明你的 patch 有效,我的心就拔凉拔凉的
Kernel 里那么多东西,我咋看的过来哪些能改哪些不能改,改了会有什么效果啊我透……
后来转念一想,Patch 最显著的现象不就是版本号升级了吗?!
于是就有了之前反向升级最新内核的操作
下载 Patch
地址:https://mirrors.tuna.tsinghua.edu.cn/kernel/
依旧是打开那个熟悉的地址,然后找到自己对应的 patch 包,用 wget 命令下载即可。
注意:如果你想跨版本升级,例如说现在是 5.3,想要升级到 5.3.8 的内核,可以一步到位从 5.3 这个大版本用 patch-5.3.8 升级至 5.3.8
解压 Patch
使用命令:
1 | xz -d patch-5.3.1.xz |
即可
安装 Patch
将解压出的 Patch 文件放在你想要打 Patch 的源代码文件夹的 Kernel 目录下 重要
为确保内核树绝对干净,执行以下命令
1 | make clean && make mrproper |
注意:由于 patch 文件中的文件路径包含了它所基于的内核源文件目录的名字(或者像是”a/“和”b/“之类的其它名字)。这很可能和你本地机器上的内核源代码目录的名字不匹配。你应该切换到你的内核源代码目录,并且在打补丁的时候去掉 patch 中文件名字路径的第一个分量(patch 命令的-p1 参数可以完成这个任务)。
因此我们在 Kernel 目录下直接执行以下命令:
1 | patch -p1 < ./patch-5.3.8.patch |
其余的 patch 文件依样画瓢即可
编译 Patch 后的内核以及之后的步骤
这个就和之前的差不多,就不再叙说了~
制作自己的 Patch 文件并打 Patch。
经过某李姓学长的提醒,我明白了这个任务其实是要我们自己动手修改 kernel 内核。
那么最简单的修改方法就是添加一个系统调用。
修改源程序,增加系统调用实现
假设你现在已经下好了 kernel 源文件并解压。在解压出的源代码文件夹内执行以下命令:
1 | vim ./kernel/sys.c |
在 sys.c 的末尾加入以下函数
1 | asmlinkage void sys_helloworld(void){ |
修改头文件,增加系统调用声明
注意:我在修改之后的系统调用后才发现 520 已经被占,因此之后图里所有的 520 都被改成了 436,也推荐大家以后新增调用时先去看看 syscall_64.tbl 文件的内容。
使用命令
1 | vim ./include/uapi/asm-generic/unistd.h |
来添加系统调用的声明
在文件的最末尾处添加如下代码:
再使用命令
1 | vim ./include/linux/syscalls.h |
在文件的最末尾处添加如下代码:
注册系统调用
进入/arch/x86/entry/syscalls
目录
可以看到以下内容:
32 位系统就添加到 syscall_32.tbl,64 位就修改 syscall_64.tbl
我这里是 64 位,因此我应该修改 syscall_64.tbl。
按着顺序往下添加即可,中间使用 Tab 键分隔。如图所示:
生成 Patch 文件
在这里,我就假设你已经修改好了文件。
比如基于 kernel 内核 做了修改,修改前的内容放在文件夹 kernel 下,修改后的内容放在文件夹 kernel_new 下,并且两个目录在同级的文件夹里,那么制作 patch 文件的命令为
1 | diff -Naur kernel/ kernel_new/ > new.patch |
然后接下来的步骤和上面的 安装 Patch 部分相同,不再赘述。
最终结果
几个踩坑的点
一开始只安装了 Base 包
网上的远古教程指导我说安装了 Base 包就行了,然而 Arch Linux 似乎把 Linux 内核从 Base 包当中分离了出来,所以一开始只安装 Base 包导致 grub 找不到内核一直引导失败。
这个惨痛的经历告诉我们,以后不管装什么,都要看官方 wiki,避免踩坑。
在编译内核时 config 文件没有配置好
一开始直接用make defconfig
命令,编译了一个几乎啥都不带的内核。之后才明白如果想沿用当前系统设置应该用zcat /proc/config.gz > .config
命令。
还好有 善意的提醒 不然又得从头再来。
在 Patch 时报错,提示 patch rejected
这是因为我用了 tuna 的 patch 包,这个包是用来一步到位从 5.3 升级到 5.3.8 的,而要想从 5.3.7 升级到 5.3.8,则需要从 https://www.kernel.org 上下载 Inc.patch 包。