/* * 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. */ /* * 如果返回到这里表示使用设备树的`kaslr-seed`来启动kaslr, 这里内核已经被重新copy * 到(0xffff_0000_0000_0000 + 128M(module) + kaslr-seed + TEXT_OFFSET的 * 位置, 因此内核的页表, 符号都需要重新进行设定. 所以下面的code关闭MMU, 重建页表, * 修复内核符号, 再次跳入__primary_switched */ 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
__relocate_kernel: /* * Iterate over each entry in the relocation table, and apply the * relocations in place. */ ldr w9, =__rela_offset // offset to reloc table ldr w10, =__rela_size // size of reloc table
| 64 bit | 64 bit | 64 bit | ... +----------------+-----------------------------------+----------------- | sym0 link addr | sym0 reloc flag | sym0 link value | sym1 link ... +----------------+-----------------------------------+-----------------
每个relocable symbol有三个entry, 每个entry都是32bit, 分别为link addr, relocation flag, link value. 对于需要重定位内核运行位置的情况, 我们需要把所有FLAG为R_AARCH64_RELATIVE的的entry指定的symbol进行修正, 修正方法为将link addr + offset的值修改为link value + offset. 其实这个段的含义就是说在IMAGE中, link addr的位置中存放的值是地址相关地值, 如果IMAGE发生了整体偏移, 那么link addr的位置实际在link addr + offset, 要把实际位置上的value修正, 这样说不知道是不是更清晰一些.