• Linux操作系统分析总结


    课程学习收获和感想

    本课程是理论和实验相结合的授课模式,同时通过参加操作系统大赛的方式,让我们能更好的利用所学的知识去处理实际问题,同时知道自己的不足之处,锻炼了自己自学钻研,思考和解决问题的能力。

    操作系统大赛

    我们小组参加的操作系统大赛是功能赛道的第111题,是基于openssl实现远程SSH登录的国密改造,主要是基于openssl提供的国密算法sm2/sm3/sm4改造openssh,使之改造后能够生成国密算法的密钥,并能使用国密算法自登录。我们小组三人分别负责一种算法的改造,将代码嵌入进openssl的源码中,虽然最终没有入围,但是在比赛过程中,加深了自己对加密算法的理解,以及对远程登录流程的熟悉,收获很多。

    课程实验总结和课程理解

    Linux内核,主要包括进程管理、内存管理、设备驱动、文件系统,从分析内核了解到整个系统是如何工作的,如何控制管理资源分配,进程切换并执行。各种策略和结构让系统运行时更有效率。只有懂得其中的基本工作机制才能够有效的裁剪内核,再重新编译内核,生成高效、可移植的内核模块。

    通过课程,自己去编写代码,去debug内核代码,一步步的理解堆栈如何切换,系统调用是如何执行的。

    实验一 反编译

    第一步:编写一个简单的包含函数调用的C程序代码

    1. // main.c
    2. int g(int x)
    3. {
    4.    return x + 3;
    5. }
    6.    
    7. int f(int x)
    8. {
    9.    return g(x);
    10. }
    11.    
    12. int main(void)
    13. {
    14.    return f(8) + 1;
    15. }

    第二步:反编译代码

    $ gcc –S –o main.s main.c -m32

    第三步:查看反编译结果

    1. .file "main.c"
    2. .text
    3. .globl g
    4. .type g, @function
    5. g:
    6. .LFB0:
    7. .cfi_startproc
    8. pushl %ebp
    9. .cfi_def_cfa_offset 8
    10. .cfi_offset 5, -8
    11. movl %esp, %ebp
    12. .cfi_def_cfa_register 5
    13. movl 8(%ebp), %eax
    14. addl $3, %eax
    15. popl %ebp
    16. .cfi_restore 5
    17. .cfi_def_cfa 4, 4
    18. ret
    19. .cfi_endproc
    20. .LFE0:
    21. .size g, .-g
    22. .globl f
    23. .type f, @function
    24. f:
    25. .LFB1:
    26. .cfi_startproc
    27. pushl %ebp
    28. .cfi_def_cfa_offset 8
    29. .cfi_offset 5, -8
    30. movl %esp, %ebp
    31. .cfi_def_cfa_register 5
    32. subl $4, %esp
    33. movl 8(%ebp), %eax
    34. movl %eax, (%esp)
    35. call g
    36. leave
    37. .cfi_restore 5
    38. .cfi_def_cfa 4, 4
    39. ret
    40. .cfi_endproc
    41. .LFE1:
    42. .size f, .-f
    43. .globl main
    44. .type main, @function
    45. main:
    46. .LFB2:
    47. .cfi_startproc
    48. pushl %ebp
    49. .cfi_def_cfa_offset 8
    50. .cfi_offset 5, -8
    51. movl %esp, %ebp
    52. .cfi_def_cfa_register 5
    53. subl $4, %esp
    54. movl $8, (%esp)
    55. call f
    56. addl $1, %eax
    57. leave
    58. .cfi_restore 5
    59. .cfi_def_cfa 4, 4
    60. ret
    61. .cfi_endproc
    62. .LFE2:
    63. .size main, .-main
    64. .ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    65. .section .note.GNU-stack,"",@progbits
       
    
    

    实验二 时间片轮转调度

    本实验通过分析一个简单的时间片轮转多道程序的内核,来理解操作系统是如何工作的。

    第一步:编译内核

    1. # 注意路径是区分大小的
    2. $ cd ~/LinuxKernel/linux-3.9.4
    3. $ rm -rf mykernel
    4. $ patch -p1 < ../mykernel_for_linux3.9.4sc.patch
    5. $ make allnoconfig
    6. # 编译内核请耐心等待
    7. $ make

    第二步:启动并查看qemu窗口输出

    $ qemu -kernel arch/x86/boot/bzImage

    第三步:运行结果和代码

    1. /*
    2. * linux/mykernel/mymain.c
    3. *
    4. * Kernel internal my_start_kernel
    5. *
    6. * Copyright (C) 2013 Mengning
    7. *
    8. */
    9. #include <linux/types.h>
    10. #include <linux/module.h>
    11. #include <linux/proc_fs.h>
    12. #include <linux/kernel.h>
    13. #include <linux/syscalls.h>
    14. #include <linux/stackprotector.h>
    15. #include <linux/string.h>
    16. #include <linux/ctype.h>
    17. #include <linux/delay.h>
    18. #include <linux/ioport.h>
    19. #include <linux/init.h>
    20. #include <linux/initrd.h>
    21. #include <linux/bootmem.h>
    22. #include <linux/acpi.h>
    23. #include <linux/tty.h>
    24. #include <linux/percpu.h>
    25. #include <linux/kmod.h>
    26. #include <linux/vmalloc.h>
    27. #include <linux/kernel_stat.h>
    28. #include <linux/start_kernel.h>
    29. #include <linux/security.h>
    30. #include <linux/smp.h>
    31. #include <linux/profile.h>
    32. #include <linux/rcupdate.h>
    33. #include <linux/moduleparam.h>
    34. #include <linux/kallsyms.h>
    35. #include <linux/writeback.h>
    36. #include <linux/cpu.h>
    37. #include <linux/cpuset.h>
    38. #include <linux/cgroup.h>
    39. #include <linux/efi.h>
    40. #include <linux/tick.h>
    41. #include <linux/interrupt.h>
    42. #include <linux/taskstats_kern.h>
    43. #include <linux/delayacct.h>
    44. #include <linux/unistd.h>
    45. #include <linux/rmap.h>
    46. #include <linux/mempolicy.h>
    47. #include <linux/key.h>
    48. #include <linux/buffer_head.h>
    49. #include <linux/page_cgroup.h>
    50. #include <linux/debug_locks.h>
    51. #include <linux/debugobjects.h>
    52. #include <linux/lockdep.h>
    53. #include <linux/kmemleak.h>
    54. #include <linux/pid_namespace.h>
    55. #include <linux/device.h>
    56. #include <linux/kthread.h>
    57. #include <linux/sched.h>
    58. #include <linux/signal.h>
    59. #include <linux/idr.h>
    60. #include <linux/kgdb.h>
    61. #include <linux/ftrace.h>
    62. #include <linux/async.h>
    63. #include <linux/kmemcheck.h>
    64. #include <linux/sfi.h>
    65. #include <linux/shmem_fs.h>
    66. #include <linux/slab.h>
    67. #include <linux/perf_event.h>
    68. #include <linux/file.h>
    69. #include <linux/ptrace.h>
    70. #include <linux/blkdev.h>
    71. #include <linux/elevator.h>
    72. #include <asm/io.h>
    73. #include <asm/bugs.h>
    74. #include <asm/setup.h>
    75. #include <asm/sections.h>
    76. #include <asm/cacheflush.h>
    77. #ifdef CONFIG_X86_LOCAL_APIC
    78. #include <asm/smp.h>
    79. #endif
    80. void __init my_start_kernel(void)
    81. {
    82.    int i = 0;
    83.    while(1)
    84.   {
    85.        i++;
    86.        if(i%100000 == 0)
    87.            printk(KERN_NOTICE "my_start_kernel here %d \n",i);
    88.            
    89.   }
    90. }
    91. /*
    92. * linux/mykernel/myinterrupt.c
    93. *
    94. * Kernel internal my_timer_handler
    95. *
    96. * Copyright (C) 2013 Mengning
    97. *
    98. */
    99. #include <linux/kernel_stat.h>
    100. #include <linux/export.h>
    101. #include <linux/interrupt.h>
    102. #include <linux/percpu.h>
    103. #include <linux/init.h>
    104. #include <linux/mm.h>
    105. #include <linux/swap.h>
    106. #include <linux/pid_namespace.h>
    107. #include <linux/notifier.h>
    108. #include <linux/thread_info.h>
    109. #include <linux/time.h>
    110. #include <linux/jiffies.h>
    111. #include <linux/posix-timers.h>
    112. #include <linux/cpu.h>
    113. #include <linux/syscalls.h>
    114. #include <linux/delay.h>
    115. #include <linux/tick.h>
    116. #include <linux/kallsyms.h>
    117. #include <linux/irq_work.h>
    118. #include <linux/sched.h>
    119. #include <linux/sched/sysctl.h>
    120. #include <linux/slab.h>
    121. #include <asm/uaccess.h>
    122. #include <asm/unistd.h>
    123. #include <asm/div64.h>
    124. #include <asm/timex.h>
    125. #include <asm/io.h>
    126. #define CREATE_TRACE_POINTS
    127. #include <trace/events/timer.h>
    128. /*
    129. * Called by timer interrupt.
    130. */
    131. void my_timer_handler(void)
    132. {
    133. printk(KERN_NOTICE "\n>>>>>>>>>>>>>>>>>my_timer_handler here<<<<<<<<<<<<<<<<<<\n\n");
    134. }

    可以看出,这个系统目前只是简单地不停输出“my_timer_handler here”、“my_start_kernel

    here”等字样。通过查看源码,可以发现这些输出字符串分别位于 mymain.c 和 myinterrupt.c

    中。只要在此基础上,再加入进程描述 PCB 和进程链表管理、进程切换等代码,一个可运行的小OS kernel

    就完成了。

    运行结果如下:

     

    第四步:总结

    通过以上实验,我们知道了操作系统的核心功能是:进程调度与中断机制。通过与硬件配合,实现多任务处理,再加上上层应用软件的支持,最终变成可以满足用户使用要求的计算机系统。

    实验三 分析内核启动过程

    第一步:内核启动完成后进入menu程序

    1. cd ~/LinuxKernel/
    2. qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

    第二步:gdb跟踪调试

    1. $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
    2. # 打开 GDB 调试器
    3. $ gdb
    4. # 在 GDB 中输入以下命令:
    5. # 在gdb界面中targe remote之前加载符号表
    6. (gdb)file linux-3.18.6/vmlinux
    7. # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
    8. (gdb)target remote:1234
    9. # 断点的设置可以在target remote之前,也可以在之后
    10. (gdb)break start_kernel

    第三步:实验结果

     

    学号:485 

    参考资料

    操作系统大赛地址oscomp/proj111-cypher-reconstruction: 基于openssl实现远程SSH登录的国密改造 (github.com)

    Linux 内核分析配套实验_Linux - 蓝桥云课 (lanqiao.cn)

    庖丁解牛Linux操作系统分析https://gitee.com/mengning997/linuxkernel

  • 相关阅读:
    Redis快速上手篇七(集群-六台虚拟机)
    如何让 GPT 输出稳定的 JSON
    MySQL 锁机制
    安防视频监控/视频集中存储/云存储平台EasyCVR平台无法播放HLS协议该如何解决?
    MacOS安装反编译工具JD-GUI 版本需要1.8+
    springboot报错驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接,解决方式
    设计模式:单例、原型和生成器
    微信页面公众号页面 安全键盘收起后键盘下方页面留白
    小米手机打开开发者模式
    1 Mybatis动态SQL
  • 原文地址:https://blog.csdn.net/dancer_one/article/details/125600454