Which Page table is appled when MMU is turned on in boot process of ARM64

JeongHwan Kim frog007.kernel.kr at gmail.com
Fri Mar 18 03:41:29 EDT 2022


Thank you for reply.


I have a question about the meaning of "Until MMU is turned on, the CPU 
has been

using physical address and pc-relative jumps."

I understand the CPU runs on physical address in assembly code before MMU is enabled.

But how is it possible?

For example, when the head.S is compiled, the PIC(position independent code) option is disabled as like this using -fno-PIE option:
aarch64-linux-gnu-gcc -Wp,-MMD,arch/arm64/kernel/.head.o.d  -nostdinc 
-isystem /usr/lib/gcc-cross/aarch64-linux-gnu/9/include 
-I./arch/arm64/include -I./arch/arm64/include/generated  -I./include 
-I./arch/arm64/include/uapi -I./arch/arm6 4/include/generated/uapi 
-I./include/uapi -I./include/generated/uapi -include 
./include/linux/compiler-version.h -include ./include/linux/kconfig.h 
-D__KERNEL__ -mlittle-endian -DKASAN_SHADOW_SCALE_SHIFT= 
-fmacro-prefix-map=./= -D__ASSEMB LY__ -fno-PIE -mabi=lp64 
-fno-asynchronous-unwind-tables -fno-unwind-tables 
-DKASAN_SHADOW_SCALE_SHIFT= -Wa,-gdwarf-2    -c -o 
arch/arm64/kernel/head.o arch/arm64/kernel/head.S
and system.map shows all the symbols of assembly code are virtual address.

Please let me know the method how the assembly code runs in PIC way.
Only are the pc-relative jumps needed?

Regards,
J.Hwan KIm

On 22. 3. 18. 14:35, Chan Kim wrote:
> Hi JeongHwan,
>
> Recently I followed the kernel boot process so now I understand how it's
> doing.
> The kernel starts at HEAD and it jumps to primary_entry. (code below is
> 5.10.0.  but in 5.4.21 it jumped to stext, just name change)
> Primary_entry looks like this.
>
>         SYM_CODE_START(primary_entry)
>
>              bl  preserve_boot_args
>              bl  el2_setup           // Drop to EL1, w0=cpu_boot_mode
>              adrp    x23, __PHYS_OFFSET
>              and x23, x23, MIN_KIMG_ALIGN - 1    // KASLR offset, defaults to
> 0
>              bl  set_cpu_boot_mode_flag
>              bl  __create_page_tables
>              /*
>               * The following calls CPU setup code, see arch/arm64/mm/proc.S
> for
>               * details.
>               * On return, the CPU will be ready for the MMU to be turned on
> and
>               * the TCR will have been set.
>               */
>              bl  __cpu_setup         // initialise processor
>              b   __primary_switch
>          SYM_CODE_END(primary_entry)
>
> The page tables for id mapping (for 0x80000000 ~ .. physical address) and
> swapper_pgdir (for virtual address) are setup inside __create_page_tables.
> MMU is turned on in __primary_switch. (code below for 5.10.0-rc5)
> You see there is bl __enable_mmu. Until MMU is turned on, the CPU has been
> using physical address and pc-relative jumps.
> At the instant MMU is turned on, the page table for the current physical
> address range is already setup so there is no problem using physical
> address.(just identical mapping)
> The first place where kernel virtual address is used is at the end of
> __primary_switch. The value __primary_switched is a virtual address
> (starting with 0xffffffc0....) and from that point on virtual->physical
> address mapping is used.  Old version will be the same. (I checked
> previously for 5.4.21)
>
>
> 		SYM_FUNC_START_LOCAL(__primary_switch)
> 		#ifdef CONFIG_RANDOMIZE_BASE
> 		    mov x19, x0             // preserve new SCTLR_EL1 value
> 		    mrs x20, sctlr_el1          // preserve old SCTLR_EL1
> value
> 		#endif
> 		
> 		    adrp    x1, init_pg_dir
> 		    bl  __enable_mmu
> 		#ifdef CONFIG_RELOCATABLE
> 		#ifdef CONFIG_RELR
> 		    mov x24, #0             // no RELR displacement yet
> 		#endif
> 		    bl  __relocate_kernel
> 		#ifdef CONFIG_RANDOMIZE_BASE
> 		    ldr x8, =__primary_switched
> 		    adrp    x0, __PHYS_OFFSET
> 		    blr x8
> 		
> 		    /*
> 		     * If we return here, we have a KASLR displacement in
> x23 which we need
> 		     * to take into account by discarding the current kernel
> mapping and
> 		     * creating a new one.
> 		     */
> 		    pre_disable_mmu_workaround
> 		    msr sctlr_el1, x20          // disable the MMU
> 		    isb
> 		    bl  __create_page_tables        // recreate kernel
> mapping
> 		
> 		    tlbi    vmalle1             // Remove any stale TLB
> entries
> 		    dsb nsh
> 		
> 		    msr sctlr_el1, x19          // re-enable the MMU
> 		    isb
> 		    ic  iallu               // flush instructions fetched
> 		    dsb nsh             // via old mapping
> 		    isb
> 		
> 		    bl  __relocate_kernel
> 		#endif
> 		#endif
> 		    ldr x8, =__primary_switched
> 		    adrp    x0, __PHYS_OFFSET
> 		    br  x8
> 		SYM_FUNC_END(__primary_switch)
> 		
>
> Hope this helps.
> Have a nice day!
>
> Chan
>
>> -----Original Message-----
>> From: JeongHwan Kim<frog007.kernel.kr at gmail.com>
>> Sent: Friday, March 18, 2022 10:41 AM
>> To:kernelnewbies at kernelnewbies.org
>> Subject: Which Page table is appled when MMU is turned on in boot process
>> of ARM64
>>
>> Hi, everyone
>>
>>
>> When ARM64 boots, it setup 2 page tables ("idmap_pg_dir" and
>> "swapper_pgdir").
>>
>> On turning on MMU, which page table is applied?
>>
>> I heard that "idmap_pg_dir" is applied as soon as MMU is turned on.
>>
>> I cannot understand why "idmap_pg_dir" is applied, which is for "Lower"
>> address.
>>
>> As I understand, the virtual address of kernel code is in "Higher"
> address.
>> Can you explain why "idmap_pg_dir" is applied on MMU turning on?
>>
>>
>> Thanks in advance
>>
>> J.Hwan Kim
>>
>>
>>
>>
>> _______________________________________________
>> Kernelnewbies mailing list
>> Kernelnewbies at kernelnewbies.org
>> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20220318/9c156b33/attachment-0001.html>


More information about the Kernelnewbies mailing list