I/O 메모리는 Linux 시스템에서 특별한 종류의 메모리로, 드라이버가 메모리를 읽고 쓰면서 주변 장치를 제어할 수 있도록 주변 장치의 레지스터를 매핑하는 데 사용됩니다. I/O 메모리 액세스는 Linux 드라이버 개발에서 가장 일반적인 작업 중 하나이며 물리적 주소 및 가상 주소, 포트 매핑 및 메모리 매핑, 바이트 액세스 및 단어 액세스 등과 같은 개념을 포함합니다. 이 기사에서는 Linux 드라이버의 I/O 메모리 액세스 기술을 소개하고 예제를 통해 사용법과 주의 사항을 설명합니다.
ARM은 메모리 공간과 IO 공간을 균일하게 주소 지정하므로 SFR을 읽고 쓰는 방식으로 하드웨어를 제어하는 것은 해당 SFR 주소를 읽고 쓰는 방식으로 하드웨어를 제어하는 것이 됩니다. 주소의 이 부분을 I/O 메모리라고도 합니다. x86에서는 I/O 주소와 메모리 주소가 별도로 지정됩니다. 이러한 IO 주소를 I/O 포트라고 합니다. 이 문서에서는 IO 메모리 액세스에 대해서만 설명합니다
우리는 가장 중요한 시스템 리소스를 관리하고 물리적 주소를 프로세스에 투명하게 만들기 위해 Linux가 메모리 매핑 메커니즘을 사용한다는 것을 알고 있습니다. 즉, 프로세스가 물리적 메모리 주소(예: SFR 주소)에 액세스하려는 경우 그런 다음 먼저 이를 가상 주소에 매핑해야 합니다.
“
”
Linux는 IO 메모리 범위를 적용하고 해제하기 위한 함수 세트를 제공합니다. 이 두 API는 IO 메모리에 액세스할 때 필요하지 않지만, 적용된 리소스의 사용 가능 여부를 확인하고 IO 액세스 보안을 강화할 수 있습니다. 사용 가능한 경우 응용 프로그램은 성공한 것으로 표시되며 이 프로세스가 리소스를 반환하기 전에 다른 드라이버가 해당 리소스를 신청하려는 경우 응용 프로그램은 실패합니다.
**request_mem_region()** 매크로 함수는 메모리의 n개 메모리 주소에 적용됩니다. 이 주소는 처음부터 시작하고 길며, 이름은 장치 이름을 나타내며, 성공하면 NULL이 아닌 값을 반환합니다.
으아아아**release_mem_region() 이름에서 알 수 있듯이 매크로 함수는 request_mem_region()**에서 요청한 IO 메모리 리소스를 커널에 반환하여 다른 프로세스도 IO 메모리에 액세스할 수 있도록 합니다.
으아아아IO 자원 신청 후 다음 단계는 물리적 주소를 가상 주소에 매핑하는 것입니다. 커널에서 제공하는 API는 다음과 같습니다
으아아아ARM의 SFR은 32비트입니다. 실제로는 강제 유형 변환을 통해 얻은 가상 주소를 직접 읽을 수 있습니다. 그러나 이 방법은 주의하지 않으면 잘못된 주소를 읽게 됩니다. , 커널 또한 IO 메모리를 읽고 쓰기 위해 제공되는 표준 API는 코드를 더 안전하게 만들 뿐만 아니라 가독성도 향상시킵니다.
unsigned int ioread8(void *addr) unsigned int ioread16(void *addr) unsigned int ioread32(void *addr)
void iowrite8(u8 val,void *addr) void iowrite16(u8 val,void *addr) void iowrite32(u8 val,void *addr)
void ioread8_rep(void *addr,void *buf,unsigned long len) void ioread16_rep(void *addr,void *buf,unsigned long len) void ioread32_rep(void *addr,void *buf,unsigned long len)
void iowrite8_rep(void *addr,const void *buf,unsigned long len) void iowrite16_rep(void *addr,const void *buf,unsigned long len) void iowrite32_rep(void *addr,const void *buf,unsigned long len)
void memcpy_fromio(void *dest,void *source,unsigned long len) void memcpy_toio(void *dest,void *source,unsigned long len)
void memset_io(void *addr,u8 value,unsigned int len)
通过本文,我们了解了Linux驱动中的I/O内存访问技术,它们可以用来实现对外设寄存器的读写操作。我们应该根据实际需求选择合适的函数,并遵循一些基本原则,如先申请再映射,先释放再取消映射,使用正确的数据类型和大小等。I/O内存访问技术是Linux驱动开发中不可或缺的一部分,它可以实现对外设的控制和配置,也可以提升驱动程序的效率和兼容性。希望本文能够对你有所帮助和启发。
위 내용은 Linux 드라이버의 I/O 메모리 액세스 기술: 원리 및 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!