में एक पॉइंटर को भौतिक डिवाइस मैप करना हमारे पास एक एम्बेडेड सिस्टम है जहां एक मेमोरी मैप किए गए डिवाइस को कनेक्ट किया गया है, और एक एआरएम सीपीयू लिनक्स चलाता है। डिवाइस 0x40400000
पते पर स्थित है और मेगाबाइट पर कब्जा कर लेता है (इसमें से अधिकांश को वास्तविक स्मृति द्वारा समर्थित नहीं किया जाता है, लेकिन पता स्थान किसी भी तरह से डिवाइस पर मैप किया जाता है)। वर्तमान में हम इस डिवाइस के लिए डिवाइस ड्राइवर नहीं है।उपयोगकर्ता स्थान
डिवाइस में 0x404f0704
पते पर एक विशेष रीड-ओनली रजिस्टर (सीआईडी कहा जाता है) है। इस रजिस्टर में CID = 0x404
मान है। मैं इस रजिस्टर को एआरएम पर चल रहे कार्यक्रम से पढ़ने की कोशिश कर रहा हूं।
नेट की खोज में मैंने mmap()
फ़ंक्शन के बारे में सीखा जो माना जाता है कि मुझे उपयोगकर्ता स्थान से भौतिक पता तक पहुंचने देता है।
#include <sys/mman.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *pdev = (void *) 0x40400000;
size_t ldev = (1024*1024);
int *pu;
int volatile *pcid;
int volatile cid;
pu = mmap(pdev, ldev, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if (pu == MAP_FAILED)
errx(1, "mmap failure");
pcid = (int *) (((void *) pu) + 0xf0704);
printf("pu = %08p\n", pu);
printf("pcid = %08p\n", pcid);
cid = *pcid;
printf("CID = %x\n", cid);
munmap(pu, ldev);
return (EXIT_SUCCESS);
}
एआरएम पार संकलक के साथ संकलन:
a-gcc -O0 -g3 -o mmap-test.elf mmap-test.c
मैं अपेक्षित परिणाम नहीं मिल सकता है तो, मैंने पाया उदाहरण के एक जोड़े का पालन करने की कोशिश कर, मैं निम्नलिखित परीक्षण लिखा था। क्या मैं देख रहा हूँ यह है कि:
pu = 0x40400000
pcid = 0x404f0704
CID = 0
बजाय अपेक्षित
CID = 404
मैं क्या याद आ रही है/कर गलत यहाँ की
?
अद्यतन:
मैं एक डेमो कार्यक्रम मिल गया और अपने कोड निम्नलिखित मैं अपने कोड काम कर प्राप्त करने में सक्षम था: फिर भी
int main(void)
{
off_t dev_base = 0x40400000;
size_t ldev = (1024 * 1024);
unsigned long mask = (1024 * 1024)-1;
int *pu;
void *mapped_base;
void *mapped_dev_base;
int volatile *pcid;
int volatile cid;
int memfd;
memfd = open("/dev/mem", O_RDWR | O_SYNC);
mapped_base = mmap(0, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, dev_base & ~MAP_MASK);
if (mapped_base == MAP_FAILED)
errx(1, "mmap failure");
mapped_dev_base = mapped_base + (dev_base & MAP_MASK);
pu = mapped_dev_base;
pcid = (int *) (((void *) pu) + 0xf0704);
printf("pu = %08p\n", pu);
printf("pcid = %08p\n", pcid);
cid = *pcid;
printf("CID = %x\n", cid);
munmap(mapped_base, ldev);
close(memfd);
return (EXIT_SUCCESS);
}
, मैं इतना यकीन है कि क्यों नहीं कर रहा हूँ 1 संस्करण काम नहीं किया। मेरी समझ यह थी कि एक बार जब आप MAP_ANONYMOUS
का उपयोग करते हैं तो आपको मैपिंग के लिए फ़ाइल हैंडल की आवश्यकता नहीं होती है। इसके अलावा, मैंने भौतिक पता होने के लिए स्पष्ट रूप से एडीआर तर्क (pepi
) को गलत तरीके से गलत किया है। अगर मैं अभी हूं, तो यह वास्तव में आभासी पता है।