486 /*
487 * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
488 *
489 * this macro returns the index of the entry in the pgd page which would
490 * control the given virtual address
491 */
492 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
493
494 /*
495 * pgd_offset() returns a (pgd_t *)
496 * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
497 */
498 #define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address)))
499 /*
500 * a shortcut which implies the use of the kernel's pgd, instead
501 * of a process's
502 */
503 #define pgd_offset_k(address) pgd_offset(&init_mm, (address))
제 장비에 있는 /usr/src/linux/arch/x86/include/asm/pgtable.h 파일 내용중 일부분입니다.
버전은 우분투 10.04, Linux Linux 2.6.32-22-generic #36-Ubuntu SMP Thu Jun 3 19:31:57 UTC 2010 x86_64 GNU/Linux 입니다.
PML4나 PGD를 구하는 방법이 2가지라고 구글링 해서 알았습니다.
첫번째는 pgd_offset(mm, address)이고,
두번째는 pgd_offset_k(&init_mm, (address))이더군요.
pgd_offset() 함수를 쓸때는 아무런 에러가 안나는데,
pgd_offset_k()함수를 쓰면 디바이스 드라이버 소스를 컴파일할때 아래와 같은 경고가 뜹니다.
WARNING: "init_mm" [/root/hh/hh_dev.ko] undefined!
이상태로 모듈을 insmod할때,
insmod: error inserting 'hh_dev.ko': -1 Unknown symbol in module
라고 뜨구요.
pgd_offset_k()는 virtual address만으로도 page global directory를 구할 수 있다고 해서 시도하고 있는데요,
위와 같은 경고를 없애고 제대로 컴파일, 모듈로드를 하려면 어떻게 해야할까요?
.
init_mm이 EXPORT되지 않아서 그런 것 같습니다.
init_task는 EXPORT되어 있으니 아래와 같이 접근하면 되지 않을까 추측해 봅니다..
pgd_offset(&init_task.active_mm, address)
물론 커널 주소 영역에만 접근해야 합니다.