Linux操作系统分析学习总结

freekeeper 2022-07-05 19:30:24

一、mykernel实现进程切换

实验环境:
  • Ubuntu18.04
  • Linux-5.4.34内核
实验准备:

通过以下命令安装实验所需要的工具

sudo apt install build-essential gcc-multilib
sudo apt install qemu 
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev

利用老师所给的资料,通过给Linux内核打补丁的方式,让Linux内核执行我们自定义的内核程序,打补丁命令如下(Linux-5.4.34内核与补丁处于同级目录下,下列命令是在Linux-5.4.34/目录下执行):

patch -p1 < ../mykernel-2.0_for_linux-5.4.34.patch

通过以下命令对内核进行编译

make defconfig # Default configuration is based on 'x86_64_defconfig'
make -j$(nproc)# 编译完成后会生成系统镜像

下图是编译完成生成系统镜像的结果

img

通过Qemu运行上面生成的系统镜像

qemu-system-x86_64 -kernel arch/x86/boot/bzImage

运行结果如下

img

实验分析:

我们通过更改Linux内核入口执行点为我们自定义的my_start_kernel函数,其中my_start_kernel函数调用my_process函数,在my_process中完成进程切换,核心代码如下:

//将task[0].thread.ip设置为my_process的入口地址
task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process;

//执行完ret指令后,task[pid].thread.ip的值也就是my_process入口地址会赋值给rip
asm volatile(
    "movq %1,%%rsp\n\t"     /* set task[pid].thread.sp to rsp */
    "pushq %1\n\t"          /* push rbp */
    "pushq %0\n\t"          /* push task[pid].thread.ip */
    "ret\n\t"               /* pop task[pid].thread.ip to rip */
    : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)   /* input c or d mean %ecx/%edx*/ 
);
//实现进程切换的关键汇编代码
//通过我们定义的进程双向循环链表中的prev跟next指针完成进程切换
asm volatile(
    "pushq %%rbp\n\t"           /* save rbp of prev */
    "movq %%rsp,%0\n\t"         /* save rsp of prev */
    "movq %2,%%rsp\n\t"         /* restore  rsp of next */
    "movq $1f,%1\n\t"           /* save rip of prev */
    "pushq %3\n\t"
    "ret\n\t"                   /* restore  rip of next */
    "1:\t"                      /* next process start here */
    "popq %%rbp\n\t"
    : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
    : "m" (next->thread.sp),"m" (next->thread.ip)
);

二、调试Linux内核

实验环境:
  • Ubuntu18.04
  • Linux-5.4.34内核
  • busybox-1.28.1
实验过程:

实验二所需要的工具,在实验一中已完成安装。按照老师所给的步骤,完成内核选项的配置:打开Debug、关闭KASLR。

计算机加电启动首先由Bootloader加载内核,BootLoader紧接着挂载内存根文件系统,所以现在需要通过Busybox制作一个根文件系统

cd busybox-1.28.1  #安装完成busybox后,进入busybox目录
make menuconfig    #会出现一个图形化界面,将其中的Setting设置为Build static binary
make -j$(nproc) && make install    #完成编译安装

下图显示编译安装完成

img

