1

やあ、

「mem_map」配列内のすべてのページの「フラグ」フィールドの値を出力するユーザー プログラムを作成しようとしています。次に、予約ビットが設定されているかどうかを確認したいと思います。

手始めに、「mem_map」配列の最初の 20 ページの値、それぞれの「フラグ」フィールド、および PageReserved マクロの出力を出力するカーネル モジュールを作成しました。

for (;i < 20; ++i) {
  unsigned long *value = &(mem_map[i].flags);
  printk("i = %u page->flags value = %u phy address = %#x isReserved = %d\n", i,mem_map[i].flags, virt_to_phys(&(mem_map[i].flags)),PageReserved(&mem_map[i]));
}

「dmesg | tail -50」を実行すると、次の値が表示されます。

[ 2858.387520] i = 0 ページ -> フラグ値 = 0 物理アドレス = 0x36840000 isReserved = 0
[ 2858.387520] i = 1 ページ -> フラグ値 = 1024 物理アドレス = 0x36840020 isReserved = 1
[ 2858.387520] i = 2 ページ -> フラグ値 = 1024 物理アドレス = 0x36840040 isReserved = 1
[ 2858.387520] i = 3 ページ -> フラグ値 = 1024 物理アドレス = 0x36840060 isReserved = 1

「フラグ」フィールドの物理アドレスを値とともに出力していることに注意してください。

ポインタを介してアドレスを見るだけで、上記の結果をユーザープログラムで再現したいと考えています。

最初のページの「フラグ」フィールドのオフセット: 0x36840000 で「/dev/mem」を開きました。STRICT_DEVMEM をオフにしてカーネルをコンパイルし、「devmem_is_allowed()」関数にデフォルトの「return 1」を追加したことを確認しました。

 /* create the offset for mmap() using the physical address of the
    mem_map[] array*/
    off_t offset = 0x36840000;

    /* /dev/mem contains the physical memory map */
    if ((fd = open("/dev/mem", O_RDONLY)) == -1) {
        printf("/dev/mem could not be opened.\n");
        perror("open");
        exit(1);
    else {
        printf("/dev/mem opened.\n");
    }

    starting_page = (char*)mmap(0, MAP_SIZE, PROT_READ,MAP_SHARED, fd,offset);

    if (starting_page == MAP_FAILED) {
        perror("mmap");
        return -1;
    } 
    else {
        printf("Memory mapped at address %p.\n", starting_page);
    }
    mapped_page = starting_page;
    for (i=0;i<10;++i,mapped_page+=32) { 
        printf("\npage i = %u flags value %ul  ", i, *(mapped_page));
    }

ただし、「フラグ値」の値を単純に出力すると、ゼロになります。ゼロを取得しているものと、これをデバッグする方法について何か提案はありますか?

ありがとう!-RR

4

0 に答える 0