2025의 게시물 표시

리눅스 커널 - NVMe PCI Driver BAR 설정

NVMe PCI Driver Basic -  https://ildelusion.blogspot.com/2025/12/nvme-pci-driver.html https://elixir.bootlin.com/linux/v4.18.20/source/drivers/nvme/host/pci.c 참고하여 NVMe 디바이스에 대한 BAR 설정을 따라가보자. Calling Path nvme_probe() --> nvme_dev_map() --> nvme_remap_bar() nvme_remap_bar ()에서 아래 라인이 실행됨 dev->bar = ioremap(pci_resource_start(pdev, 0), size); pdev->resource[0].start --> 이 NVMe PCI 디바이스의 0번 BAR가 맵핑된 시스템 메모리 공간 상 물리 주소 ioremap()으로 해당 물리주소를 커널 가상 주소에 매핑한다. nvme_dev_map() 은 사실 nvme_remap_bar() 를 부르기전에  pci_request_mem_regions() 함수를 먼저 부른다. pci_request_mem_regions(pdev, "nvme") 는 해당 PCI 디바이스가 가진 모든 MMIO(BAR) 메모리 영역을 “nvme” 드라이버 명의로 한꺼번에 예약하는 함수다. 이 예약이 성공하면 /proc/iomem에 해당 구간이 "nvme" 이름으로 표시되고, 다른 드라이버가 동일 범위를 다시 request_mem_region / pci_request_mem_regions로 잡는 것을 막는다. MMIO 레지스터를 ioremap() 해서 쓰기 전에, “이 주소 범위는 이 드라이버가 사용 중이다”라고 커널 리소스 관리 계층에 선언하는 단계다. 아래 함수가 결국 불리는 함수이다. ​ static int __pci_request_selected_regions ( struct pci_dev * pdev , int bar...

리눅스 커널 - NVMe PCI Driver Basic

  Linux NVMe PCI 드라이버 상세 분석 Linux 커널의 NVMe PCI 드라이버는 PCIe를 통해 NVMe 스토리지 디바이스와 통신하는 핵심 모듈입니다.  용어설명 -  iod = I/O Descriptor: 각 I/O 명령마다 필요한 메타데이터 구조체 - cdev: 캐릭터 디바이스 -> /dev/nvme0이 캐릭터 디바이스 (컨트롤러 단위의 admin/passthru 명령을 ioctl (입출력제어를 위한 시스템콜, 장치 설정 변경/조회에 사용됨) 형태로 보내는데 사용됨), /dev/nvme0n1은 블록 디바이스로, read/write I/O가 이 블록 디바이스 경로를 통해 처리된다. NVMe PCI 드라이버의 주요 구조와 함수들을 다음과 같이 분류할 수 있습니다. 1. 드라이버 초기화 및 프로브(Probe) pci_driver 구조체 ​ 드라이버의 진입점은 다음과 같이 정의됩니다: c static struct pci_driver nvme_driver = { . name = "nvme" , . id_table = nvme_id_table , . probe = nvme_probe , . remove = nvme_remove , . shutdown = nvme_shutdown , . driver = { . pm = & nvme_dev_pm_ops , } , . err_handler = & nvme_err_handler , } ; 주요 함수들: nvme_probe() : 새로운 NVMe 디바이스가 시스템에 연결될 때 호출됩니다. 이 함수는 디바이스를 인식하고 드라이버를 해당 디바이스에 바인딩합니다. ​ BAR(Base Address Register) 매핑 컨트롤러 리소스 할당 Admin 큐(Queue) 초기화 I/O 큐 설정 PRP Pool 설정 -  nvme_setup_prp_pools(...