Эмулирует ли QEMU ARM-сопроцессор? - PullRequest
0 голосов
/ 08 ноября 2018

Мне нужно реализовать модуль ядра, который включает чтение регистра сопроцессора ARM Cortex-A9:

register int reg asm ("r6");
reg = -2;
volatile printk(KERN_INFO "reg: %d\n", reg);
volatile  asm("MRC p15, 0,r6, c1, c0, 2;"); //Read Coprocessor Access Control Register
volatile  printk(KERN_INFO "reg: %d\n", reg);

Однако, когда я запускаю это на QEMU, оно всегда распечатывается:

reg: -2
reg: -2

Это из-за моего кода или из-за QEMU?

Заранее спасибо.

1 Ответ

0 голосов
/ 09 ноября 2018

Ваш код должен работать нормально (хотя вам нужно удалить volatile из printk строк, а команда ASM должна быть asm volatile, а не наоборот). Попробуйте проверить следующее:

  1. Версия QEMU. Я использую 2.12, и ваш код работает. Так что, если вы используете старую версию, попробуйте 2.12 тоже.
  2. Эмулируемая машина и процессор. Не уверен, влияет ли это на регистры CP, но я использую машину "virt" без указания процессора, вы также можете попробовать эту конфигурацию.
  3. Если это не поможет, проверьте более подробную информацию о моей конфигурации ниже.

Моя конфигурация

Я использую следующую команду для запуска QEMU:

$ qemu-system-arm -kernel $zimage -initrd $rootfs \
    -machine virt -nographic -m 512 \
    --append "root=/dev/ram0 rw console=ttyAMA0,115200 mem=512M"

где:

  • $zimage - это путь к файлу zImage (мое ядро ​​- linux-mainline для тега v4.18, построено с конфигурацией multi_v7_defconfig)
  • $rootfs - это путь к архиву CPIO с минимальными rootfs BusyBox

Мой код модуля ядра следующий:

#include <linux/module.h>

static int __init mrc_init(void)
{
    u32 acr;

    /*
     * Read Coprocessor Access Control Register.
     * See Cortex-A9 TRM for details.
     */
    asm volatile ("mrc p15, 0, %0, c1, c0, 2\n" : "=r" (acr));

    pr_info("ACR = 0x%x\n", acr);

    return 0;
}

static void __exit mrc_exit(void)
{
}

module_init(mrc_init);
module_exit(mrc_exit);

MODULE_AUTHOR("Sam Protsenko");
MODULE_DESCRIPTION("Test MRC on QEMU");
MODULE_LICENSE("GPL");

После загрузки этого модуля я вижу следующий вывод в dmesg:

ACR = 0xf00000
...