• 作业要求:

    完成本专题教学内容中的验收测试题并提交验收材料。

    验收材料要求:

    新内核引导成功前

    \1. 执行命令:uname –a,提交截屏结果1

    image-20210514211226158

    新内核引导成功后

    \2. 执行命令:uname –a,提交截屏结果2

    image-20210514222101971

    \3. 进入目录/boot,执行命令:ls -l,提交截屏结果3

    image-20210514222213871

  • ==tips:== 在创建虚拟机时,最好分配 50 GB 以上从磁盘空间,四个以上内核

  • 最重要的是:分配 4 GB 以上的内存,防止在内存中死锁

  • 最最重要的是:新版本的 Linux 内核make install安装后,不再需要手动引导内核!!!即不再需要配置 grub

1 [知识点]什么是 Linux 内核

  • 操作系统的结构

    • image-20210511210840223

    • 操作系统:Kernel + Shell

  • Kernel的组成和功能

    • image-20210511211233011
  • Linux 发行版本内核版本之间的关系:

    • 例如教学视频中:Ubuntu10.04 = Kernel2.6.30 + SHELL + USERS APPLICATIONS
    • 两者独立
  • 本次课程设计我选择的发行版本Ubuntu20.04.20

    • 内核版本:用命令uname -r
      • 5.8.0-50-generic

2 [实验] 从内核源码 到 内核镜像(Kernel Image)

实验准备

当前Linux内核版本为5.8.0-50

内核版本官网下载另一个内核版本:

  • 版本号尾号为偶数的是stable版的,所以我选择5.12.2

tips: 直接点击屎黄色按钮下载很慢,可以将下载链接复制至自己喜欢的下载软件下载IDM

实验步骤

实验要求: 利用make menuconfig的配置功能,配置并编译信息中带有自己学号加姓名的内核

1 安装相应的软件包

步骤

  • 手动或终端解压package

  • .deb 离线安装包

    • 老版本的发行版在线安装比较麻烦
  • sudo bash ./INSTALL.sh: 执行安装脚本

遇到的问题:相关依赖下载安装

  1. 可以先更换国内源

    1. 软件和更新 选择 最佳的服务器
    2. image-20210512163243691
  2. 在执行 INSTALL.sh 时,许多警告,缺少依赖等

  1. 百度找到 Ubuntu20.04 编译内核所需要的依赖
  2. 首更新sudo apt-get update && sudo apt-get upgrade
  3. sudo apt-get install libelf-dev
  4. sudo apt-get install libncurses5-dev libssl-dev
  5. sudo apt-get install build-essential openssl
  6. sudo apt-get install libidn11-dev libidn11
  7. sudo apt-get install zlibc minizip
  8. sudo apt-get install bison
  9. sudo apt-get install flex
  10. sudo apt-get install pkg-config
    1. sudo apt-get install libssl-dev

2 拷贝源码包至/usr/src并解压

  • 需要用 root 用户权限将源码包拷入标准路径/usr/src
  • 解压命令 sudo tar xfv xxx
    • 解压七万多个文件(.c .h文件)

遇到的问题:

