커널 모듈에서 ISA 버스를 읽고 쓰는 방법은 무엇입니까?

커널 모듈에서 ISA 버스를 읽고 쓰는 방법은 무엇입니까?

나는 Redhat 6.2를 실행하는 x86 단일 보드 컴퓨터에서 사용자 정의(내가 설계하지 않은) ISA 보드와 통신하려고 합니다. 이 맞춤형 보드와 통신하는 방법에 대해 제가 가지고 있는 유일한 정보는 맞춤형 보드가 응답하는 ISA 버스 주소와 데이터입니다(ISA 버스를 로직 분석기에 연결하여 이를 알게 되었습니다).

예를 들어, 내가 보는 공통 버스 주소는 0xE30000맞춤형 보드의 FPGA에 액세스한다는 것입니다. 원래는 싱글보드 컴퓨터의 버스 주소와 물리적 주소가 같기를 바랐습니다. 이를 통해 mmap/ioremap가정된 물리적 주소를 0xE30000내가 쓸 수 있는 가상 주소로 설정할 수 있습니다 . 불행하게도 Redhat의 커널은 사용자 공간이 그렇게 높은 주소에 액세스하는 것을 허용하지 않습니다 mmap. 내가 작성한 커널 모듈에서 이에 액세스하려고 시도했을 때 물리적 주소가 이미 시스템 RAM용으로 예약되어 있음을 발견했습니다.

[root@rheldev ~]# cat /proc/iomem
00000000-00000fff : reserved
00001000-0009dfff : System RAM
0009e000-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000cbfff : Video ROM
000e0000-000fffff : reserved
  000f0000-000fffff : System ROM
00100000-07ffffff : System RAM  // <--- 0xE30000 sits in there
  00400000-008364e2 : Kernel code
  008364e3-00a917c7 : Kernel data
  00b15000-00c3af6f : Kernel bss
c0000000-c3ffffff : 0000:00:00.0
e0000000-e0000fff : 0000:00:0f.0
  e0000000-e0000fff : e100
e0020000-e003ffff : 0000:00:0f.0
  e0020000-e003ffff : e100
ff000000-ff00ffff : 0000:00:0f.0
fff00000-ffffffff : reserved

이제 저는 다시 원점으로 돌아가서 ISA 버스에 쓸 수 있는 방법을 찾고 있습니다. 오픈 소스 PC/104 드라이버는 찾았지만 ISA 드라이버에 대한 정보는 많이 찾지 못했습니다.여기. 그러나 좀 더 자세히 살펴보면 포트 매핑을 사용하여 버스에 기록하고 포트 X에 기록하면 0xE30000ISA(및/또는 PC/104) 버스에 필요한 버스 주소가 입력되는지 확인하는 방법을 알 수 없습니다.

나는 이것이 내 이해를 완전히 넘어서는 영역이라는 것을 인정합니다. 이것은 매우 기본적이고 단순해 보이며 큰 문제가 되지는 않지만, 이에 대한 정보를 찾는 것이 내가 바라던 것만큼 간단하지 않을 정도로 오래된 프로토콜입니다. 저에게 알려줄 수 있는 리소스/튜토리얼/예제에 대해 미리 감사드립니다!

고쳐 쓰다:

올바른 방향을 알려준 @dirkt의 답변에 감사드립니다! ISA 버스에 직접 액세스하려고 하는데 실제로는 PCI 버스에 연결된 브리지입니다.

[root@rheldev ~]# lspci
00:00.0 Host bridge: VIA Technologies, Inc. VT8605 [ProSavage PM133]
00:01.0 PCI bridge: VIA Technologies, Inc. VT8605 [PM133 AGP]
00:07.0 ISA bridge: VIA Technologies, Inc. VT82C686 [Apollo Super South] (rev 40)
00:07.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
00:07.4 Non-VGA unclassified device: VIA Technologies, Inc. VT82C686 [Apollo Super ACPI] (rev 40)
00:0f.0 Ethernet controller: Intel Corporation 8255xER/82551IT Fast Ethernet Controller (rev 10)

자세히 살펴보면 거기에는 많은 것이 없지만 /sys/bus/isa/아래에는 00:07:0 ISA 브리지가 나타납니다 /sys/bus/pci/devices/. 폴더의 내용은 다음과 같습니다.

[root@rheldev 0000:00:07.0]# ls
broken_parity_status  enable         msi_bus  reset             uevent
class                 irq            power    resource          vendor
config                local_cpulist  ppdev    subsystem
device                local_cpus     remove   subsystem_device
driver                modalias       rescan   subsystem_vendor

이제 내 질문을 업데이트하세요. PCI 버스에 연결된 ISA 브리지를 통해 ISA 버스를 읽고 쓰는 방법은 무엇입니까?

몇몇 사이트에서 ISA 버스에 액세스하기 위해 더 낮은 메모리/포트를 사용하는 방법에 대해 설명하는 것을 보았지만 더 높은 ISA 주소(0xE00000에서 시작)를 사용해야 하기 때문에 그것이 나에게는 적합하지 않을 것 같습니다. (@dirkt의 답변에 대한 내 의견도 참조하십시오)

다시 한 번 말씀드리지만, ISA 버스에 더 높은 ISA 버스 주소를 넣을 수 있도록 ISA 브리지와 통신하고 싶다고 PCI 버스에 알리는 방법에 대한 리소스를 알려주시면 감사하겠습니다. 감사해요!

업데이트 2:

