From 175e7496608f3526eff2b8b0aff640ad3dc046d6 Mon Sep 17 00:00:00 2001 From: proninyaroslav Date: Sun, 5 Aug 2018 13:20:01 +0300 Subject: [PATCH] Update linux-bootstrap-5.md --- Booting/linux-bootstrap-5.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Booting/linux-bootstrap-5.md b/Booting/linux-bootstrap-5.md index bb76b18..48a0aad 100644 --- a/Booting/linux-bootstrap-5.md +++ b/Booting/linux-bootstrap-5.md @@ -60,14 +60,21 @@ ENTRY(startup_64) `rbp` содержит начальный адрес распакованного ядра и после выполнения этого кода регистр `rbx` будет содержать адрес релокации ядра для декомпрессии. Такой код мы уже видели в `startup_32` (вы можете прочитать об этом в предыдущей части - [Расчёт адреса релокации](https://github.com/proninyaroslav/linux-insides-ru/blob/master/Booting/linux-bootstrap-4.md#Расчёт-адреса-релокации)), но нам снова нужно вычислить его, поскольку загрузчик может использовать 64-битный протокол загрузки и в этом случае `startup_32` просто не будет выполнен. -На следующем шаге мы видим установку указателя стека и сброс регистра флагов: +На следующем шаге мы видим установку указателя стека, сброс регистра флагов и установку `GDT` заново из-за того, что в случае `64-битного` протокола `32-битный` сегмент кода может быть проигнорирован загрузчиком: ```assembly - leaq boot_stack_end(%rbx), %rsp + leaq boot_stack_end(%rbx), %rsp + + leaq gdt(%rip), %rax + movq %rax, gdt64+2(%rip) + lgdt gdt64(%rip) + pushq $0 popfq ``` +Если вы посмотрите на исходный код ядра Linux после команды `lgdt gdt64(%rip)`, вы увидите, что есть некоторый дополнительный код. Этот код необходим для включения [пятиуровневой страничной организации](https://lwn.net/Articles/708526/), в случае необходимости. В этой книге мы рассмотрим только четырёхуровневую страничную организацию, поэтому этот код будет проигнорирован. + Как вы можете видеть выше, регистр `rbx` содержит начальный адрес кода декомпрессора ядра, и мы помещаем этот адрес со смещением `boot_stack_end` в регистр `rsp`, который представляет указатель на вершину стека. После этого шага стек будет корректным. Вы можете найти определение `boot_stack_end` в конце [arch/x86/boot/compressed/head_64.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/compressed/head_64.S): ```assembly