1.가상 데이터 센터, 클라우드 컴퓨팅...발전의 순서는 어떻게되며 각각은 어떻게 다른 것인가 - 가상화와 클라우드 컴퓨팅은 어떻게 다른 것일까? 같은 것일까? 책에서는 다른 용어로 설명이 된다. 2.스토리지 아케틱처의 진화 과정에 대한 이해 필요 - 서버 중심 스토리지 아키텍처는 무엇인
해당 장에서 얘기되는 SQ와 CQ는 NVMe over PCIe에서만 적용이 된다. NVMe over Fabrics에 관한 SQ와 CQ의 정보는 NVMe over Fabrics spec을 참조해야 한다.
SQ와 CQ는 circular queue 구조를 가지며, head와 tail을 가지고 있어 entry point를 나타낸다.
submiiter는 현재 tail entry pointer가 가리키는 queue slot에 command를 저장한 후 tail pointer를 증가시킨다.
consumer는 현재 head entry pointer가 가리키는 slot를 가지고 간 후 head pointer를 증가시킨다.
Queue Empty 상태 • Head == Tail Queue Full 상태 • Head == Tail + 1 mod # Of Queue Entries.
SQ와 CQ의 생성과 삭제는 host software에 의해 요청되어져야 한다.
생성시 CQ가 생성된 이후에 관련된 SQ가 생성된다. 삭제시 SQ가 먼저 메모리 해제된 이후 CQ가 삭제된다.
Host software는 새로운 command가 entry로 들어왔다는 것을 통신하기 위해 SQ tail doorbell과 CQ head doorbell에 쓰기를 수행한다. 만약 SQ tail doorbell 또는 CQ head head doorbell에 invalid value 쓰기와 asyn 이벤트 요청 command가 처리되지 않았다면, admin CQ에 invalid doorbell write value status가 놓여지게된다. 문제를 해결 하기 위해 host software에 의해 queue가 삭제 및 재생성되며, controller는 이전에 처리 중이던 command까지만 끝내고 추가적인 command에 대해서 처리하지 않는다. 해당 상황은 host software가 full 상태인 SQ에 entry를 추가하거나 빈 CQ에서 entry를 가지고 갈려는 동작에서 비롯된다.
Host software는 새로운 CQ entry가 놓여졌는지 확인하기 위해 CQ entry의 Phage Tag (P) bit를 확인한다. CQ tail pointer는 host에서는 알지 못하고 controller 내부에서만 사용된다. controller는 CQ 항목의 SQHD (SQ Head Pointer) 필드를 사용하여 SQHD의 새 값을 호스트에 전달한다.
Queue identifier: 16 bit ID 값으로 queue가 생성되었을때 할당된다. 이것으로 queue를 식별하게된다.
4.2 Submission Queue Entry - Command Format
SQ는 64byte 크기로 구성되어 있다. 하지만, 추후에 spec에 의해서 command format이 변경될수 있다.
(NVMe spec 1.2와 비교해 Dword 0의 15번 bit만 사용되던 것이 spec 1.4에선 [15:14] bit로 확장되었다.
Dword 0
- [07:00] opcode: 실행하기 위한 command의 opcode를 명시한다.
- [09:08] Fused Operation (FUSE): 간단한 command 두개를 같이 수행하는 command로 만든다. 두개의 command사이에는 어떤 command도 존재하지 않으며, atomic 하게 수행된다.
- [15:14] PRP or SGL for Data Transfer (PSDT): command와 관련된 data를 전송함에 있어 PRPs 또는 SGLs 중 어느 것을 선택할 것인지에 대한 field이다. PRPs는 NVMe over PCIe에서 admin commands를 위해 사용된다. SGLs는 NVMe over Fabrics에서 Admin command 그리고 I/O command를 위해 사용된다.
- [31:16] Command Identifier (CID): SQ identifier와 함께 조합되어 고유의 identifier를 나타낸다.
Dword 1
- [31:00] Namespace Identifier (NSID): command가 적용되는 namespace를 나타낸다. 만약 command에 NSID 값이 사용되지 않는다면 0x0의 값을 가진다. 만약 0xFFFFFFFF의 값을 가진다면 broadcast value(모든 네임 스페이스를 지정하는 데 사용되는 값)이다. 만약 비활성화된(생성은 되었지만 controller에 deattached된 상태) NSID 값을 사용한다면 contoller는 abort 를 status Invalid Field를 남기고 수행한다. invalid NSID 값을 사용한다면 controller는 status Invalid Namespace or Format를 남기고 abort를 수행한다. broadcast value가 지원되지 않는 command 종류에 broadcast value를사용했다면 controller는 status Invalid Field를 남기고 abort를 수행한다.
Dword 4, 5
- [63:00] Metadata Pointer (MPTR): MPTR은 logical block data과 interleaved되지 않은 metadata가 command에 있을시에 유효하게 사용된다.
Dword 0의 PSDT field가 0b00인 경우, MPTR field는 metadata의 연속된 physical buffer 주소를 나타낸다. MPTR의 [01:00] 비트가 0b00의 값을 가지지 않는다면, controller는 invalid field 에러를 리포트한다.
Dword 0의 PSDT field가 0b01인 경우, metadata의 phyiscal buffer 주소를 포함한다.
Dword 0의 PSDT field가 0b10인 경우, 한개의 SGL descriptor를 포함하는 SGL segment 주소를 포함한다. SGL segment내에 포함된 SGL descriptor는 command를 위한 metadata의 첫번째 SGL descriptor를 나타낸다.
Dword 6~9
- [127:000] Data Pointer (DPTR): command에 포함된 data를 나타낸다.
Dword 0의 PSDT field가 0b00인 경우, PRP entry 1과 PRP entry2를 나타낸다.
PRP1: command를 위한 PRP entry 혹은 command와 연관된 PRP list pointer를 나타낸다.
PRP2: 1) memory page boundary를 초과하는 않는 data 전송의 경우 사용되지 않는다.
2) 전송할 데이터가 하나의 memory page boundary를 초과하는 경우 두번째 memory page의 page base address를 나타낸다.
3) 전송할 데이터가 하나의 memory page boundary를 초과하고 두개 이상의 memory pages를 가져야 하는 경우 PRP list pointer를 나타낸다.
Dword 0의 PSDT field가 0b01 또는 0b10인 경우, SGL entry 1(SGL1)으로 사용된다.
Command를 위한 첫번째 SGL segment를 나타낸다.
4.3 Physical Region Page Entry and List
PRP (Physical region page) entry는 pysical memory page를 가리키는 pointer이다. PRPs는 controller와 memory 사이에 데이터 전송을 위한 scatter/gather mechanism을 사용한다. 효율적인 out of order의 순서로 data를 전송하기 위해 entry는 고정된 사이즈로 사용된다. Pysical memory page는 host software에 의해 CC.MPS에 설정된다.
위 그림은 PRP entry의 64bit field를 나타낸다. offset은 CC.MPS에 의해 결정된다.
[64:00] Page Base Address and Offset (PBAO): 4KB의 memory page size라면 [11:00] 12bit(2^12=4KB)가 offset으로 사용된다. 만약 첫번재 PRP entry나 PRP list pointer가 아니라면, offset은 0의 값을 가진다. dword로 align되므로 [01:00] 하위 2bit (2^2=4B)는 0b00의 값으로 된다. 만약 0b00으로 초기화 되지 않으면 PRP Offset Invalid 에러를 controller가 리포트 후 0b00으로 클리어 시킨다.
PRP List (pysical region page list)는 연속적인 메모리의 single page를 가지는 PRP entry들의 집합이다. 만약 전송해야 할 data가 PRP list pages가 필요하다면 마지막 PRP entry는 다음 PRP list의 pointer를 가리킨다. 만약 non-zero offset을 PRP entry들이 가진다면 PRP offset invalid 에러를 반환한다.
PRP_SIZE는 64bit(8B)이고, PAGE_SIZE는 host page size를 default로 보통 4KB로 고려했을때 하나의 memory page안에 총 512개의 entry가 포함될수 있다. (4096B / 8B = 512개) 또한, 하나의 entry가 physical memory page (4KB)를 가리키므로 2048KB (2MB)의 데이터를 전송할 수 있게된다.
4.4 Scatter Gather List (SGL)
우선 Scatter Gatehr의 의미를 파악하자.
커널 영역에서 메모리 관리를 할 때는 어렵긴 하지만(오버헤드가 크지만) 물리 메모리에 일렬로 정렬해서 사용하는 것이 가능하지만 사용자 영역에서는 이렇게 할 수가 없다. 커널 영역에서 메모리를 물리 영역에 일렬로 정리해서 쓰는것이 가능하다고 했지만 여기 저기 흩어져 있는(Scatter) 메모리를 일렬로 정렬되어 있는 것처럼 사용할 수 있다면 좀더 편한 관리가 가능할 것이다. 다시 정리하면 Scatter/Gather 의 개념은 여기 저기 흩어져 있는 메모리(Scatter) 를 논리적으로 모아서(Gather) 연속된 물리적 메모리처럼 사용하는 것을 의미하며 Scatterlist 는 여기 저기 흩어져 있는 메모리(Scatter) 의 모음(array) 라고 보면 된다. 출처:https://poplinux.tistory.com/75
struct scatterlist{
struct page *page;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
}
왜 NVMe over PCIe에서는 SGL을 안쓰고 PRP를 쓰는지에 대한 이유이다. 결론은 결국 PRP가 SGL보다 간단하다이다. 하지만, 많은 양의 데이터를 전송할땐 SGL을 사용하는 것이 더 빠르다고 한다.
SGL은 데이터 버퍼를 표현하기 위한 memory 주소 공간의 자료구조이다. controller는 'Identify Controller data stucture'에 지원하는 SGL types를 가리킨다. data buffer는 source buffer이거나 destination buffer이다. SGL은 하나 이상의 SGL segment를 포함하고 있다. SGL 내에 Data Block과 Bit Bucket descriptor의 총 길이가 전송할 logical block의 수와 같거나 초과할것이다. 마지막 SGL segment는 SGL segment descriptor 또는 SGL last segment descriptor를 포함하지 않는다.
SGL segment는 하나 이상의 SGL descriptor를 가진다.
SGL descriptor의 format이다.
15B: SGL identifier
[03:00] SGL descriptor sub type: 만약 reserved value이거나 unsupported value인 경우, descriptor는 SGL descriptor type error로 처리된다.
[07:04] SGL descriptor type: 만약 reserved이거나 unsupported value인 경우 SGL descriptor는 SGL descriptor type error로 처리된다.
SGL data block descriptor인 경우
[07:00] Address:
- SGL descriptor sub type field가 0x0인 경우: address field는 data block의 64bit memory 시작 주소를 나타낸다.
- SGL descriptor sub type field가 0x1인 경우: 전송되어야 할 memory 주소의 offset을 나타낸다.
[11:08] Length: data block의 B단위 길이를 나타낸다. 0x0인 경우 전송할 데이터가 존재하지 않는다.
[15:15] SGL identifier:
- [03:00] SGL descriptor sub type
- [07:04] SGL descriptor type: 0x0
SGL bit bucket descriptor인 경우
[11:08] Length: discard되는 source data의 길이를 나타낸다. 만약 destination data buffer인 경우, controller에 의해 discard되는 source data의 길이를 말한다. 만약 source data buffer인 경우 0이다.
[15:15] SGL identifier:
- [03:00] SGL descriptor sub type
- [07:04] SGL descriptor type: 0x0
4.6 Completion Queue Entry
CQ의 entry는 최소 16B 크기를 가진다. 추후에 I/O coomand set의 사용에 따라 크기가 달라질 수 있다.
Dword 2
[31:16] SQ identifier (SQID): issue된 command와 관련되어 SQ를 구분하기 위한 식별자로 사용된다.
[15:00] SQ Head Pointer (SQHD): command를 가지고온 SQ의 현재 SQ head pointer를 가리킨다. 어디까지 entry가 처리되었는지를 나타낸다.
Dword 3
[31:17] Status Field (SF): 처리 완료된 command의 상태를 나타낸다.
- no fatal or non-fatal error conditions 없이 성공적으로 끝났을 경우 0x0의 값을 가진다.
- [31] Do Not Retry (DNR):
--- set to 1: 같은 command가 다시 submmit된 command는 fail된다.
--- set to 0: 같은 command가 다시 submiit된 command는 성공한다.
- [30] More (M):
---set to 1: Get log pag command를 통해 받은 에러 정보보다 더 많은 status 정보를 가지고 있다.
---set to 0: 추가적은 status 정보가 없다.
- [29:28] Command Retry Delay (CRD):
--- set to 0: ?????????????
- [27:25] Status Code Type (SCT): status code type of the completion queue entry
- [24:17] Status Code (SC): status code identifying any error or status information
[16:16] Phase Tag (P): CQ entry가 새로운 entry인지 판단하는데 사용된다. CC.EN이 1의 값이 되기전 host software에 의해 0으로 초기화 된다. controller가 CQ에 처리 끝난 entry를 놓은경우, host software가 새로운 entry를 식별할수 있도록 controller는 P field를 invert시킨다.
[15:00] Command Identifier (CID): 처리 완료된 command의 식별자를 가리킨다. 해당 식별자는 host software에 의해 SQ에 command가 놓여질때 할당된다. SQ identifier와 Command identifier의 조합으로 command가 완료되었다는 것을 판단할 수 있다.
Controller register는 2장 내용중 PCI header 부분에서 나온 MLBAR/MUBAR (PCI BAR0, BAR1) register들을 통해 Host PC의 main memory 영역에 할당되어 있다. Host는 locked access를 할수 없다. 아래의 그림은 SSD controller에서 사용될 register들에 대한 정의이다.
nvme-cli가 설치되어 있다는 전제하에 실행
#nvme show-regs /dev/nvme0
또는
#nvme show-regs /dev/nvme0 -H
2장에서처럼 마찬가지로 이번에는 controller의 register 값들을 보기 위해 nvme-cli 툴을 사용한다. nvme-cli는 nvme 디바이스에 대해 편리하게 사용하기 위한 commnad line 기반의 management tool이다.
nvme show-regs /dev/nvme0만 사용했을 경우엔 hex 값으로 값이 전부 보이며 -H 옵션을 주게 되면 human-readable 옵션으로 보기 좋게 바뀐다.
cap : 200a010fff
Controller Memory Buffer Supported (CMBS): The Controller Memory Buffer is Not Supported
Persistent Memory Region Supported (PMRS): The Persistent Memory Region is Not Supported
Memory Page Size Maximum (MPSMAX): 4096 bytes
Memory Page Size Minimum (MPSMIN): 4096 bytes
Boot Partition Support (BPS): No
Command Sets Supported (CSS): NVM command set is supported
NVM Subsystem Reset Supported (NSSRS): No
Doorbell Stride (DSTRD): 4 bytes
Timeout (TO): 5000 ms
Arbitration Mechanism Supported (AMS): Weighted Round Robin with Urgent Priority Class is not supported
Contiguous Queues Required (CQR): Yes
Maximum Queue Entries Supported (MQES): 4096
version : 10200
NVMe specification 1.2
cc : 460001
I/O Completion Queue Entry Size (IOCQES): 16 bytes
I/O Submission Queue Entry Size (IOSQES): 64 bytes
Shutdown Notification (SHN): No notification; no effect
Arbitration Mechanism Selected (AMS): Round Robin
Memory Page Size (MPS): 4096 bytes
I/O Command Sets Selected (CSS): NVM Command Set
Enable (EN): Yes
csts : 1
Processing Paused (PP): No
NVM Subsystem Reset Occurred (NSSRO): No
Shutdown Status (SHST): Normal operation (no shutdown has been requested)
Controller Fatal Status (CFS): False
Ready (RDY): Yes
nssr : 0
NVM Subsystem Reset Control (NSSRC): 0
intms : 0
Interrupt Vector Mask Set (IVMS): 0
intmc : 0
Interrupt Vector Mask Clear (IVMC): 0
aqa : 1f001f
Admin Completion Queue Size (ACQS): 32
Admin Submission Queue Size (ASQS): 32
asq : 303d9000
Admin Submission Queue Base (ASQB): 303d9000
acq : 34580000
Admin Completion Queue Base (ACQB): 34580000
cmbloc : 3
Offset (OFST): 0x0 (See cmbsz.szu for granularity)
CMB Queue Dword Alignment (CQDA): 0
CMB Data Metadata Mixed Memory Support (CDMMMS): Enforced
CMB Data Pointer and Command Independent Locations Support (CDPCILS): Enforced
CMB Data Pointer Mixed Locations Support (CDPMLS): Enforced
CMB Queue Physically Discontiguous Support (CQPDS): Enforced
CMB Queue Mixed Memory Support (CQMMS): Enforced
Base Indicator Register (BIR): 0x3
cmbsz : 500003
Size (SZ): 1280
Size Units (SZU): 4 KB
Write Data Support (WDS): Write Data and metadata transfer in Controller Memory Buffer is Not supported
Read Data Support (RDS): Read Data and metadata transfer in Controller Memory Buffer is Not supported
PRP SGL List Support (LISTS): PRP/SG Lists in Controller Memory Buffer is Not supported
Completion Queue Support (CQS): Admin and I/O Completion Queues in Controller Memory Buffer is Supported
Submission Queue Support (SQS): Admin and I/O Submission Queues in Controller Memory Buffer is Supported
bpinfo : ffffffff
Active Boot Partition ID (ABPID): 1
Boot Read Status (BRS): Error completing Boot Partition read
Boot Partition Size (BPSZ): 32767
bprsel : ffffffff
Boot Partition Identifier (BPID): 1
Boot Partition Read Offset (BPROF): fffff
Boot Partition Read Size (BPRSZ): 3ff
bpmbl : ffffffffffffffff
Boot Partition Memory Buffer Base Address (BMBBA): ffffffffffffffff
cmbmsc : ffffffffffffffff
Controller Base Address (CBA) : fffffffffffff
Controller Memory Space Enable (CMSE): 1
Capabilities Registers Enabled (CRE) : CMBLOC and CMBSZ registers are enabled
cmbsts : ffffffff
Controller Base Address Invalid (CBAI): 1
pmrcap : ffffffff
Controller Memory Space Supported (CMSS) : Referencing PMR with host supplied addresses is Supported
Persistent Memory Region Timeout (PMRTO): ff
Persistent Memory Region Write Barrier Mechanisms(PMRWBM): f
Persistent Memory Region Time Units (PMRTU): PMR time unit is minutes
Base Indicator Register (BIR): 7
Write Data Support (WDS): Write data to the PMR is supported
Read Data Support (RDS): Read data from the PMR is supported
pmrctl : ffffffff
Enable (EN): PMR is READY
pmrsts : ffffffff
Controller Base Address Invalid (CBAI): 1
Health Status (HSTS): Reserved
Not Ready (NRDY): The Persistent Memory Region is Not Ready to process PCI Express memory read and write requests
Error (ERR) : ff
pmrebs : ffffffff
PMR Elasticity Buffer Size Base (PMRWBZ): ffffff
Read Bypass Behavior : memory reads not conflicting with memory writes in the PMR Elasticity Buffer SHALL bypass those memory writes
PMR Elasticity Buffer Size Units (PMRSZU): Reserved
pmrswtp : ffffffff
PMR Sustained Write Throughput (PMRSWTV): ffffff
PMR Sustained Write Throughput Units (PMRSWTU): Reserved/second
pmrmsc : ffffffffffffffff
Controller Base Address (CBA) : fffffffffffff
Controller Memory Space Enable (CMSE : 0
위 결과는 -H 옵션을 주고 실행했을때의 결과이다.
CAP -controller capabilities
8B의 크기를 가지고 있다.
값: 0x200a010fff
controller의 특성을 host software에게 알려준다.
nvme-cli에서는 admin passthru command를 통해 register 값을 읽어 온다.
Controller Memory Buffer Supported (CMBS): The Controller Memory Buffer is Not Supported
Persistent Memory Region Supported (PMRS): The Persistent Memory Region is Not Supported
Memory Page Size Maximum (MPSMAX): 4096 bytes
Memory Page Size Minimum (MPSMIN): 4096 bytes
Boot Partition Support (BPS): No
Command Sets Supported (CSS): NVM command set is supported
NVM Subsystem Reset Supported (NSSRS): No
Doorbell Stride (DSTRD): 4 bytes
Timeout (TO): 5000 ms
Arbitration Mechanism Supported (AMS): Weighted Round Robin with Urgent Priority Class is not supported
Shutdown Notification (SHN): No notification; no effect
Arbitration Mechanism Selected (AMS): Round Robin
Memory Page Size (MPS): 4096 bytes
I/O Command Sets Selected (CSS): NVM Command Set
controller가 diable되었을대 (CC.EN == 0) 설정을 변경할 수 있다.
Enable (EN): Yes
NSSR - NVM subsystem reset
NVM Subsystem Reset Control (NSSRC): 0
CAP.NSSRS와 관련
AQA - admin queue attributes
값: 1f001f
Admin Completion Queue Size (ACQS): 32
Admin Submission Queue Size (ASQS): 32
asq : 303d9000
Admin Submission Queue Base (ASQB): 303d9000
acq : 34580000
Admin Completion Queue Base (ACQB): 34580000
cmbloc : 3 Offset (OFST): 0x0 CMB Queue Dword Alignment (CQDA): 0 CMB Data Metadata Mixed Memory Support (CDMMMS): Enforced CMB Data Pointer and Command Independent Locations Support (CDPCILS): Enforced CMB Data Pointer Mixed Locations Support (CDPMLS): Enforced CMB Queue Physically Discontiguous Support (CQPDS): Enforced CMB Queue Mixed Memory Support (CQMMS): Enforced Base Indicator Register (BIR): 0x3
cmbsz : 500003 Size (SZ): 1280 Size Units (SZU): 4 KB Write Data Support (WDS): Write Data and metadata transfer in Controller Memory Buffer is Not supported Read Data Support (RDS): Read Data and metadata transfer in Controller Memory Buffer is Not supported PRP SGL List Support (LISTS): PRP/SG Lists in Controller Memory Buffer is Not supported Completion Queue Support (CQS): Admin and I/O Completion Queues in Controller Memory Buffer is Supported Submission Queue Support (SQS): Admin and I/O Submission Queues in Controller Memory Buffer is Supported
bpinfo : ffffffff Active Boot Partition ID (ABPID): 1 Boot Read Status (BRS): Error completing Boot Partition read Boot Partition Size (BPSZ): 32767
cmbmsc : ffffffffffffffff Controller Base Address (CBA) : fffffffffffff Controller Memory Space Enable (CMSE): 1 Capabilities Registers Enabled (CRE) : CMBLOC and CMBSZ registers are enabled
cmbsts : ffffffff Controller Base Address Invalid (CBAI): 1
pmrcap : ffffffff Controller Memory Space Supported (CMSS) : Referencing PMR with host supplied addresses is Supported Persistent Memory Region Timeout (PMRTO): ff Persistent Memory Region Write Barrier Mechanisms(PMRWBM): f Persistent Memory Region Time Units (PMRTU): PMR time unit is minutes Base Indicator Register (BIR): 7 Write Data Support (WDS): Write data to the PMR is supported Read Data Support (RDS): Read data from the PMR is supported
pmrctl : ffffffff Enable (EN): PMR is READY
pmrsts : ffffffff Controller Base Address Invalid (CBAI): 1 Health Status (HSTS): Reserved Not Ready (NRDY): The Persistent Memory Region is Not Ready to process PCI Express memory read and write requests
pmrebs : ffffffff PMR Elasticity Buffer Size Base (PMRWBZ): ffffff Read Bypass Behavior : memory reads not conflicting with memory writes in the PMR Elasticity Buffer SHALL bypass those memory writes PMR Elasticity Buffer Size Units (PMRSZU): Reserved
NVMe Spec 2장에서는 어떻게 PCI header, PCI capabilities, PCIe extended capabilites가 NVMe controller에 대해 구성되어 있는지를 살펴 본다.
PCIe register에 대한 큰 틀에서의 구성이다. SSD 내에 존재하는 controller의 PCIe와 관련된 IP의 register들에 대한 설정이다. PCI header는 0x00 ~ 0x3F까지 범위이며, 뒤의 register들은 펌웨어에서 메모리 어느 부분에 베이스 주소를 가지고 갈 것인지에 따라 다르게 설정될수 있다.
가장 먼저 PCI header에 대해 살펴 볼 것이다.
PCI Header
PCI header는 디바이스의 타입에 따라 Type 0, Type 1 두 종류로 나뉘며 Type에 따라 header의 bit가 다르게 사용된다. 하지만, 여기에서는 RC 혹은 Bridge를 사용한 디바이스가 아닌 RC에 다이렉트로 연결된 End device를 가정으로 설명한다.
Type 0 header: PCI Express 디바이스
Type 1 header: Switch 및 Root Complex 가상 PCI Bridges
그리고 PCI header에 대해 spec을 그냥 읽는 것 보다는 하나의 디바이스를 예제로 보는 것이 좋기 때문에 아래처럼 실행하자.
$ lspci -x
PCI slot에 연결된 디바이스들에 대해 정보를 알기 위해선 리눅스에서 lspci 명령을 통해 알수 있다. Configuration address 중 PCI header 부분에 대해서만 알고 싶다면 -x 옵션을 전체 4KB에 대한 영역 전부 알고 싶다면 -xxx 옵션을 주면 된다. 아래는Virutual box에서 가상으로 생성한 NVMe device의 결과이다.