mkdir rootfs       #在busybox1.28.1目录下生成rootfs目录
cd rootfs
cp ../_install/* ./ -rf
mkdir dev proc sys home
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/

然后在busybox-1.28.1/rootfs目录下添加一个init文件,文件内容如下:

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome SA21225330's OS!"
echo "--------------------"
echo "Copyright by mengning@ustc.edu.cn"
cd home
/bin/sh
#给init脚本添加可执行权限,在busybox-1.28.1/rootfs目录下执行
chmod +x init     
#打包成内存根文件系统镜像,在busybox-1.28.1/rootfs目录下执行
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz 
#测试挂载根文件系统,看内核启动完成后是否执行init脚本
#在linux-5.4.34跟busybox-1.28.1文件同级目录下执行
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd ./busybox-1.28.1/rootfs.cpio.gz  

下图显示init脚本成功执行

img

qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd ./busybox-1.28.1/rootfs.cpio.gz -S -s

执行完上述命令后,可以看到Qemu处于暂定状态。

img

再打开一个命令行窗口,启动gdb,把内核符号表加载进来,建立连接

cd linux-5.4.34/
gdb vmlinux
(gdb) target remote:1234
(gdb) b start_kernel

从下图中可以看到成功在Linux内核入口执行点start_kernel函数断点并显示信息

img

三、实验总结

做完这两个实验,只能说浅浅入门了Linux内核。虽然孟老师给出了实验的运行代码和执行步骤,但是起初自己做的时候还是走了不少弯路,比如:

  • 做这两个实验,遇到最大的问题就是软件版本的问题,一个是Linux内核版本,一个是busybox版本
  • 自己电脑安装的是Ubuntu22.04,在做实验一执行最后一步运行生成的系统镜像,根据报错信息去搜索,两天还没有解决这个问题。最后发现是自己Ubuntu的内核版本过高,已经不过像之前老版本一样生成bzImage镜像文件,最后安装了Ubuntu18.04才得以解决
  • 在做实验二的时候,根据孟老师提供的busybox-1.31.1版本,在自己电脑上始终不能成功制作根文件系统,最后换成了低版本的busybox-1.28.1才得以成功。后面按照孟老师给出的命令一步步操作,得不到正确的结果,绕了好长时间,才发现孟老师没有给出命令执行的所在目录,自己一昧的跟着PPT敲命令,却没有考虑要切换目录去执行,所以走了一些弯路

下面是学习Linux操作系统的一些收获和感想

  • 由于之前对Linux内核了解的不多,所以实时上课的时候,很多内容当时听不懂,需要反复观看几遍录播才能明白

  • 孟老师的mykernel目前只是简单实现了进程管理功能,对于内存管理和文件管理没有涉及。后面还是希望能看到孟老师能够给出这两部分的实验

  • Linux最本质的东西在于自由和开放,可以获取所有的源代码,侯捷老师说过”源码面前,了无秘密“。Linux内核上百万行的代码令学习曲线变的陡峭,不禁令人发憷。孟老师的mykernel从成千上万行的代码中抽丝剥茧,实现了一个精简版的进程调度功能,让我找到了一个着手点

  • 开始用Source Insight阅读源代码的时候,自己会专注于一个子系统就一头扎到实际的代码行中去,但由于牵涉的知识很广,会碰到很多困难,容易产生挫败感,一个函数体中可能掺杂着其他各个子系统方面设计理念(多是大量相关的数据结构或者全局变量,用于支撑该子系统的管理工作)下相应的代码实现,这个时候看到这些东西,纷繁芜杂,没有头绪很难理解,会产生很多疑问

  • 后来阅读了陈莉君老师所译的《Linux内核设计与实现》,整体上了解了Linux内核对进程、内存、文件的管理,阅读完后,只能说能够看懂一些源代码。这本书适合对Linux内核了解较少的学生阅读

  • 后来又阅读了陈莉君老师所译的《深入理解Linux内核》部分内容,这本书很详细,但也是有难度的,需要反反复复看好几遍才能理解。纸上得来终觉浅,获得的都是一些理论知识,实践部分目前还是有些欠缺

  • 经过一个学期的学习,只能说刚刚入门了Linux内核,越深入Linux内核,越发现设计者的厉害之处。我们只不过是站在巨人的肩膀上去学习前辈留下来的知识,只希望有一天能够爬上巨人的肩膀

四、参考资料

作者:330

...全文
124 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
[14本经典Android开发教程] 8 Linux内核阅读心得体会 读核感悟 2 读核感悟 Linux内核启动 内核的生成 2 读核感悟 Linux内核启动 从hello world说起 3 读核感悟 Linux内核启动 BIOS 5 读核感悟 Linux内核启动 setup辅助程序 6 读核感悟 Linux内核启动 内核解压缩 8 读核感悟 Linux内核启动 开启页面映射 9 读核感悟 Linux内核启动 链接脚本 11 读核感悟 伪装现场 系统调用参数 13 读核感悟 伪装现场 fork 系统调用 15 读核感悟 伪装现场 内核线程: 17 读核感悟 伪装现场 信号通信 19 读核感悟 kbuild系统 内核模块的编译 22 读核感悟 kbuild系统 编译到内核和编译成模块的区别 24 读核感悟 kbuild系统 make bzImage的过程 26 读核感悟 kbuild系统 make menuconfig 31 读核感悟 文件系统 用C来实现面向对象 32 读核感悟 设计模式 用C来实现虚函数表和多态 32 读核感悟 设计模式 用C来实现继承和模板 33 读核感悟 设计模式 文件系统和设备的继承和接口 34 读核感悟 设计模式 文件系统与抽象工厂 36 读核感悟 阅读源代码技巧 查找定义 37 读核感悟 阅读源代码技巧 变量命名规则 42 读核感悟 内存管理 内核中的页表映射总结 43 读核感悟 健壮的代码 exception table 内核中的刑事档案 44 读核感悟 定时器 巧妙的定时器算法 45 读核感悟 内存管理 page fault处理流程 45 读核感悟 文件读写 select实现原理 47 读核感悟 文件读写 poll的实现原理 49 1 功能介绍: 49 2 关键的结构体: 49 3 poll的实现 49 4 性能分析: 50 读核感悟 文件读写 epoll的实现原理 50 1 功能介绍 50 2 关键结构体: 51 3 epoll create的实现 53 4 epoll ctl的实现 53 5 epoll wait的实现 54 6 性能分析 54 读核感悟 同步问题 同步问题概述 55 1 同步问题的产生背景 55 2 内核态与用户态的区别 55 读核感悟 同步问题 内核态自旋锁的实现 56 1自旋锁的总述 56 2非抢占式的自旋锁 56 3 锁的释放 57 4 与用户态的自旋锁的比较 57 5 总结 58 读核感悟 内存管理 free命令详解 58 读核感悟 文件读写 2 6 9内核中的AIO 59 1 AIO概述 59 2 内核态AIO的使用 61 读核感悟 文件读写 内核态AIO相关结构体 61 1 内核态AIO操作相关信息 61 2 AIO上下文: 63 3 AIO ring 63 4 异步I O事件的返回信息 64 读核感悟 文件读写 内核态AIO创建和提交操作 65 1 AIO上下文的创建 io setup 65 2 AIO请求的提交:io submit实现机制 66 读核感悟 文件操作 AIO操作的执行 66 1 在提交时执行AIO 66 2 在工作队列中执行AIO 66 3 负责AIO执行的核心函数aio run iocb 67 4 AIO操作的完成 67 读核感悟 文件读写 内核态是否支持非direct I O方式的AIO 67 已上传7本: [14本经典Android开发教程] 1 Android开发从入门到精通 http: download csdn net detail cleopard 8355245 [14本经典Android开发教程] 2 Android开发手册 API函数详解 http: download csdn net detail cleopard 8374487 [14本经典Android开发教程] 3 Android SDK 中文开发文档 http: download csdn net detail cleopard 8380429 [14本经典Android开发教程] 4 Android应用程序开发36技 http: download csdn net detail cleopard 8380495 [14本经典Android开发教程] 5 linux Android基础知识总结 http: download csdn net detail cleopard 8380529 [14本经典Android开发教程] 6 Android驱动开发入门及手机案例开发分析教程 http: download csdn net detail cleopard 8388019 [14本经典Android开发教程] 7 Android编程入门教程 http: download csdn net detail cleopard 8388043 剩余8本稍后上传 @或直接从这里寻找@ http: download csdn net user cleopard album @更多@ http: cleopard download csdn net 福利 http: xuemeilaile com 17份软件测试文档 http: download csdn net album detail 1425 13份WPF经典开发教程 http: download csdn net album detail 1115 C#资料合辑二[C#桌面编程入门篇] http: download csdn net album detail 957 C#资料合辑一[C#入门篇] http: download csdn net album detail 669 [Csharp高级编程 第6版 ] 共8压缩卷 http: download csdn net album detail 667 10个[精品资源]Java学习资料合辑[一] http: download csdn net album detail 663 10个C#Socket编程代码示例 http: download csdn net album detail 631 6份GDI+程序设计资源整合[全零分] http: download csdn net album detail 625 2014年移动游戏行业数据分析 http: download csdn net detail cleopard 8340331 一文读懂2014年全球互联网广告新生态 http: download csdn net detail cleopard 8340303">[14本经典Android开发教程] 8 Linux内核阅读心得体会 读核感悟 2 读核感悟 Linux内核启动 内核的生成 2 读核 [更多]

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