From 3c4a6e6bd7c811957e1342c730d881b11c0688b4 Mon Sep 17 00:00:00 2001 From: Z Date: Tue, 17 Nov 2020 21:06:20 +0800 Subject: [PATCH 1/3] Update linux-initialization-2.md --- Initialization/linux-initialization-2.md | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Initialization/linux-initialization-2.md b/Initialization/linux-initialization-2.md index c1fc024..d2a40ad 100644 --- a/Initialization/linux-initialization-2.md +++ b/Initialization/linux-initialization-2.md @@ -314,6 +314,13 @@ Now let's look on the `early_idt_handler_common` implementation. It locates in t incl early_recursion_flag(%rip) ``` +The `early_recursion_flag` locates in the same assembly file as the `early_idt_handler_common` symbol like the following: + +```assembly + early_recursion_flag: + .long 0 +``` + Next we save general registers on the stack: ```assembly @@ -410,6 +417,33 @@ int __init early_make_pgtable(unsigned long address) } ``` +`__PAGE_OFFSET` is defined in the [arch/x86/include/asm/page_64_types.h](https://www.notion.so/lance1994/IDT-Interrupt-Descriptor-Table-2a2e5714fbf44b2f8dc3cf962a1a13e6#60c1ca54af4042b292921f1640f8c893) header file, and you can note that the `UL` tells the compiler that they are not of type int, but unsigned long. + +```C +#define __PAGE_OFFSET _AC(0xffff880000000000, UL) +``` + +And the `_AC` macro is defined in the [include/uapi/linux/const.h](https://www.notion.so/lance1994/IDT-Interrupt-Descriptor-Table-2a2e5714fbf44b2f8dc3cf962a1a13e6#5e0b21a1a3394a7bbb526897708dc5a4) header file: + +```C +/* Some constant macros are used in both assembler and + * C code. Therefore we cannot annotate them always with + * 'UL' and other type specifiers unilaterally. We + * use the following macros to deal with this. + * + * Similarly, _AT() will cast an expression with a type in C, but + * leave it unchanged in asm. + */ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#endif +``` +So, where `__PAGE_OFFSET` expands to `0xffff880000000000`. + We initialize `pmd` and pass it to the `__early_make_pgtable` function along with `address`. The `__early_make_pgtable` function is defined in the same file as the `early_make_pgtable` function as the following: ```C From 1862f56adfa71bcd002a19e386f6ce560a93daff Mon Sep 17 00:00:00 2001 From: Z Date: Wed, 18 Nov 2020 08:08:36 +0800 Subject: [PATCH 2/3] Update linux-initialization-2.md --- Initialization/linux-initialization-2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Initialization/linux-initialization-2.md b/Initialization/linux-initialization-2.md index d2a40ad..e625952 100644 --- a/Initialization/linux-initialization-2.md +++ b/Initialization/linux-initialization-2.md @@ -417,13 +417,13 @@ int __init early_make_pgtable(unsigned long address) } ``` -`__PAGE_OFFSET` is defined in the [arch/x86/include/asm/page_64_types.h](https://www.notion.so/lance1994/IDT-Interrupt-Descriptor-Table-2a2e5714fbf44b2f8dc3cf962a1a13e6#60c1ca54af4042b292921f1640f8c893) header file, and you can note that the `UL` tells the compiler that they are not of type int, but unsigned long. +`__PAGE_OFFSET` is defined in the [arch/x86/include/asm/page_64_types.h](https://elixir.bootlin.com/linux/v3.10-rc1/source/arch/x86/include/asm/page_64_types.h#L33) header file, and you can note that the `UL` tells the compiler that they are not of type int, but unsigned long. ```C #define __PAGE_OFFSET _AC(0xffff880000000000, UL) ``` -And the `_AC` macro is defined in the [include/uapi/linux/const.h](https://www.notion.so/lance1994/IDT-Interrupt-Descriptor-Table-2a2e5714fbf44b2f8dc3cf962a1a13e6#5e0b21a1a3394a7bbb526897708dc5a4) header file: +And the `_AC` macro is defined in the [include/uapi/linux/const.h](https://elixir.bootlin.com/linux/v3.10-rc1/source/include/uapi/linux/const.h#L16) header file: ```C /* Some constant macros are used in both assembler and From 41bc27ff71526a138de4495e134dc07ea8774c06 Mon Sep 17 00:00:00 2001 From: Z Date: Wed, 18 Nov 2020 16:23:34 +0800 Subject: [PATCH 3/3] Update linux-initialization-2.md --- Initialization/linux-initialization-2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Initialization/linux-initialization-2.md b/Initialization/linux-initialization-2.md index e625952..34fd00b 100644 --- a/Initialization/linux-initialization-2.md +++ b/Initialization/linux-initialization-2.md @@ -314,7 +314,7 @@ Now let's look on the `early_idt_handler_common` implementation. It locates in t incl early_recursion_flag(%rip) ``` -The `early_recursion_flag` locates in the same assembly file as the `early_idt_handler_common` symbol like the following: +The `early_recursion_flag` is defined in the same assembly file as the `early_idt_handler_common` symbol as follows: ```assembly early_recursion_flag: @@ -417,7 +417,7 @@ int __init early_make_pgtable(unsigned long address) } ``` -`__PAGE_OFFSET` is defined in the [arch/x86/include/asm/page_64_types.h](https://elixir.bootlin.com/linux/v3.10-rc1/source/arch/x86/include/asm/page_64_types.h#L33) header file, and you can note that the `UL` tells the compiler that they are not of type int, but unsigned long. +`__PAGE_OFFSET` is defined in the [arch/x86/include/asm/page_64_types.h](https://elixir.bootlin.com/linux/v3.10-rc1/source/arch/x86/include/asm/page_64_types.h#L33) header file, and the suffix `UL` forces the page offset to be a unsigned long data type. ```C #define __PAGE_OFFSET _AC(0xffff880000000000, UL)