Na I/O porty můžeš lézt z userspace normálně instrukcemi assembleru in a out (poté, co si povolíš přístup na porty pomocí syscallu iopl --- na to musíš být root). Do paměťově-mapovaných registrů tak, že si namapuješ příslušnou část /dev/mem pomocí syscallu mmap a pak k ní přistupuješ. Co se týče PCI-konfiguračního prostoru, tak buď přes I/O porty --- tam ovšem hrozí, že se popereš s kernelem, který na ty PCI porty bude přistupovat současně (steré Xservery to tak dělaly), nebo přes sysfs (třeba /sys/bus/pci/devices/0000:00:01.0/config).
Asi proto, že dokud nezměníš IOPL pro daný proces, tak opravdu jen z userspace opravdu nejdou. Jinak pozor, iopl() opravdu nastavuje bity IOPL v EFLAGS, což má i jiné vedlejší efekty, např. povolení instrukce "cli".
BTW ví někdo, jak to funguje na jiných architekturách než x86? Co třeba powerpc?
Buď to jde řešit způsobem, jaký naznačili předřečníci, nebo je možné použít nějaký dummy driver, který funkce nějaké karty zpřístupní v user space. Podobná věc, jakýsi universální driver pro PCI zařízení (s podporou pass thru i bus-masteru) v Linuxu, před pár lety řešili v rámci diplomek na VUT v Brně na automatizaci, asi by se dalo zjistit, v jakém je celá věc stavu. Viděl jsem zdrojáky ještě neodladěné verze (ta byla určena pro jednu konkrétní kartu) a bylo to docela čitelné, hlavně v porovnání s funkčně stejnými zdrojáky určenými pro Windows (DDK) :-)