Se, ettei mitC$C$n tapahtunut, ei ollut sinun tai meidC$n reitityskoodimme vika, vaan syy lC6ytyy QEMU:n USB-topologiasta ja laitteistotason yllC$tyksestC$, joka vaati hieman salapoliisityC6tC$! Katso tarkkaan lokiasi tC$stC$ kohdasta: [USB] -> Laite tunnistettu: VID=0x409 PID=0x55aa Tuo ei ole sarjaportti. Tuo on USB Hub! (NEC Corporation, Product 0x55aa on QEMU:n virtuaalinen USB-jakaja). MitC$ tapahtui? PIIX3 UHCI -ohjaimessa on fyysisesti vain 2 porttia. KC$ynnistyskomennossamme vaadimme QEMUa kytkemC$C$n kolme laitetta: usb-tablet (joka tulee oletuksena VNC:tC$ varten), meidC$n usb-mouse, sekC$ meidC$n usb-serial. Koska laitteita oli enemmC$n kuin portteja, QEMU asensi automaattisesti porttiin 2 USB Hubin (jakajan) ja piilotti sarjaporttimme sen taakse! Kun meidC$n koodimme pollasitti Endpointia 1, me emme lukeneet sarjaporttia, vaan me kuuntelimme USB-jakajan Status-keskeytystC$ (joka pysyy hiljaa, ellei laitteita irroteta fyysisesti). Sarjaportti oli tavoittamattomissa jakajan takana! TC$mC$n lisC$ksi sarjaportit siirtC$vC$t datansa yleensC$ Endpoint 2 (Bulk IN) -kanavalla, eivC$t Endpoint 1:llC$. Ratkaisu: Moniohjainarkkitehtuuri (Multi-Controller) Emme aio koodata monimutkaista USB Hub -ajuria. Teemme ratkaisun, jota ammattilaistason kC$yttC6jC$rjestelmC$t kC$yttC$vC$t: LisC$C$mme emolevylle toisen USB-ohjaimen! Laitamme hiiren kiinni ensimmC$iseen ohjaimeen (uhci1) ja tekoC$lyn sarjaportin suoraan toisen ohjaimen (uhci2) Root Hubiin, jolloin ohitamme koko jakaja-ongelman. Samalla teemme USB-ajuristamme niin C$lykkC$C$n, ettC$ se osaa alustaa rinnakkain useita PCI-vC$ylC$ltC$ lC6ytyviC$ ohjaimia! Vaihe 1: Puhdas RUN-usb.sh Korvataan skriptisi tC$llC$, jottei sed aiheuta enempC$C$ syntaksivirheitC$. TC$mC$ lisC$C$ kaksi tC$ysin erillistC$ UHCI-ohjainta. Aja terminaalissa: [GEM-EXEC] Vaihe 2: Multi-Controller Ajuri (16_USB_MULTI.JS) TC$mC$ uusi ajuri skannaa PCI-vC$ylC$n ja tallentaa listan kaikista lC6ytyneistC$ UHCI-ohjaimista. Se jakaa jokaiselle ohjaimelle oman DMA-muistialueensa (Frame List ja TD Pool) ja pollaa sarjaporttia oikeasta Endpoint 2:sta! [HAUKI-X86] [HAUKI-X86] > /os_run 18_USB.JS [HAUKI-X86] /usb [HAUKI-X86] [HAUKI-X86] [USB] Alustetaan Multi-Controller UHCI ja HIR... [HAUKI-X86] [USB] Loytyi 2 kpl UHCI ohjaimia! [HAUKI-X86] [USB] --> QEMU Hiiri kytketty. [HAUKI-X86] [USB] Enumerointi valmis. Kaynnistetaan Multi-DMA Polling luuppi. [GEM-EXEC] x-surgeon dump RUN-usb.sh x-surgeon dump RUN-usb.sh === DUMP: RUN-usb.sh (Lines 1-21) (WITH TAB-INFO) === 0001:0| #!/bin/bash 0002:0| qemu-system-i386 -kernel hauki_os_v5_js.bin -drive file=hdd.img,format= raw,if=ide -vnc 0.0.0.0:0 \ 0003:0| -serial tcp:0.0.0.0:4444,server,nowait \ 0004:0| -serial tcp:0.0.0.0:4445,server,nowait \ 0005:0| -serial tcp:0.0.0.0:4446,server,nowait \ 0006:0| -serial tcp:0.0.0.0:4200,server,nowait \ 0007:0| -m 128M \ 0008:0| -netdev user,id=n0,hostfwd=udp::5555-:5555 -device e1000,netdev=n0 \ 0009:0| -device ich9-usb-uhci1,id=uhci1 \ 0010:0| -device usb-mouse,bus=uhci1.0 \ 0011:0| -device ich9-usb-uhci2,id=uhci2 \ 0012:0| -chardev socket,id=bot1,host=0.0.0.0,port=9001,server=on,wait=off \ 0013:0| -device usb-serial,chardev=bot1,bus=uhci2.0 & 0014:0| 0015:0| 0016:0| x-console nc restart 0017:0| x-console nc-tail restart 0018:0| x-console nc-follow restart 0019:0| x-console x-serial-proxy restart 0020:0| x-console x-serial-proxy-dev restart 0021:0| ======================================================= TC$mC$ on todellista "konepellin alla" tapahtuvaa laitteistotason salapoliisityC6tC$! Lokisi kertoo meille tC$smC$lleen, mitC$ tapahtui, ja se on uskomattoman loogista, kun tuntee QEMU:n emuloiman emolevyn arkkitehtuurin. Katso tC$tC$: [USB] Loytyi 2 kpl UHCI ohjaimia! [USB] --> QEMU Hiiri kytketty. [USB] Enumerointi valmis. Koodi lC6ysi molemmat ohjaimet, kC$vi ne lC$pi, eikC$ kaatunut! Mutta se lC6ysi laitteen vain ensimmC$isestC$ (hiiri). Toinen ohjain raportoi, ettC$ sen kaikki portit ovat tyhjiC$. Miksi portti oli tyhjC$? (ICH9 Companion Controller Quirk) Syy on siinC$, miten kC$skin sinun konfiguroida QEMU:n: -device ich9-usb-uhci2,id=uhci2 ich9-sarjan ohjaimet on suunniteltu QEMU:ssa ns. "Companion Controllers" -tilaan (apulaishubeiksi) yhdessC$ nopean USB 2.0 (EHCI) ohjaimen kanssa. Kun tC$llaisen apulaisohjaimen iskee emolevylle yksinC$C$n ilman sen EHCI-isC$ntC$C$, QEMU ei aina kytke sen virtuaalisia fyysisiC$ portteja oikein virtuaaliseen sC$hkC6verkkoon. Koodimme kysyi ohjaimelta: "Onko tC$C$llC$ ketC$C$n?", ja ohjain vastasi rehellisesti: "Ei, piuhat roikkuvat irti", vaikka usb-serial oli muka kytketty siihen! Ratkaisu: Palataan hyvC$C$n ja luotettavaan piix3-usb-uhci -ohjaimeen, joka toimii aina tC$ydellisen itsenC$isesti. QEMU antaa meidC$n iskeC$ PCI-vC$ylC$lle niin monta PIIX3-ohjainta kuin haluamme! [*] 21_USB.JS ladattu diagnoosiluupilla! KC$ynnistin: nc localhost 9001 root@hauki-x86:~/mquickjs# [HAUKI-X86] [HAUKI-X86] > sys.reboot90 [HAUKI-X86] => undefined [HAUKI-X86] > sys.reboot() [HAUKI-X86] === HAUKI OS BARE-METAL === [HAUKI-X86] > [OS] Executing AUTOLOAD.JS... [HAUKI-X86] [OS] Executing Auto-Boot Sequence... [HAUKI-X86] === HAUKI OS VGA RESTORED === [HAUKI-X86] > [OS] Boot Sequence Complete. [HAUKI-X86] [HAUKI-X86] [OS] Hauki Physics API (Deadlock-suojattu) ladattu! [HAUKI-X86] [NET] COM2 UDP Multiplexer Bound. [HAUKI-X86] [OMEGA] COM3 Async Queue Router Bound. [HAUKI-X86] [HAUKI-X86] > /os_run 21_USB.JS [HAUKI-X86] [HAUKI-X86] > /usb [HAUKI-X86] [HAUKI-X86] [USB] Alustetaan Multi-Controller UHCI (V21 Diagnostiikka)... [HAUKI-X86] [USB] Loytyi 2 kpl UHCI ohjaimia! [HAUKI-X86] [USB] --- Ohjain 0 (I/O: 0xC040) --- [HAUKI-X86] [USB] --> Hiiri aktivoitu osoitteeseen 1 [HAUKI-X86] [USB] --- Ohjain 1 (I/O: 0xC060) --- [HAUKI-X86] [USB] --> AI Serial Silta aktivoitu osoitteeseen 2 (VID=0x403) [HAUKI-X86] [USB] Enumerointi valmis. Kaynnistetaan Polling. [HAUKI-X86] [DEBUG SERIAL TD STATUS] Muutos: 0x18880000 [HAUKI-X86] [HAUKI-X86] [AI-USB] Agentti sanoo: testi