Dit artikel beschrijft een driver voor SGI IRIX 6.5 die moderne NVMe SSD's toegankelijk maakt door middel van SCSI-emulatie. Hierdoor kunnen legacy IRIX-schijfdrivers werken met moderne hardware.
Kernpunten uit het artikel:
- Compatibiliteit: De driver is ontworpen voor SGI-systemen zoals de Octane (IP30), O2 (IP32) en Fuel (IP35), en is getest op IRIX-versies 6.5.22 en 6.5.30.
- Installatie en Configuratie: Het bouwen van de driver vereist de MIPSPro 7.4.4 compiler en specifieke development libraries. Gebruikers kunnen de driver laden als kernelmodule of, voor IP30 en IP32 systemen, het systeem volledig vanaf de NVMe-schijf laten opstarten.
- Technische Architectuur: De driver fungeert als een vertaallaag die SCSI CDB (Command Descriptor Blocks) vertaalt naar NVMe-commando's. De architectuur is modulair opgebouwd met specifieke componenten voor PCI-ontdekking, commando-constructie en de afhandeling van de completion queue.
- Testen en Diagnostiek: Er is een utility genaamd
nvmectl voor runtime tuning en een uitgebreid testprogramma nvmetest.c voor functionele tests en destructieve random write/read stresstests.
- Hardwarevereisten: Voor gebruik is een PCI-naar-PCIe bridge nodig om de NVMe SSD aan te sluiten op de legacy PCI-slots van de SGI-hardware.
IRIX NVMe-driver
Bouwen
Voorwaarden
Installeer de volledige IRIX-ontwikkelomgeving:
- MIPSPro 7.4.4 compiler (installeer 7.4, en patch vervolgens naar 7.4.4m)
- Development Foundation 1.3
- Development Libraries februari 2002 (laatste versie)
Configuratie
Bewerk het Makefile en stel de variabele CPUBOARD in voor het doelsysteem:
CPUBOARD=IP30 (voor Octane)
CPUBOARD=IP32 (voor O2)
CPUBOARD=IP35 (voor Fuel)
Build en Installatie
Voer de volgende commando's uit:
make # Bouwt de driver
make load # Laadt de kernelmodule
make ioc # Voert ioconfig uit om partities te ontdekken
hinv -v # Verifieert of de NVMe-controller verschijnt in de inventaris (als integral WDC33)
Partitioneren en Mounten
fx: Partitioneer uw NVMe-schijf.
mkfs: Maak het bestandssysteem aan.
- Alternatief: Gebruik de IRIX GUI-beheertools om de schijf te initialiseren en te mounten.
Geavanceerd: Opstarten vanaf NVMe (alleen IP30 & IP32)
⚠️ Waarschuwing: Dit zal de bootconfiguratie van uw systeem wijzigen. Zorg ervoor dat u reservekopieën heeft!
- Voorbereiding (als root):
Formatteer de NVMe-schijf en kloon uw bestaande root-bestandssysteem.
- Makefile aanpassen:
Stel BUILTIN=1 in. Indien u IP32 gebruikt, zet dan DISABLEWC of ENABLEFUA op 1. Deze kunnen tijdens runtime worden gewijzigd via de nvmectl-utility.
- Installatie en configuratie:
``bash make install ` Bewerk /var/sysgen/system/irix.sm en voeg aan het einde toe: USE: nvme`
- Kernel herbouwen en rebooten:
``bash autoconf reboot ``
- In PROM het boot-apparaat instellen:
``bash setenv root dks2d0s0 auto ``
Runtime Tuning en Diagnostiek
make nvmectl
./nvmectl 2 stats # Toont counters + high-water marks (CIDs, PRP pages, timeouts, aborts)
Raadpleeg CHANGES-heavy-write-fix.md voor informatie over de deferred-request scheduler, per-request timeouts en andere wijzigingen die zijn doorgevoerd om langdurige grote schrijfacties (zoals videocapture of render scratch gebruik) te overleven.
Getest met
- Bridges: PLX en PERICOM PCI-PCIe bridges (Sedna en Startech via Amazon); PLX-bridges zijn goedkoper op eBay.
- Adapters: Passieve PCIe-M.2 adapters van diverse merken.
- SSD's: Goedkope Liteon en Patriot NVMe SSD's. (Let op: de Samsung 990 EVO werd niet herkend op de bus).
- Systemen:
- R12K/300 O2 en Dual R14k/600 Octane met shoebox.
- Fuel (gebruik de twee onderste PCI-slots op Fuel voor 66MHz).
- Versies: IRIX 6.5.22 op O2 en Octane, 6.5.30 op Fuel.
- Tevens getest door anderen op O2, Octane en O350.
Projectstructuur
irixnvme/
├── nvme.h - NVMe specificatie definities (registers, commando's, structuren)
├── nvmedrv.h - Driver-specifieke structuren en functieprototypes
├── nvmedrv.c - Hoofdcomponent van de driver (PCI, initialisatie, SCSI-registratie)
├── nvme_scsi.c - SCSI naar NVMe vertaallaag
├── nvme_cmd.c - Constructie en indiening van NVMe-commando's
├── nvme_cpl.c - Afhandeling van de NVMe completion queue
├── Makefile - IRIX make build-bestand
└── README.md - Dit bestand
Architectuur
Verantwoordelijkheden per component
nvme.h
Bevat pure NVMe-specificatiedefinities uit NVMe 1.0e:
- Register-offsets en bit-definities.
- Commando- en completion-structuren.
- Statuscodes.
- Draagbaar over verschillende OS-implementaties.
nvmedrv.h
Bevat IRIX-specifieke driver-structuren:
nvmesoftt: Status van de controller en informatie over de namespace.
nvmequeuet: Beheer van queue-pairs.
- Functieprototypes voor alle modules.
nvmedrv.c
- PCI-driver registratie (wildcard matching op class code
0x010802).
- Initialisatie en afsluiting van de controller.
- SCSI-controller registratie.
- Integratie in de hardware graph.
- Interrupt-afhandeling.
nvme_scsi.c
- Vertaling van SCSI CDB naar NVMe-commando's.
- Implementatie van standaard SCSI-commando's:
- INQUIRY
- READ CAPACITY
- TEST UNIT READY
- READ (6/10/16)
- WRITE (6/10/16)
- MODE SENSE
- SYNC CACHE
- Biedt SCSI-interfacefuncties voor de
dksc-driver.
nvme_cmd.c
- Constructie van NVMe-commando's.
- Admin-commando's (Identify, Create/Delete Queues).
- I/O-commando's (Read, Write).
- Indiening van commando's naar queues en het "luiden" van de doorbell.
nvme_cpl.c
- Verwerking van de completion queue.
- Tracking van de phase bit.
- Dispatch van de completion handler.
- Doorbell updates.
Werking
PCI Discovery
De driver registreert zich met wildcard vendor/device ID's (-1, -1). De attach-functie controleert de PCI class code voor NVMe (0x010802), mapt BAR0 (controller registers) en leest de mogelijkheden van de controller.
SCSI Emulatie
Er wordt een SCSI-controller aangemaakt in de hardware graph: /hw/scsi_ctlr/N. NVMe namespace 1 verschijnt als SCSI target 0. De IRIX dksc-driver koppelt zich vervolgens aan de SCSI-apparaten, waarna SCSI-commando's worden vertaald naar NVMe-commando's.
Apparaatpaden (Device Paths)
Deze kunnen op een Octane enigszins verschillen: /hw/node/io/pci/9 └── scsi_ctlr/(waarschijnlijk)2/ (aangemaakt door NVMe-driver) └── target/0/ (Namespace 1) └── lun/0/ └── disk/ (dksc koppelt hier) └── dks2d1s0 (bruikbaar block device)
Voorbeelden van SCSI naar NVMe Vertaling
| SCSI Commando | NVMe Vertaling |
| INQUIRY | Synthese op basis van Identify Controller |
| READ CAPACITY(10) | Opvragen uit Identify Namespace (NSZE veld) |
| READ(10) | NVMe Read commando met LBA/count uit CDB |
| WRITE(10) | NVMe Write commando met LBA/count uit CDB |
| TEST UNIT READY | Controleren van controller ready bit (CSTS.RDY) |
Testen
Het programma nvmetest.c biedt uitgebreide tests van de driver via de SCSI-laag.
Compileren op IRIX:
cc -o nvmetest nvmetest.c
Basis tests:
./nvmetest -a: Voer alle basistests uit (INQUIRY, READ CAPACITY, enkele read).
./nvmetest -i: INQUIRY test.
./nvmetest -c: READ CAPACITY test.
./nvmetest -r 0: Lees een enkel blok op LBA 0.
./nvmetest -w 100: Write/read verificatie op LBA 100.
./nvmetest -s 0 8192: Sequentiële reads van 8192 blokken (4MB) startend bij LBA 0 (test PRP chaining).
Random write/read stress test (DESTRUCTIEF!):
./nvmetest -R 100: 100 iteraties van random write/read tests.
./nvmetest -R 1000: 1000 iteraties voor uitgebreide testing.
Kenmerken van de Random Write/Read Test
De -R optie voert een uitgebreide stresstest uit die het volgende doet:
- Random LBA selectie: Schrijft naar willekeurige locaties binnen de eerste 10.000 blokken.
- Random transfer groottes: Per operatie van 1 blok tot 1024 blokken (512KB).
- Random buffer alignment: Test 4KB page-aligned, 512B block-aligned en willekeurige 4-byte alignments.
- Data verificatie: Elke schrijfactie wordt gevolgd door 2-5 overlappende leesacties met checksum-verificatie.
- Patroongeneratie: Gebruikt reproduceerbare random datapatronen voor verificatie.
Let op: Deze test is DESTRUCTIEF en zal gegevens op de schijf overschrijven. Gebruik dit alleen op testsystemen zonder belangrijke data.
Voorbeeld output:
=== Random Write/Read Stress Test ===
Max LBA range: 0-10000
Iterations: 100
--- Iteration 1/100 ---
WRITE: LBA 4523, blocks 128 (65536 bytes), align 4096 bytes
Write OK (checksum=0x12345678)
READ 1/3: LBA 4523, blocks 64 (32768 bytes), align 512 bytes
VERIFY OK: overlap LBA 4523-4586 (checksum=0x0abcdef0)
READ 2/3: LBA 4600, blocks 50 (25600 bytes), align 4096 bytes
VERIFY OK: overlap LBA 4600-4650 (checksum=0x0fedcba0)
...
Hardwarevereisten
- SGI-systeem met IRIX 6.5.
- PCI naar PCIe bridge.
- NVMe SSD.
- Geteste platforms: IP32 (O2), IP30 (Octane), IP35 (Fuel). Andere systemen kunnen mogelijk ook werken.
Inspiratie en Referenties
Deze driver is even "absurd" als de Windows 2000 NVMe-driver (nvme2k), in de poging om moderne NVMe-opslag naar een legacy OS te brengen dat meer dan tien jaar ouder is dan de NVMe-specificatie.
Referenties:
- NVMe 1.0e Specification.
- IRIX Device Driver Programmer's Guide (niet nuttig).
simpleirixdriver (basisvoorbeeld van een loadable module).
Licentie
BSD 3-clause. Gebruik op eigen risico.
IRIX NVMe-driver
Bouwen
Voorwaarden
Installeer de volledige IRIX-ontwikkelomgeving:
- MIPSPro 7.4.4 compiler (installeer 7.4, en patch vervolgens naar 7.4.4m)
- Development Foundation 1.3
- Development Libraries februari 2002 (laatste versie)
Configuratie
Bewerk het Makefile en stel de variabele CPUBOARD in voor het doelsysteem:
CPUBOARD=IP30 (voor Octane)
CPUBOARD=IP32 (voor O2)
CPUBOARD=IP35 (voor Fuel)
Build en Installatie
Voer de volgende commando's uit:
make # Bouwt de driver
make load # Laadt de kernelmodule
make ioc # Voert ioconfig uit om partities te ontdekken
hinv -v # Verifieert of de NVMe-controller verschijnt in de inventaris (als integral WDC33)
Partitioneren en Mounten
fx: Partitioneer uw NVMe-schijf.
mkfs: Maak het bestandssysteem aan.
- Alternatief: Gebruik de IRIX GUI-beheertools om de schijf te initialiseren en te mounten.
Geavanceerd: Opstarten vanaf NVMe (alleen IP30 & IP32)
⚠️ Waarschuwing: Dit zal de bootconfiguratie van uw systeem wijzigen. Zorg ervoor dat u reservekopieën heeft!
- Voorbereiding (als root):
Formatteer de NVMe-schijf en kloon uw bestaande root-bestandssysteem.
- Makefile aanpassen:
Stel BUILTIN=1 in. Indien u IP32 gebruikt, zet dan DISABLEWC of ENABLEFUA op 1. Deze kunnen tijdens runtime worden gewijzigd via de nvmectl-utility.
- Installatie en configuratie:
``bash make install ` Bewerk /var/sysgen/system/irix.sm en voeg aan het einde toe: USE: nvme`
- Kernel herbouwen en rebooten:
``bash autoconf reboot ``
- In PROM het boot-apparaat instellen:
``bash setenv root dks2d0s0 auto ``
Runtime Tuning en Diagnostiek
make nvmectl
./nvmectl 2 stats # Toont counters + high-water marks (CIDs, PRP pages, timeouts, aborts)
Raadpleeg CHANGES-heavy-write-fix.md voor informatie over de deferred-request scheduler, per-request timeouts en andere wijzigingen die zijn doorgevoerd om langdurige grote schrijfacties (zoals videocapture of render scratch gebruik) te overleven.
Getest met
- Bridges: PLX en PERICOM PCI-PCIe bridges (Sedna en Startech via Amazon); PLX-bridges zijn goedkoper op eBay.
- Adapters: Passieve PCIe-M.2 adapters van diverse merken.
- SSD's: Goedkope Liteon en Patriot NVMe SSD's. (Let op: de Samsung 990 EVO werd niet herkend op de bus).
- Systemen:
- R12K/300 O2 en Dual R14k/600 Octane met shoebox.
- Fuel (gebruik de twee onderste PCI-slots op Fuel voor 66MHz).
- Versies: IRIX 6.5.22 op O2 en Octane, 6.5.30 op Fuel.
- Tevens getest door anderen op O2, Octane en O350.
Projectstructuur
irixnvme/
├── nvme.h - NVMe specificatie definities (registers, commando's, structuren)
├── nvmedrv.h - Driver-specifieke structuren en functieprototypes
├── nvmedrv.c - Hoofdcomponent van de driver (PCI, initialisatie, SCSI-registratie)
├── nvme_scsi.c - SCSI naar NVMe vertaallaag
├── nvme_cmd.c - Constructie en indiening van NVMe-commando's
├── nvme_cpl.c - Afhandeling van de NVMe completion queue
├── Makefile - IRIX make build-bestand
└── README.md - Dit bestand
Architectuur
Verantwoordelijkheden per component
nvme.h
Bevat pure NVMe-specificatiedefinities uit NVMe 1.0e:
- Register-offsets en bit-definities.
- Commando- en completion-structuren.
- Statuscodes.
- Draagbaar over verschillende OS-implementaties.
nvmedrv.h
Bevat IRIX-specifieke driver-structuren:
nvmesoftt: Status van de controller en informatie over de namespace.
nvmequeuet: Beheer van queue-pairs.
- Functieprototypes voor alle modules.
nvmedrv.c
- PCI-driver registratie (wildcard matching op class code
0x010802).
- Initialisatie en afsluiting van de controller.
- SCSI-controller registratie.
- Integratie in de hardware graph.
- Interrupt-afhandeling.
nvme_scsi.c
- Vertaling van SCSI CDB naar NVMe-commando's.
- Implementatie van standaard SCSI-commando's:
- INQUIRY
- READ CAPACITY
- TEST UNIT READY
- READ (6/10/16)
- WRITE (6/10/16)
- MODE SENSE
- SYNC CACHE
- Biedt SCSI-interfacefuncties voor de
dksc-driver.
nvme_cmd.c
- Constructie van NVMe-commando's.
- Admin-commando's (Identify, Create/Delete Queues).
- I/O-commando's (Read, Write).
- Indiening van commando's naar queues en het "luiden" van de doorbell.
nvme_cpl.c
- Verwerking van de completion queue.
- Tracking van de phase bit.
- Dispatch van de completion handler.
- Doorbell updates.
Werking
PCI Discovery
De driver registreert zich met wildcard vendor/device ID's (-1, -1). De attach-functie controleert de PCI class code voor NVMe (0x010802), mapt BAR0 (controller registers) en leest de mogelijkheden van de controller.
SCSI Emulatie
Er wordt een SCSI-controller aangemaakt in de hardware graph: /hw/scsi_ctlr/N. NVMe namespace 1 verschijnt als SCSI target 0. De IRIX dksc-driver koppelt zich vervolgens aan de SCSI-apparaten, waarna SCSI-commando's worden vertaald naar NVMe-commando's.
Apparaatpaden (Device Paths)
Deze kunnen op een Octane enigszins verschillen: /hw/node/io/pci/9 └── scsi_ctlr/(waarschijnlijk)2/ (aangemaakt door NVMe-driver) └── target/0/ (Namespace 1) └── lun/0/ └── disk/ (dksc koppelt hier) └── dks2d1s0 (bruikbaar block device)
Voorbeelden van SCSI naar NVMe Vertaling
| SCSI Commando | NVMe Vertaling |
| INQUIRY | Synthese op basis van Identify Controller |
| READ CAPACITY(10) | Opvragen uit Identify Namespace (NSZE veld) |
| READ(10) | NVMe Read commando met LBA/count uit CDB |
| WRITE(10) | NVMe Write commando met LBA/count uit CDB |
| TEST UNIT READY | Controleren van controller ready bit (CSTS.RDY) |
Testen
Het programma nvmetest.c biedt uitgebreide tests van de driver via de SCSI-laag.
Compileren op IRIX:
cc -o nvmetest nvmetest.c
Basis tests:
./nvmetest -a: Voer alle basistests uit (INQUIRY, READ CAPACITY, enkele read).
./nvmetest -i: INQUIRY test.
./nvmetest -c: READ CAPACITY test.
./nvmetest -r 0: Lees een enkel blok op LBA 0.
./nvmetest -w 100: Write/read verificatie op LBA 100.
./nvmetest -s 0 8192: Sequentiële reads van 8192 blokken (4MB) startend bij LBA 0 (test PRP chaining).
Random write/read stress test (DESTRUCTIEF!):
./nvmetest -R 100: 100 iteraties van random write/read tests.
./nvmetest -R 1000: 1000 iteraties voor uitgebreide testing.
Kenmerken van de Random Write/Read Test
De -R optie voert een uitgebreide stresstest uit die het volgende doet:
- Random LBA selectie: Schrijft naar willekeurige locaties binnen de eerste 10.000 blokken.
- Random transfer groottes: Per operatie van 1 blok tot 1024 blokken (512KB).
- Random buffer alignment: Test 4KB page-aligned, 512B block-aligned en willekeurige 4-byte alignments.
- Data verificatie: Elke schrijfactie wordt gevolgd door 2-5 overlappende leesacties met checksum-verificatie.
- Patroongeneratie: Gebruikt reproduceerbare random datapatronen voor verificatie.
Let op: Deze test is DESTRUCTIEF en zal gegevens op de schijf overschrijven. Gebruik dit alleen op testsystemen zonder belangrijke data.
Voorbeeld output:
=== Random Write/Read Stress Test ===
Max LBA range: 0-10000
Iterations: 100
--- Iteration 1/100 ---
WRITE: LBA 4523, blocks 128 (65536 bytes), align 4096 bytes
Write OK (checksum=0x12345678)
READ 1/3: LBA 4523, blocks 64 (32768 bytes), align 512 bytes
VERIFY OK: overlap LBA 4523-4586 (checksum=0x0abcdef0)
READ 2/3: LBA 4600, blocks 50 (25600 bytes), align 4096 bytes
VERIFY OK: overlap LBA 4600-4650 (checksum=0x0fedcba0)
...
Hardwarevereisten
- SGI-systeem met IRIX 6.5.
- PCI naar PCIe bridge.
- NVMe SSD.
- Geteste platforms: IP32 (O2), IP30 (Octane), IP35 (Fuel). Andere systemen kunnen mogelijk ook werken.
Inspiratie en Referenties
Deze driver is even "absurd" als de Windows 2000 NVMe-driver (nvme2k), in de poging om moderne NVMe-opslag naar een legacy OS te brengen dat meer dan tien jaar ouder is dan de NVMe-specificatie.
Referenties:
- NVMe 1.0e Specification.
- IRIX Device Driver Programmer's Guide (niet nuttig).
simpleirixdriver (basisvoorbeeld van een loadable module).
Licentie
BSD 3-clause. Gebruik op eigen risico.