2007年5月19日 星期六

透過USB連線與OpenMoko模擬裝置互動

前幾篇文章介紹如何透過qemu來模擬openmokoPoky,這部份的開發逐漸穩定,而qemu現在對於硬體的模擬也頗完整,很多時候我們可直接指定Ethernet模擬來作PXE/BOOTP/TFTP開機或DHCP,於是Host與(Emulated) Target互動就相當簡單。但,如果是openmoko Neo1973/GTA01這類沒有Ethernet (頂多只有Wifi或Bluetooth)的硬體裝置,該如何互動呢?最近加入USB gadget模擬的支援,可將USB slave轉包到Linux 2.6的gadgetfs,如此一來,我們就可建立USB (emulated) network,兩端也可用NFS或sshfs來作檔案分享存取。

在Ubuntu 7.04上操作的方式如下,注意,建議使用一般權限進行,並善用sudo的機制。

取得Linux Kernel原始程式碼:

$ apt-get install linux-source-2.6.20
解開檔案並給予目前的組態:
$ cd /usr/src
$ tar jxf linux-source-2.6.20.tar.bz2 && cd linux-source-2.6.20
$ cp /boot/config-`uname -r` .config
因為Ubuntu預設的USB Gadget/Peripheral controller是實體裝置,但我們需要dummy_hcd (Dummy/Loopback USB host and device emulator driver),所以我們得調整設定:
$ patch -p0 < dotconfig_dummy_hcd.patch
然後建構我們需要的核心模組:
$ make MODVERDIR=drivers/usb/gadget \
drivers/usb/gadget/dummy_hcd.ko \
drivers/usb/gadget/gadgetfs.ko
順利的話就會有兩個 .ko檔,接著就安裝:
$ sudo insmod drivers/usb/gadget/dummy_hcd.ko
$ sudo insmod drivers/usb/gadget/gadgetfs.ko default_uid=`id -u`
Host端需要一個名為/dev/gadget的目錄,以掛載gadgetfs:
$ sudo mkdir -p /dev/gadget
$ sudo mount -t gadgetfs gadget /dev/gadget -o noauto,user,group
核心的部份告一段落,接著我們要來建構qemu,取得最新的openmoko-emulator:
$ svn co https://OpenSVN.csie.org/openmoko_addons/openmoko-emulator
編譯時期需指定kernel header (Ubuntu預設沒有打包全部USB gadget的header):
$ cd openmoko-emulator
$./configure --cc="gcc-3.4 -I/usr/src/linux-source-2.6.20/include"

在最後一行輸出應該要有以下字樣:
USB Gadgetfs support yes
接著就打 "make",順利的話會在arm-softmmu目錄產生名為qemu-system-arm的執行檔。我們可透過script自動下載u-boot、kernel,與rootfs等images並「燒」入我們的模擬硬體中,操作如下:
$ ./openmoko/download.sh
$ ./openmoko/flash.sh
正確的話,畫面會提示run.sh的script檔案被生成,咱們就來跑看看:
$ ./openmoko/run.sh
操作方式在前文「OpenMoko/Neo1973硬體模擬」已提及,不贅述。等X Window的畫面都出現後,就是運用gadgetfs的時機。按下Ctrl-Alt-2組合鍵切入Qemu Monitor,我們可監控與管理Qemu的狀態,當我們打入"info usbslave"指令時,應該有如下的輸出:
USB2.2 device 1457:5122:
Manufacturer: Linux 2.6.20.7-moko8/s3c2410_udc
Product: RNDIS/Ethernet Gadget
Configuration 0: RNDIS
Configuration 1: CDC Ethernet
因為openmoko在啟動X的時候會順便將USB network帶起,這時候我們就可透過gadgetfs去讓Host與(emulated) target互動。同樣在Qemu Monitor畫面,打入 "usb_add gadget:1" 指令,若無錯誤訊息,表示已成功。在Host上的終端機檢查USB gadgetfs的狀態:
$ lsusb -v | grep -A10 -B12 s3c2410
應該會有以下輸出:
Bus 004 Device 003: ID 1457:5122
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1457
idProduct 0x5122
bcdDevice 2.12
iManufacturer 1 Linux 2.6.21.1-moko8/s3c2410_udc
iProduct 2 RNDIS/Ethernet Gadget
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 80
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 7 CDC Ethernet
這時候就可透過CDC Ethernet操作USB network,openmoko在啟動該裝置時就設定IP與route,所以我們只要在Host設定必要的網路組態,即可連線到模擬的裝置:
$ ifconfig usb0 inet 192.168.0.200 netmask 255.255.255.0
$ ssh root@192.168.0.202
順利的話就會看到命令提示畫面:
root@fic-gta01:~$
當然,拿到shell後,什麼事情都可以作。

注意,在關閉openmoko-emulator前,請切換到Qemu Monitor,並打入"usb_del gadget"的指令,要求將gadgetfs的存取關閉,否則很可能會kernel panic。這時候Host的dmesg輸出應該類似以下:
[ 4751.700000] dummy_udc dummy_udc: unregister gadget driver 'gadgetfs'
[ 4751.700000] gadgetfs: disconnected
[ 4751.700000] dummy_hcd dummy_hcd: port status 0x00010100 has changes
[ 4751.700000] dummy_hcd dummy_hcd: port status 0x00010100 has changes
[ 4751.700000] usb 4-1: USB disconnect, address 3
[ 4751.700000] usb0: unregister 'cdc_ether' usb-dummy_hcd-1, CDC Ethernet Device
[ 4753.856000] usb usb4: dummy_bus_suspend
另外,Win32的USB redirection實做我也開始進行,希望不久後也可在Win32進行openmoko的模擬與開發工作。本文內容僅供參考與進度展示,後續的更新會發佈於openmoko官方的wiki: OpenMoko_under_QEMU

1 則留言:

匿名 提到...

win32部份能support usb redirect,目前好像還沒有免錢的的實現,好期待的說!