如何使用汇编将变量的地址加载到寄存器中?(arm64 linux内核代码)

bpsygsoo  于 2023-04-05  发布在  Linux
关注(0)|答案(1)|浏览(234)

过一会儿回到汇编代码。
我把这段代码放在Linux内核启动之后(linux-5.15.68)。

.global mydebug2
....(skip)
SYM_CODE_START(primary_entry)
    mov x27, #0x3333
    ldr x28, mydebug2
    add x28, x28, #8
    str x27, [x28], #8
    ldr x26, =myptr
    str x28, [x26]
    b .

    bl  preserve_boot_args
    bl  init_kernel_el          // w0=cpu_boot_mode

缓冲区“mydebug 2”在init/main. c中定义如下。

#include <test/mwtest.h>
uint64_t mydebug2[MWBUF_LENGTH] = {0,};
uint32_t myidx = 0;
uint64_t mycnt = 0; // for left shift, 64bit

asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
{
    char *command_line;
    char *after_dashes;

当我编译它的时候,我在最后得到这个错误。
LD .tmp_vmlinux.kallsyms1 arch/arm64/kernel/head.o:在init/main.o中.bss部分定义的函数primary_entry': /home/ckim/prj1/LinuxDevDrv/linux-5.15.68/arch/arm64/kernel/head.S:97:(.init.text+0x4): relocation truncated to fit: R_AARCH64_LD_PREL_LO19 against symbol mydebug 2 '中,make:***[Makefile:1214:vmlinux]错误1
我猜mydebug 2是虚拟地址(如0xffffffc 008 c4 b 028),ldr x28, mydebug2指令无法将该地址加载到x28中。如何将该地址加载到x28中?
(BTW,我知道在当前的设置中,物理地址是如何Map到内核虚拟地址的。我看到0xffffffc 008000000对应于物理内存0x 80200000)。

ADD:正如Nate Eldredge所建议的,我尝试使用adrp和add对,它们在arch/arm64/include/asm/assembler.h中定义如下。

/*
 * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
 * <symbol> is within the range +/- 4 GB of the PC.
 */
    /*
     * @dst: destination register (64 bit wide)
     * @sym: name of the symbol
     */
    .macro  adr_l, dst, sym
    adrp    \dst, \sym
    add \dst, \dst, :lo12:\sym
    .endm
    .... more (skip) ...
h43kikqp

h43kikqp1#

在ARM64寄存器中生成地址的最常见方法是pc相对的,使用adrpldr x28, =mydebug2语法,从文字池加载,通常也是一个选项,但在这种情况下,似乎内核的重定位修复还没有完成,所以这不会起作用。
因此,按照以下理解ARM重新定位(示例:strx0,[tmp,#:lo12:zbi_paddr]),你想做什么

mov x27, #0x3333
    adrp x28, mydebug2
    add x28, x28, #:lo12:mydebug2
    add x28, x28, #8
    str x27, [x28], #8

由于完整的相对地址不适合一条指令,adrp提供21个高位,#lo12:mydebug2提供12个低位。
实际上,通过将+8构建到地址计算中,可以保存一条指令:

mov x27, #0x3333
    adrp x28, mydebug2+8
    add x28, x28, #:lo12:mydebug2+8
    str x27, [x28], #8

(Note+8需要在两个位置,以考虑+8导致低12位进位的可能性,这是add可以编码为立即数的全部。
您需要在下一行对myptr执行相同的操作。

相关问题