Linux实验总结

Linux实验总结:

运行mykernel

环境:ubuntu 18.04,实测21.04的默认GCC版本编译完无法生成bzImage

步骤

wget https://raw.github.com/mengning/mykernel/master/mykernel-2.0_for_linux-5.4.34.patch
sudo apt install axel
axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar
cd linux-5.4.34
patch -p1 < ../mykernel-2.0_for_linux-5.4.34.patch
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev
make defconfig # Default configuration is based on 'x86_64_defconfig'
make -j$(nproc) # 编译的时间比较久哦
sudo apt install qemu qemu-system-x86 # install QEMU
qemu-system-x86_64 -kernel arch/x86/boot/bzImage

结果

请添加图片描述

基于mykernel的极简内核

修改内核代码,使用时间片轮转调度多道程序

下载mykernel代码,并将mypcb.h; mymain.c; myinterrupt.c复制替换到Linux内核中的mykernel文件夹,重新编译

make defconfig
make -j$(nproc)
qemu-system-x86_64 -kernel arch/x86/boot/bzImage

请添加图片描述

Debug Linux Kernel

根据参考资料PPT上的步骤,在Linux内核文件夹编译内核makemake install,使用qemu验证无文件系统时的内核,会出现内核异常,之后配置根文件系统。请添加图片描述
请添加图片描述

完成内存跟系统镜像后,不要手贱更新系统,否则将无法正常启动。
请添加图片描述

跟踪启动

请添加图片描述
请添加图片描述
请添加图片描述

  1. start_kernel()静态创建0号进程init_task,最终成为idle进程,init_task进程的内核栈通过静态方式分配
  2. rest_init(),Linux内核初始化的尾声,做了很多剩下的初始化工作。调用kernel_thread(),通过fork创建内核进程,1号进程init和2号进程kthreadd,其中调用了kernel_init()
  3. kernel_init(),通过调用do_execve()来执行根文件系统的init文件,其中调用了run_init_process()
  4. run_init_process()通过execve()来运行init程序
  5. kthreadd用来管理系统的资源

跟踪系统调用

测试代码

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
int main(int argc, char *argv[]){
    char buffer[80] = "/tmp/test";
    int fd = open(buffer, O_RDONLY);
    int size = read(fd, buffer, sizeof(buffer));
    close(fd);
}

静态编译

gcc -g -static -o test_open test_open.c

使用gdb调试,使用disas命令查看汇编
在这里插入图片描述
可见在0x4488a0位置调用了open64,打开open64
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

跟踪fork

  1. 打断
    在这里插入图片描述
  2. 跟踪在这里插入图片描述
    在这里插入图片描述
  • copy_process复制父进程信息
  • wake_up_new_task将子进程加入调度队列等待分配CPU资源
  • copy_process调用dup_task_struct复制父进程的数据结构、以及进行初始化、信息检查等工作
  • copy_process调用copy_thread来初始化子进程的内核栈,设置pid
  • ret_from_fork结束。

动态链接库

装载时动态的shared lib

  1. 照着PPT创建shlibexample.h/shlibexample.c,注意注释与中文符号
  2. 编译生成.so文件gcc -shared shlibexample.c -o libshlibexample.so

运行时动态的dynamic lib

  1. 照着PPT创建dllibexample.h / dllibexample.c,注意注释与中文符号
  2. 编译生成.so文件gcc -shared dllibexample.c -o libdllibexample.so

测试动态链接

  1. 创建测试文件main.c,(PPT上的代码不全,得看src文件夹里的源码)

    #include <stdio.h>
    #include "shlibexample.h" 
    #include <dlfcn.h>
    
    int main()
    {
        printf("This is a Main program!\n");
        /* 装载时动态链接 */
        printf("Calling SharedLibApi() function of libshlibexample.so!\n");
        SharedLibApi();
        
        /* 运行时动态链接 */
        void * handle = dlopen("libdllibexample.so",RTLD_NOW);
        if(handle == NULL)
        {
            printf("Open Lib libdllibexample.so Error:%s\n",dlerror());
            return   FAILURE;
        }
        int (*func)(void);
        char * error;
        func = dlsym(handle,"DynamicalLoadingLibApi");
        if((error = dlerror()) != NULL)
        {
            printf("DynamicalLoadingLibApi not found:%s\n",error);
            return   FAILURE;
        }    
        printf("Calling DynamicalLoadingLibApi() function of libdllibexample.so!\n");
        func();  
        dlclose(handle);
        return SUCCESS;
    }
    
  2. libshlibsxample.so复制到/usr/lib

  3. $export LD_LIBRARY_PATH=$PWD 将当前目录加入默认路径,否则main找不到依赖的库文件,当然也可以将库文件复制到默认路径下。

  4. 编译main.c并执行

  5. 在这里插入图片描述

总结

感觉课程中的Linux内核更偏向于嵌入式系统中的Linux,在我的理解中,Linux的组成部分包括:进程管理(切换、调度)、内存分配与管理、系统内进程通信与同步机制、时钟与中断、驱动程序与模块、文件系统、网络以及系统调用等

课程主要讲解了Linux系统的编译与启动过程、进程管理、程序执行与文件系统、时钟与中断、驱动程序与模块、中断与系统调用等。即使有的内容在好几个课都接触过,但是记不住确实还是记不住= =。

406
参考资料庖丁解牛Linux操作系统分析https://gitee.com/mengning997/linuxkernel

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值