需要重新安装VMware tools

  1. 首先将压缩包移动至 usr/local`
  2. 然后使用tar -zxvf xxx 解压
  3. 进入vmware-tools-distrib, 使用sudo ./vmware-install.pl命令安装
  4. 手动启动vmware-user

3 进入源码所在目录

  • 按照功能分
  • Makefile

4 执行一系列 make 指令

==tips:== 可以使用多核进行编译make -j x : x为核心数,不能超过自己的核心数,省略则使用最多数

  • 步骤一:make menuconfig -j x
    • 进入配置菜单
      • [ ] : 编译入内核
      • [*]:可选
      • [M]: 编译为内核模块
    • 必须改:在 General setup ——>Local version:加入学号加姓名

遇到的错误:

Your display is too small to run Menuconfig! It must be at least 19 lines by 80 columns. make[1]: *** [scripts/kconfig/Makefile:34:menuconfig] 错误 1 make: *** [Makefile:602:menuconfig] 错误 2

  • 第一个问题似乎是终端窗口太小,最大化试试
  • 最大化之后再将比例缩小即可
  • 步骤二: make -j x (x为分配的内核数):.c编译为.o
    • 一到两小时
      • 可以用多内核减少一些时间
    • 快照:保存当前系统的状态,随时可以恢复载入改状态
    • 编译finished后,目录下产生:vmlinux.o 目标文件和vmlinux 可执行文件

make之后报错:scripts/sign-file.c:25:10: fatal error: openssl/opensslv.h: 没有那个文件或目录 25 | #include <openssl/opensslv.h> | ^~~~~~~~~~~~~~~~~~~~ compilation terminated.

  • 解决:sudo apt-get install libssl-dev
  • 应提前安装
  • 步骤三make modules_install -j x
    • 编译为动态链接库.ko
      • driver
      • fs
      • sound
      • lib
    • .ko(类似于动态库)移动至标准目录

make modules_install报错:

sed: 无法读取 modules.order: 没有那个文件或目录 make: *** [Makefile:1471:_modinst_] 错误 2

  • 问题解决:
    • make[1]: *** 没有规则可制作目标“debian/canonical-certs.pem”由“certs/x509_certificate_list” 需求。 停止。 make: *** [Makefile:1851:certs] 错误 2
      • solution :
        • vi .config
        • /搜索CONFIG_SYSTEM_TRUSTED_KEYS,将里面内容清空
  • 步骤四make install -j x
    • 执行.sh脚本:将内核镜像移动至 boot 引导目录
      • 用引导程序将内核镜像引导起来
    • 执行完命令后:
      • 三个以 学号姓名 为后缀的文件是引导所需要的

Warning:

dpkg: warning: version '5.12.2mazihao_19030500024~old' has bad syntax: invalid character in version number dpkg: warning: version '5.12.2mazihao_19030500024~old' has bad syntax: invalid character in version number

  • solution:
  • 注意:新版本(我的是5.12.2)的Linux内核,不需要手动引导内核,
    • make install 之后直接重启即可

3 [知识点] GNU make和makefile

什么是 make

  • make menuconfig: 用命令行模式配置内核
  • make: 编译内核模块
  • make modules_install: 安装模块
    • /lib/modules/内核版本 对应的目录下,建立文件夹并把模块文件放入
  • make install: 安装内核
    • 即拷贝入/boot目录下

什么是makefile

  • 告诉 make 命令如何去编译

makefile文件保存了 编译器和连接器的参数选项, 还表述了所有源文件之间的关系(源代码文件需要的特定的包含文件,可执行文件要求包含的目标文件模块及库等).

创建程序(make程序) 首先读取makefile文件, 然后再激活编译器,汇编器,资源编译器和连接器以便产生最后的输出, 最后输出并生成的通常是可执行文件.

创建程序利用内置的推理规则来激活编译器,以便通过对特定CPP文件的编译来产生特定的OBJ文件.

makefile 规则

1
2
3
4
target ... :prerequisites ...
recipe
...
...

Makefile demo 使用规则

试读内核源码的Makefile

4 [知识点] 操作系统启动

操作系统 引导过程

  1. 电脑开机后, 启动 BIOS , BIOS 自检
  2. 自检后,BIOS 找到硬盘上的主引导记录 MBR
  3. MBR 读取硬盘分区表 DPT ,找到活动分区中的分区引导记录 PBR,将控制权交给 PBR
  4. PBR 搜索活动分区中的启动管理器 bootmgr (Linux下是Grub,grub.conf , windows下是),将控制权交给 bootmgr
  5. bootmgr 寻找 boot 文件夹中的 BCD 文件(启动配置数据)
  6. 找到 BCD 后,bootmgr 首先从 BCD 中读取启动管理器 bootmgr 菜单信息,在显示器上显示多操作系统选择画面
  7. 如果存在多个操作系统并且系统设置的等待时间不是0,就会显示多个操作系统。若无,则直接进入
  8. 进入系统后,bootmgr 会读取 BCD 中win7系统所在的盘的winload.exe 文件,将控制器交给
  9. winload.exe 加载win7 内核、硬件、服务等,之后加载桌面等信息,从而启动整个系统

启动管理程序 grub

  • grub.conf
    • 需要改配置正确才能启动

5 [实验] Linux 内核的引导

引导前:

image-20210514102943927

内核 make install成功后

==注意:==

新版本的Ubuntu 不再需要手动引导内核(知道真相的我眼泪流下来,需要将内存分配至4GB以上)

然后,make install之后,直接reboot

首先:将内核作为引导,数字改为自己编译的版本号:

  • sudo update-initramfs -c -k 5.12.2mzh19030500024

然后,更新 grub:

  • sudo update-grub

之后,修改 grub文件:

  • sudo gedit /etc/default/grub
  • img

然后,执行sudo update-grub

最后重启,选择advanced,选择编译好的内核

  • 步骤一:sudo mkinitramfs -o /boot/initrd.img-5.12.2
  • 步骤二:sudo update-initramfs -c -k 5.12.2
    • 在boot目录下产生init
  • 步骤三:sudo update-grub2
    • 自动修改系统引导配置,产生grub.cfg启动文件。
    • 后grub.cfg文件中增加了新内核的启动项
  • 步骤三:reboot
  • 选择新版本内核