かなり強引技だけど,仮想メモリのアドレスをそのまま物理メモリアドレス変換するページテーブルを作成してみた.
# もっとスマートなやりかたないですかねー...?
#include <linux/module.h> #include <linux/init.h> #include <asm/page.h> #include <linux/pagemap.h> // 物理メモリにアクセスするためのページテーブル void *linear_pagedir = NULL; /* * 物理メモリにアクセスするためのページテーブルを作成 * (最初に1回これを呼ぶ) */ void linear_pagedir_init(void) { struct page *pagedir_page; ulong pde_template, pde; int i; ulong *pd; pagedir_page = alloc_page(GFP_ATOMIC | __GFP_ZERO); linear_pagedir = page_address(pagedir_page); pd = (ulong *) linear_pagedir; pde_template = (1 << 7) + (1 << 1) + (1 << 0); for (i = 0; i < 1024; i++) { pde = pde_template | (i << 22); pd[i] = pde; } } /* * 物理メモリを1ワード読む * phys_addr: 読みたい物理アドレス * val: 読み出す変数 * * 事前にlinear_pagedir_init()を呼んでおく必要あり. */ asmlinkage void read_phys_mem (ulong phys_addr, ulong *val) { ulong tmpcr3 = (ulong) __pa(linear_pagedir); asm volatile ( "mov %%cr3, %%eax\n\t" "mov %1, %%cr3\n\t" "mov (%2), %%ebx\n\t" "mov %%eax, %%cr3\n\t" "mov %%ebx, %0" : "=r" (*val) : "r" (tmpcr3), "r" (phys_addr) : "%eax", "%ebx", "cc" ); } /** * 物理メモリにアクセスするためのページテーブルを開放 * (最後に1回これを呼ぶ) */ void linear_pagedir_free(void) { if (linear_pagedir == NULL) { // no need to free } else { free_page((ulong)linear_pagedir); linear_pagedir = NULL; } }