Microblaze をプロセッサとして使用する組み込みボード用のアプリケーションを構築しています。このために Linux をクロスコンパイルしました。ボードには 512 MB のメモリがありますが、カーネルはそのうちの 256 MB (DDR3 の下半分) しか認識していません。
これは、システムのメモリ マップです。
0x4000_0000 to 0x5FFF_FFFF -> Physical range of DDR3 (verified with cat /proc/meminfo)
0x4000_0000 to 0x4FFF_FFFF -> Known to linux and used by the kernel
0x5000_0000 to 0x5FFF_FFFF -> Mmaped using "/dev/mem" for my application
DDR の領域、特に DDR の後半に直接アクセスする必要があります。そこで、mmap の物理メモリを次のようにマッピングするアプリケーションを作成しました。
typedef struct
{
int fd; // File descriptor
unsigned long *hw_addr; // Hardware base address
unsigned long *vaddr; // Virtual address pointer
unsigned long memsize; // Size of physical region
off_t page_offset;
off_t page_address;
off_t page_size;
} mem_region_t ;
mem->vaddr = (unsigned long *) mmap(0,
mem->memsize,
PROT_READ|PROT_WRITE,
MAP_SHARED,
mem->fd,
mem->page_address);
動作をテストするために、要求された領域で簡単なメモリ テスト (memtest) を実行しています。
ここに私が気づいているいくつかの問題があります:
任意の量のメモリを割り当てて mmap できますが、問題ありません。memtest に小さな領域 0x100 バイトを使用すると、テストが正常に実行されます。
大きな領域 (0x1000、0x1_0000 など) を割り当てると、カーネルはセグメンテーション違反を起こさず、ハングします !! この動作は正常ですか?
問題を回避する方法を提案できますか? 私はそれを正しくマッピングしていますか?
私の疑いでは、メモリのページよりも小さいものはすべて機能し、それ以上のものはひどく失敗する. カーネルで機能を有効にする必要がありますか?
ご清聴ありがとうございました。さらに情報が必要な場合はお知らせください。
RRS