为什么 linux 内核中的这段代码不会导致死循环?
Why is this piece of code in linux kernel NOT causing dead loop?
我正在阅读linux源代码(4.4.45,但其他版本应该相同)关于页面table启动时初始化,下面的代码让我感到困惑。
具体来说,我正在阅读 early_level4_pgt
是如何初始化的。这是x86_64中的部分代码,link is here.
leaq level2_kernel_pgt(%rip), %rdi
leaq 4096(%rdi), %r8
/* See if it is a valid page table entry */
1: testb , 0(%rdi)
jz 2f
addq %rbp, 0(%rdi)
/* Go to the next page */
2: addq , %rdi
cmp %r8, %rdi
jne 1b
/* Fixup phys_base */
addq %rbp, phys_base(%rip)
movq $(early_level4_pgt - __START_KERNEL_map), %rax
jmp 1f
ENTRY(secondary_startup_64)
(below is omitted...)
从1:
开始,无论如何都会去2:
;而在 2:
里面,无论如何都会跳回 1:
!!
我真的很困惑,这个循环是怎么结束的,内核什么时候进入secondary_startup_64
?我的猜测是,当它访问一个无效的 pmd 条目时,会导致页面错误,处理程序将处理其余的启动代码。但是我不是很清楚,也不知道在哪里可以找到相应的代码。
谁能给我一些线索?感谢任何帮助。
jmp 1f
表示向前跳转到标签1
(在这条指令之后)。
jmp 1b
表示向后跳转到标签1
(在这条指令之前)。
因此 jmp 1f
行跳转到其后的标签 1
,不会导致死循环。
我正在阅读linux源代码(4.4.45,但其他版本应该相同)关于页面table启动时初始化,下面的代码让我感到困惑。
具体来说,我正在阅读 early_level4_pgt
是如何初始化的。这是x86_64中的部分代码,link is here.
leaq level2_kernel_pgt(%rip), %rdi
leaq 4096(%rdi), %r8
/* See if it is a valid page table entry */
1: testb , 0(%rdi)
jz 2f
addq %rbp, 0(%rdi)
/* Go to the next page */
2: addq , %rdi
cmp %r8, %rdi
jne 1b
/* Fixup phys_base */
addq %rbp, phys_base(%rip)
movq $(early_level4_pgt - __START_KERNEL_map), %rax
jmp 1f
ENTRY(secondary_startup_64)
(below is omitted...)
从1:
开始,无论如何都会去2:
;而在 2:
里面,无论如何都会跳回 1:
!!
我真的很困惑,这个循环是怎么结束的,内核什么时候进入secondary_startup_64
?我的猜测是,当它访问一个无效的 pmd 条目时,会导致页面错误,处理程序将处理其余的启动代码。但是我不是很清楚,也不知道在哪里可以找到相应的代码。
谁能给我一些线索?感谢任何帮助。
jmp 1f
表示向前跳转到标签1
(在这条指令之后)。
jmp 1b
表示向后跳转到标签1
(在这条指令之前)。
因此 jmp 1f
行跳转到其后的标签 1
,不会导致死循环。