@dirkt가 제안한 대로 lilo를 조사하는 동안 Redhat 6 설치가 grub 2 대신 이전 버전의 grub을 사용하고 있다는 것을 알았으므로 먼저 grub 2가 메모리 구멍을 활성화하여 무엇을 할 것인지 알아보기로 결정했습니다. 로컬에서 컴파일하고 내 컴퓨터에 수동으로 설치한 후(redhat 6 패키지가 없기 때문에) 상황이 기대했던 것보다 나아진 것 같습니다!

14MB-16MB의 메모리를 예약된 것으로 표시하기 위해 grub에 커널 라인 매개변수를 추가했는데, 커널은 요청을 존중하고 해당 주소를 표시하는 것처럼 보였습니다 . @dirkt에 대한 내 의견에서 지적했듯이 커널이 이렇게 될 것이라고 reserved/proc/iomem/

간단한 C 프로그램과 로직 분석기를 사용하면 이 주소에 데이터를 읽고 쓰는 것을 볼 수 있습니다! 다음 단계는 ISA 버스에 대한 읽기 및 쓰기를 적절하게 처리하기 위해 적절한 커널 모듈을 작성하는 것입니다. 그러나 이제 작동하므로 비교적 쉬운 작업이 될 것입니다!

답변1

나는 다소 일반적인 대답만 드릴 수 있지만, 이것이 여러분에게 올바른 방향을 제시해 주기를 바랍니다.

어떤 x86 보드를 사용하고 있는지 지정하지 않았지만 비구식 시스템에서는 ISA 버스가 PCI-ISA 브리지 뒤에 있습니다. 이것을 사용하여 lspci다리를 찾을 수 있습니다 . 브리지는 메인 메모리와 I/O 공간을 ISA 버스 메모리와 I/O 공간에 매핑하는 기능을 제공합니다. 이는 BIOS(예: 레거시 PNP를 포함한 ACPI)에 제공된 정보를 기반으로 부팅 시 커널에 의해 설정됩니다. dmesg이 프로세스를 시작한 후 이 프로세스에 대한 정보를 볼 수 있습니다 .

최신 시스템에서도 레거시 ISA 장치가 여전히 존재합니다. 하지만 이제 실제 ISA 버스가 아닌 LPC 버스에 있습니다. 이러한 장치용 Linux 커널 드라이버( 예: 8042 /2 키보드/마우스 드라이버)(drivers/input/serioPSrequest_regioni8042_platform_initi8042-io.hinboutb/proc/ioports

브릿지는 에 표시되어야 합니다 /sys/bus/pci/devices. 아마도 거기에서 더 많은 정보를 찾을 수 있을 것입니다. 또한 /sys/bus/isa, 어떤 상황에서 커널이 정보로 채울지는 잘 모르겠습니다.

그래서 먼저 마더보드가 특정 I/O 포트에 반응하는지 확인하려고 합니다. 또한 PNP 열거 프로세스를 시도해 보십시오(또는 dmesg시작 시 아직 완료되지 않았는지 확인하십시오). 이에 응답하면 나머지는 훨씬 쉬울 것입니다.

마지막으로 PCI-ISA 브리지가 메모리 공간을 어떻게 매핑하는지, 이 메모리 공간을 예약하려면 어떤 커널 작업이 필요한지 파악한 다음 다시 조사하여 어떤 일이 발생하는지 확인할 수 있습니다.

편집하다:

이 책Linux 장치 드라이버, 제3판ISA 메모리 접근에 대한 정보가 있습니다.9.4.5.

편집하다:

시도해 볼 가치가 있는 것들:

1) lilo부팅하는 대신 를 사용하여 grubBIOS에서 "홀"(ISA 매핑)을 활성화하고 부팅되는지 확인합니다. 예, lilo여전히 작동합니다.

2) VIA VT82C686A South Bridge데이터시트는 Google에서 확인하세요. PCI-ISA 브리지의 PCI 구성 공간에는 다음 레지스터가 있습니다.

Offset 43 - ROM Decode Control  

Setting these bits enables the indicated address range to be
included in the ROMCS# decode:  

7    FFFE0000h-FFFEFFFFh  
6    FFF80000h-FFFDFFFFh 
5    000E8000h-000EFFFFh  
4    000E0000h-000E7FFFh 
3    000D8000h-000DFFFFh  
2    000D0000h-000D7FFFh  
1    000C8000h-000CFFFFh 
0    000C0000h-000C7FFFh  

따라서 부팅 후 "홀"(ISA 매핑)을 활성화하고 로직 분석기로 작동하는지 확인할 수 있을 것 같습니다. 카드가 높은 비트를 디코딩할 수 없는 경우 FFFE0000h대신 사용해 볼 가치가 있습니다.000E0000h

이 작업을 올바르게 수행하고 변경된 매핑을 Linux 커널에 알리는 방법을 모르겠습니다. 어쩌면 이에 대한 시작 옵션도 있을 수 있습니다.

더미 파일을 통해 PCI 구성 공간에 액세스할 수 있다는 것을 알고 있으므로 /sys/bus/pci/devices/0000:00:07.0/config커널 드라이버 외부에서 이를 시도할 수도 있습니다.

3) 본인의 카드가 열거되어 있는지 반드시 확인 dmesg하고 확인 하시기 바랍니다 . /sys/bus/pnp출력 내용을 이해할 수 없으면 dmesg붙여넣기 상자에 넣고 링크를 게시해 보세요.

관련 정보