현재 장치 드라이버를 작성 중입니다.교육 장비qemu(RISC-V)에서. 따라서질문, 이미 하나가 있는 것을 확인했습니다.장치 드라이버그러한 장비의 경우.
~에 따르면Edu 장치 문서의 이 줄이는 주소 >= 0x80이 크기 == 4 또는 크기 == 8 액세스를 허용함을 의미합니다. 이러한 제약 조건은 그림에 나와 있습니다.여기는edu_mmio_read()
그리고여기는edu_mmio_write()
Edu 장치 소스 코드에서.
내부에드라이버 코드, 및 의 경우 read()
8 write()
바이트가 아닌 4바이트 크기의 읽기/쓰기 값만 처리하는 것으로 보입니다. 따라서 8바이트 값 읽기/쓰기를 지원하기 위해 이 두 함수에 새로운 것을 추가했습니다.
static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
ssize_t ret;
u32 kbuf32;
u64 kbuf64;
if (*off % 4 || len == 0) {
ret = 0;
} else {
switch (len)
{
case 4:
kbuf32 = ioread32(mmio + *off);
if (copy_to_user(buf, (void *)&kbuf32, len)) {
ret = -EFAULT;
} else {
ret = 4;
(*off)++;
}
break;
case 8:
kbuf64 = ioread64(mmio + *off);
if (copy_to_user(buf, (void *)&kbuf64, len)) {
ret = -EFAULT;
} else {
ret = 8;
(*off)++;
}
break;
default:
ret = -EFAULT;
break;
}
}
return ret;
}
static ssize_t write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
ssize_t ret;
u32 kbuf32; /* for size == 4 */
u64 kbuf64; /* for size == 8 */
ret = len;
if (!(*off % 4)) {
switch (len) {
case 4:
/* copy buf to kbuf32 */
if (copy_from_user((void *)&kbuf32, buf, len)) {
ret = -EFAULT;
} else {
iowrite32(kbuf32, mmio + *off);
}
break;
case 8:
if (copy_from_user((void *)&kbuf64, buf, len)) {
ret = -EFAULT;
} else {
iowrite64(kbuf64, mmio + *off);
}
break;
default:
ret = -EFAULT;
break;
}
}
return ret;
}
내 사용자 모드 테스트 코드에서는 다음을 수행합니다.
// open the device - succeed
// fd2 - the file descriptor representing the opened edu device
uint64_t val64 = 0x8b320000; // a random 64-bit value
unsigned long ret = -1; // retval
// write val64 to 0x80
lseek(fd2, 0x80, SEEK_SET); // seek to address 0x80 - dma.src in edu device source code (line 281)
ret = write(fd2, &val64, sizeof(uint64_t));
if(ret == -1) printf("write to dma src failed\n");
else printf("written %llx to dma src\n", val64);
// reset val64
val64 = 0;
// read what we have just written (sanity check)
lseek(fd2, 0x80, SEEK_SET);
ret = read(fd2, &ret64, sizeof(uint64_t));
if(ret == -1) printf("read from dma src failed\n");
else printf("sanity check: read dma src and we get - %llx\n", ret64);
그런데 사용자 모드 코드를 테스트하면 주소에 값을 쓰지만 0x80
읽을 수는 없습니다. 몇 가지 printf 문을 추가하고 read()
다음 코드 줄에 해당하는 오류가 발생했음을 확인했습니다.
kbuf64 = ioread64(mmio + *off);
나는 이것을 찾았다페이지IO 접근 기능의 차이점에 대해 이야기하고 ioread64()
로 대체했지만 readq()
여전히 문제가 해결되지 않았습니다. kbuf64 = ioread64(mmio + *off);
실행 중에 코드 실행이 중지됩니다. 추가도 시도했지만 #define CONFIG_64BIT
여전히 오류가 해결되지 않았습니다.
그런 다음 Ctrl+C를 눌러도 사용자 모드 코드를 중지할 수 없습니다. 내가 할 수 있는 일은 QEMU를 중지하고 Ctrl+A를 누른 다음 X를 눌러 다시 시작하는 것뿐이었습니다.
4바이트 값의 경우 ioread32()
및 와 함께 읽기 또는 쓰기를 사용할 수 있습니다 iowrite32()
.
내가 뭘 잘못해서 오류가 발생했는지 알 수 있나요 ioread64()
?