busybox devmem 명령을 사용하여 레지스터를 읽고 쓰려고 합니다. 소스 코드에서 드라이버의 기본 주소를 인쇄했고 다음 주소를 받았습니다: 0xffffff800bdd0000
이 주소는 가상 커널 주소라고 가정합니다. busybox devmem을 사용할 수 있도록 이것을 물리적 주소로 어떻게 변환합니까? 프로그래밍 없이 터미널에서 실행하려고 합니다.
답변1
이것제목/dev/kmem
귀하의 질문에 대한 답변은 다음과 같습니다: 장치 노드를 읽거나 쓰십시오 . (*1)
하지만... 귀하의 질문을 읽어보니... 이것이 귀하가 찾고 있는 것이 아닌 것 같습니다.
나는 당신이 장치의 특정 레지스터를 읽고 쓰고 싶어한다는 것을 알고 있습니다.
어떤 하드웨어 장치(RAM 포함)가 특정 버스를 통해 CPU와 통신하든 관계없이 장치 I/O 레지스터의 실제 주소는 장치가 사용하는 버스에만 관련됩니다.
즉, 이러한 주소에 액세스하려면 엄격하고 구체적인 프로토콜을 따라야 하며 다른 읽기/쓰기 명령도 필요할 수 있습니다.
다행스럽게도 Linux는 모든 버스와 장치에서 IO를 추상화하는 방법을 제공합니다.메모리 매핑된 IO.통합(ram 및 io) 주소 공간에 액세스하기 위한 장치 노드:/dev/메모리(*2)
어떤 일을 하기 전에 먼저 해야 할 일노드가 존재하는지 확인하세요.귀하의 시스템에서. 명백한 보안상의 이유로 많은 배포판에서는 이를 활성화하지 않거나 이에 대한 액세스를 제한합니다. 따라서 kernel.config 파일을 확인하여 CONFIG_DEVMEM이 설정되어 있고 CONFIG_STRICT_DEVMEM이 설정되어 있지 않은지 확인하세요.
그렇지 않은 경우 선호하는 도구를 사용하여 그에 따라 커널 구성을 조정하고 커널을 다시 빌드하십시오.
그렇다면 지금 알아야 할 것은레지스터가 다시 매핑되는 주소:
OP에서 주장하는 것과는 달리 드라이버 소스 코드를 읽는다는 사실을 알면 안됩니다. 해당 코드는 장치 독립적인 방식으로 기본 주소에 논리적으로 작성되기 때문입니다.
이 코드에서 실제로 이해할 수 있는 것은 관심 있는 레지스터의 상대 주소입니다. 기본 주소를 기준으로 해당 주소의 오프셋입니다. 기록해 두세요(또는 장치 사양에서 확인하세요).
Linux(성공한 경우)가 장치와 관련된 IO 공간을 다시 매핑하는 기본 주소가 /proc/iomem
파일에 보고되어야 합니다. (*삼)
레지스터 재매핑 주소를 얻으려면 두 개(기본 주소와 오프셋)를 추가합니다.
이제 /dev/mem 장치 노드를 사용해야 합니다. 이 모든 것이 매우 간단하기 때문입니다. 사용하는 것이 정말 현명합니다.비지박스 장치 메모리. (*4)
읽으면서 사용하세요: devmem ADDRESS [WIDTH [VALUE]]
WIDTH 매개변수 처리(비트 단위의 레지스터 크기)
1: 아니면 어쩌면항상답변을 받은 이후로리누스 토발즈(Linus Torvalds)는 그것에서 벗어나고 싶어합니다.
2: x86_64 아키텍처에서 Linux는 장치를 처리하는 또 다른 방법(/proc/ioports에서 포트 주소를 보고하고 /dev/port를 통해 액세스)을 제공하지만 이는 arm을 사용하는 ARM 아키텍처 및 OP에는 적용되지 않으므로 장치 여기에 설명된 유일한 방법인 IO 재매핑으로 인해 레지스터에 액세스할 수 없습니다.
3: 일부 장치의 경우 메모리 재매핑 범위가 여러 위치로 분할될 수 있습니다. 레지스터 참조의 기본 주소를 이해하려면 사양(또는 드라이버 코드)을 읽으십시오.
4:살이 많이 찐다는 경고:devmem과 같은 중간 도구를 통해서도 부적절한 사용으로 인해 /dev/mem
시스템이 손상될 수 있습니다.