希望本教學也可以幫助到一些使用 Siano 方案的電視棒的使用者!

花了一點時間 + GPT 幫忙分析,終於成功一圓之前未竟的遺憾?

沒想到思路對了,把韌體改正確後,這隻”沒有官方Linux驅動”的電視棒,也可以正確在Linux下被驅動啦!!

思路

  1. 該電視棒在Windows沒有安裝驅動的時候,裝置會為 Test EEPROM Product String ,其實,此種電視棒(IC 為 Siano 家的 SMS1150),本電視棒的韌體在拔電之後會揮發,在插上電腦的時候,驅動會對電視棒載入正確的韌體 dvb_nova_12mhz_b0.inp ,才能正確的接收電腦的請求並接收 DVB-T 訊號

    1000044233.jpg

    (這是怎麼發現的呢…測試正確的方式的時候,發現如果Linux端"韌體”沒有載入正確,在Linux下無法正確解碼電視訊號,不過裝置有正確建立;不過當我把裝置從Linux虛擬機移動回Windows(有裝驅動),再移動回Linux…可以解碼了,而拔掉一陣子再插回又不能解碼,所以韌體應該是暫存在某個位置(例如電視棒上的記憶體裡))

  2. 研究之後發現其實Siano電視棒的韌體包含很多種,那應該載入哪種呢? 在Windows的裝置管理員查看正確驅動的電視棒會發現以下選單:

    image.png

    可以發現所有的韌體都帶有 B0 ,在 Linux 測試的時候發現清單中帶有 B 的會嘗試載入帶有 b0 尾巴的韌體檔 (像晶片組一樣有B0步進這種東西?)。另外,觀察韌體檔可以發現 nova 這個關鍵字,都是判定 Linux 下要怎麼載入驅動的線索!

  3. 使用 SMS1150 Linux 關鍵字搜尋,可見很早之前該卡的驅動似乎就被加入 Linux 驅動清單了,那驅動這支電視棒應該不是不可能的事情?

  4. 這支電視棒不論插在 Windows 或是 Linux ,都會出現一個不尋常(?的 USB ID,VID:1b80(Kworld)/PID:e414 ,因此在Linux下是無法正確地被Linux下的Siano電視棒驅動正確識別,並正確載入應有的韌體並驅動的,所以就需要走一些歪路修改驅動囉

修改方式(正題開始)

<aside> ⚠️

本部分教學方式以 osboxes.org 下載下來的 Xubuntu 22.04 韌體為基礎,請依照自己的 Linux 發行版調整修改方式,對 Linux 模組不熟悉的不建議操作!

</aside>

  1. 下載Linux原始碼

    sudo apt install linux-source
    
  2. 建立編譯資料夾

    mkdir /usr/src/smsusb-make
    
  3. 解開內核原始碼 (請自行替換指令成自己使用的內核版本)

    cd /usr/src
    sudo tar xf linux-source-6.8.0.tar.bz2
    
  4. 複製原始的驅動檔案 (請自行替換指令成自己使用的內核版本)

    cp /usr/src/linux-source-6.8.0/drivers/media/usb/siano/smsusb.c /usr/src/smsusb-make/
    
  5. 在編譯資料夾 /usr/src/smsusb-make 中建立 Makefile

    cd /usr/src/smsusb-make
    nano Makefile
    

    內容 (ChatGPT 幫忙的,我也不會寫XD)

    # Build standalone smsusb.ko against current kernel
    obj-m := smsusb.o
    
    # 指向完整 kernel source tree (你已經展開在 /usr/src/linux-source-6.8.0)
    KDIR := /usr/src/linux-source-6.8.0
    
    # 目前工作目錄
    PWD := $(shell pwd)
    
    # 加入 Siano 共用程式碼的 include path
    ccflags-y += -I$(KDIR)/drivers/media/common/siano
    
    all:
    	$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) EXTRA_CFLAGS="$(ccflags-y)"
    
    clean:
    	$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    
    
  6. 修改原始的驅動檔案

    nano /usr/src/smsusb-make/smsusb.c
    

    修改以下部分 (用 struct usb_device_id 找到以下區塊,並新增底下提示的那三行)

    <aside> 💡

    記得前面思路部分發現的 nova b2 線索嗎?還有IC型號是 SMS1150

    所以最適合的驅動推論下來就是 SMS1XXX_BOARD_SIANO_NOVA_B 最合理囉!

    驗證後確實也是可用!

    </aside>

    static const struct usb_device_id smsusb_id_table[] = {
    	/* This device is only present before firmware load */
    	{ USB_DEVICE(0x187f, 0x0010),
    		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR_ROM },
    	/* This device pops up after firmware load */
    	{ USB_DEVICE(0x187f, 0x0100),
    		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
    		
    	/* 下面三行是要增加的部分 */
    	/* This is for Kworld UB220-T LE*/
    	{ USB_DEVICE(0x1b80, 0xe414),
    		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
    		
    	{ USB_DEVICE(0x187f, 0x0200),
    		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
    	{ USB_DEVICE(0x187f, 0x0201),
    		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
    	{ USB_DEVICE(0x187f, 0x0300),
    		.driver_info = SMS1XXX_BOARD_SIANO_VEGA },
    
  7. 修改存檔好後,編譯驅動

    cd /usr/src/smsusb-make
    sudo make
    

    編譯好的檔案如下

    $ ls -l
    total 1020
    -rw-r--r-- 1 root root    492 Sep 28 10:05 Makefile
    -rw-r--r-- 1 root root     30 Sep 28 10:57 modules.order
    -rw-r--r-- 1 root root      0 Sep 28 10:57 Module.symvers
    -rw-r--r-- 1 root root  19749 Sep 28 10:53 smsusb.c
    -rw-r--r-- 1 root root 496728 Sep 28 10:57 smsusb.ko
    -rw-r--r-- 1 root root     30 Sep 28 10:05 smsusb.mod
    -rw-r--r-- 1 root root   6103 Sep 28 10:57 smsusb.mod.c
    -rw-r--r-- 1 root root 155408 Sep 28 10:57 smsusb.mod.o
    -rw-r--r-- 1 root root 344728 Sep 28 10:57 smsusb.o
    
  8. 之後下載電視棒的韌體,也可以從Windows驅動檔案複製出來

    這個是我做的驅動備份,亦可在 Windows 11 下正常使用:https://archive.org/details/kw-ub-220-t

    如果從Windows驅動複製,請複製 dvb_nova_12mhz_b0.inp 韌體檔案到Linux電腦

    image.png

    否則可使用以下方式,將網路上的相同檔案載到 /tmp 暫存目錄下

    cd /tmp
    sudo wget <https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/dvb_nova_12mhz_b0.inp>
    
  9. cd 指令移動到韌體所在的路徑後,複製進正確位置

    cp dvb_nova_12mhz_b0.inp /lib/firmware/
    
  10. 嘗試載入驅動,可先插上電視棒,先載入相依模組:

    sudo modprobe smsdvb
    

    再載入剛剛的修改模組

    sudo insmod /usr/src/smsusb-make/smsusb.ko