Skip to content

mykernel代码疑问 #15

Open
Open

Description

@meilihao

疑问:

  1. 进程切换时为什么rbp不像rsp那样存成Thread的成员而是通过压栈处理?
  2. 进程切换完成后next进程的rip指向了"popq %rbp", 它是如何接着上次的中断位置继续执行的?
  3. 无法理解启动第一个进程的这句"pushq %1\n\t", 因为此时rbp的值应是my_start_kernel的rbp, 这句又没给rbp赋新值, 有何意义?

Activity

  1. mengning commented on Sep 19, 2020

    @mengning
    Owner

    https://mp.weixin.qq.com/s/SzpN1BNty5aPDZhNdCO5yA

    这里我写了一篇文章并配了视频,希望对您有帮助。

  2. meilihao commented on Sep 19, 2020

    @meilihao
    Author

    嗯. 抱歉, 我就是看完所有能找到的资料(包括上面的链接)都没法解答才问的.

  3. mengning commented on Sep 20, 2020

    @mengning
    Owner

    问:

    1. 进程切换时为什么rbp不像rsp那样存成Thread的成员而是通过压栈处理?

    其实rip和rsp是CPU现场中最关键的两个,缺一不可,而rbp则不是最关键的,可以通过间接的方式处理,当然像rsp一样处理也可以工作,但为什么有通用的堆栈机制方法不用而采用特例呢?

    1. 进程切换完成后next进程的rip指向了"popq %rbp", 它是如何接着上次的中断位置继续执行的?

    rsp指向next进程的堆栈栈顶,而栈顶恰恰是"popq %rbp"

    1. 无法理解启动第一个进程的这句"pushq %1\n\t", 因为此时rbp的值应是my_start_kernel的rbp, 这句又没给rbp赋新值, 有何意义?

    这一点你要理解函数调用堆栈框架,只是从头开始的进程栈底稍微特殊一点,空栈也就是rsp和rbp相同。

  4. meilihao commented on Sep 21, 2020

    @meilihao
    Author
    1. 很容易理解了
    2. 结合反汇编看看, 也理解了
    3. 还是没明白.

    我对函数调用堆栈有基本的概念, 之前自学过一点反汇编. 通常函数开头都有这两句, 就是为了让rsp和rbp相同.

        1211:	55                   	push   %rbp
        1212:	48 89 e5             	mov    %rsp,%rbp
    

    我反汇编my_start_kernel的结果是:

    ...
    ffffffff8185f02a:	48 c7 05 53 50 09 00 	movq   $0xffffffff818f40a0,0x95053(%rip)        # ffffffff818f4088 <my_current_task>
    ffffffff8185f031:	a0 40 8f 81 
    ffffffff8185f035:	48 8b 0d 74 90 09 00 	mov    0x99074(%rip),%rcx        # ffffffff818f80b0 <task+0x4010>
    ffffffff8185f03c:	48 8b 15 75 90 09 00 	mov    0x99075(%rip),%rdx        # ffffffff818f80b8 <task+0x4018>
    ffffffff8185f043:	48 89 d4             	mov    %rdx,%rsp # rsp=rdx=task[pid].thread.sp
    ffffffff8185f046:	52                   	push   %rdx # pushq %rdx= `subq $8, %rsp` + `movq %rdx, (%rsp)`
    ffffffff8185f047:	51                   	push   %rcx
    ffffffff8185f048:	c3                   	retq   
    ffffffff8185f049:	5d                   	pop    %rbp
    ffffffff8185f04a:	5d                   	pop    %rbp
    ffffffff8185f04b:	c3                   	retqs
    

    还是没看出push %rdx与rbp有什么关系.

  5. mengning commented on Sep 22, 2020

    @mengning
    Owner
    1. 很容易理解了
    2. 结合反汇编看看, 也理解了
    3. 还是没明白.

    我对函数调用堆栈有基本的概念, 之前自学过一点反汇编. 通常函数开头都有这两句, 就是为了让rsp和rbp相同.

        1211:	55                   	push   %rbp
        1212:	48 89 e5             	mov    %rsp,%rbp
    

    我反汇编my_start_kernel的结果是:

    ...
    ffffffff8185f02a:	48 c7 05 53 50 09 00 	movq   $0xffffffff818f40a0,0x95053(%rip)        # ffffffff818f4088 <my_current_task>
    ffffffff8185f031:	a0 40 8f 81 
    ffffffff8185f035:	48 8b 0d 74 90 09 00 	mov    0x99074(%rip),%rcx        # ffffffff818f80b0 <task+0x4010>
    ffffffff8185f03c:	48 8b 15 75 90 09 00 	mov    0x99075(%rip),%rdx        # ffffffff818f80b8 <task+0x4018>
    ffffffff8185f043:	48 89 d4             	mov    %rdx,%rsp # rsp=rdx=task[pid].thread.sp
    ffffffff8185f046:	52                   	push   %rdx # pushq %rdx= `subq $8, %rsp` + `movq %rdx, (%rsp)`
    ffffffff8185f047:	51                   	push   %rcx
    ffffffff8185f048:	c3                   	retq   
    ffffffff8185f049:	5d                   	pop    %rbp
    ffffffff8185f04a:	5d                   	pop    %rbp
    ffffffff8185f04b:	c3                   	retqs
    

    还是没看出push %rdx与rbp有什么关系.

    rdx应该是task[pid].thread.sp,也就是next进程的rsp,next进程是一个新程序,为空栈
    因此这时要压栈rbp,那就直接压栈rsp就好了,这地方只是我自己的简便写法,实际Linux内核中启动一个新程序的做法要复杂的多。

  6. meilihao commented on Sep 22, 2020

    @meilihao
    Author

    "空栈也就是rsp和rbp相同", 这我理解, 但mykernel里的这个场景需要我们手动调整, 因为起先rsp和rbp都是my_start_kernel的. 我认为这段内嵌汇编应该实现让rsp与rbp相等. 但实际只是设置了rsp让它等于rdx, push %rdx后, rbp还是不等于rsp呀, 因此还是有点懵.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions