实验一、openEuler操作系统安装与内核编译

1、操作系统安装

1.1 下载OpenEular镜像

 

1.2 安装到VM VirtualBox虚拟机

该步骤遇到很多问题。最开始在OS实验成长故事平台下载了openeuler21.09:

并使用VMware安装虚拟机,但是安装完成进入后无法连接网络,使用ping命令无法ping通,初步分析原因,应该是yum源没有配置好,于是去配置yum源,但在配置好安装源、安装好必要工具、调整虚拟机参数(主要是网络转换方式)安装很多次依然无法连接网络。随后改用官网下载的openeuler20.03,配合VM Virtualbox虚拟机平台,成功完成搭建。因为之前接触linux系统较少、经验不足,整个从安装到能上网前后折腾了一个星期。

最终的虚拟机配置:

内存、处理器大小视情况而定,虚拟硬盘需要设置尽量大(35~45G比较合适),原因是实验一编译内核需要较大的硬盘空间,若过小会导致安装失败,且虚拟硬盘大小调整也比较复杂。

选择安装磁盘(虚拟磁盘)及分区(自动分区),连接网络(NTA模式),添加root用户密码,开始自动安装。

安装完成后只有终端,且字体太小比较难受,故为其安装桌面环境(gnome)以及terminal。

yum update  #报错,提示缺少相关文件

首先配置清华源:

vim /etc/yum.repos.d/openEuler_x86_64.repo #打开配置文件
# 添加如下内容
[osrepo]
name=osrepo
baseurl=https://mirrors.tuna.tsinghua.edu.cn/openeuler/openEuler-20.03-LTS/OS/x86_64/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/openeuler/openEuler-20.03-LTS/OS/x86_64/RPM-GPG-KEY-openEuler

安装gnome:

dnf install gnome-shell gdm gnome-session   #安装gnome及相关组件
dnf install gnome-terminal  #安装terminal
#设置开机自启动
systemctl enable gdm.service
systemctl set-default graphical.target
#补全丢失文件
cd /tmp
wget https://gitee.com/name1e5s/xsession/raw/master/Xsession
mv Xsession /etc/gdm/
chmod 0777 /etc/gdm/Xsession

gnome桌面安装成功!

【参考教程:在 openEuler 上安装桌面环境 - 知乎 (zhihu.com)

yum -y install firefox #顺便安装firefox

2. openEuler内核编译安装

【参考:OpenEuler内核编译与替换

2.1 系统备份

cd ~
dnf install lrzsz      # rz和sz可以在终端下很方便的传输文件
tar czvf boot_origin.tgz /boot/
sz boot_origin.tgz    # 将备份文件发送到本地

2.2 内核源码下载

在gitee仓库中下载openEuler内核压缩文件并解压:

【内核地址:openeuler_kernel

移动到内核源码目录:

2.3 清理源代码树

make mrproper

2.4 生成内核配置文件

复制原配置文件:

依赖安装、更改配置:

yum install ncurses-devel
make menuconfig

选择save,生成配置文件.config:

安装编译所需组件:

yum install elfutils-libelf-devel
yum install openssl-devel
yum install bc

2.5 编译、安装

make -j4 #四核多线程编译,提升编译效率,cpu发热也提升。

两个半小时后,编译完成:

安装模块:

make modules_install

安装内核:

make install

出现报错:(内核上模块构建的返回状态不正确)

查看编译日志:

找到错误:未知的类型名‘time_t'。

先继续查看安装的内核,发现新内核已经存在了:

更新引导:

重启,可以看到编译成功的新内核,选择新内核回车:

成功进入系统后,查看默认启动内核:

查看内核版本:

内核安装成功。

3 内核模块编程

helloworld.c:

#include<linux/module.h>
​
MODULE_LICENSE("GPL");
​
int __init hello_init(void)
{
    printk("hello init\n"); //printk函数,而不是之前学的printf
    printk("hello,world!\n");
    return 0;
}
​
void __exit hello_exit(void)
{
    printk("hello exit\n");
}
module_init(hello_init);
module_exit(hello_exit);



Makefile:

ifneq ($(KERNELRELEASE),)
    obj-m := helloworld.o
else
    KERNELDIR ?=/usr/src/kernels/5.10.0-4.25.0 #此处实验文档所给为树莓派内核目录,在此要修改为x86_64系统下的内核目录,并且在后续的内核编程中所有的Makefile文件都需要更改为该路径。
    PWD := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
.PHONY:clean
clean:
    -rm *.mod.c *.o *.order *.symvers *.ko

先学习内核模块和Makefile文件的基本结构:

//内核模块.c文件基本框架
​
#include<linux/module.h>             //包含了对模块的结构定义以及模块的版本控制
​
MODULE_LICENSE("GPL");           //声明GPL版权
static __init module_init(void){      //加载模块
     。。。。。。
}
​
static __exit module_exit(void){     //卸载模块
     。。。。。。
}
module_init(module_init);
module_exit(module_exit);
//Makefile文件基本框架
​
ifneq ($(KERNELRELEASE),)                                                            
    obj-m :=main.o       //指定将要编译的内核模块列表(一些.o文件)
​
else
    KERNELDIR ?=/usr/lib/modules/$(shell uname -r)/build      //内核源代码位置
    PWD := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules     //编译连接目标
endif
.PHONY:clean
clean:
    -rm *.mod.c *.o *.order *.symvers *.ko

后续Makefile文件只有内核模块列表那一行不一样,其他部分均参考实验一的Makefile文件,故后续实验Makefile文件不再展示。

编译内核:

编译后的文件列表:

模块的加载、查看、卸载:

内核模块的相关操作:

  • 加载内核模块:insmod

  • 卸载内核模块:rmmod

  • 查看内核模块:lsmod

  • 查看打印信息:dmesg | tail -n 行数

实验总结

通过本次实验,我完整地进行了从编写内核源码、make编译、加载、卸载、查看内核模块的整个过程,为后续实验的顺利进行奠定了基础。

  • 20
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯若

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值