星期一, 10月 22, 2012

[OpenWrt] preinit

一般 Linux 執行的第一個指令會是 /sbin/init、/etc/init、/bin/init、/bin/sh 其中之一 ,而 OpenWrt 將第一個執行的指令改為 /etc/preinit。

/etc/preinit 會呼叫 /lib/preinit/ 下的 script 來準備下列五組程式組,記在環境變數裡,並執行前面兩組:
  1. preinit_essential:會先執行,大致上是在掛載 /proc, /sys, /tmp, /dev 等,跟相關 daemon,以及初始化 console。
  2. preinit_main:大致包括載入 reset 按鍵驅動,設定網路界面,檢查是否執行 failsafe 程式組,初始化 hotplug,檢查是否執行 initramfs 程式組,執行 preinit_mount_root 程式組,回復系統設定,最後執行 /sbin/init。
  3. failsafe:提供 telnet 登入
  4. initramfs:似乎是空的
  5. preinit_mount_root:掛載根目錄

星期三, 10月 10, 2012

[設備] TP-LINK TL-WR703N

號稱市面上最小的含有 USB Host 的 Wi-Fi AP,也相當省電,低於 1W[參考來源]

主要處理器是 Atheros AR9331,內含:
  • AR7240 CPU @400MHz
  • Wi-Fi 802.11b/g/n
  • Fast Ethernet (有 5 port,但 WR703N 只用一個)
  • USB 2.0
外加 4MB Flash 及 32MB RAM

AR9331 也用在 TL-MR3020 (多開關及一些燈號)、TL-WR741ND (使用 5 port Ethernet)

由於 OpenWrt 有支援,常拿來改成其它應用。

拆解:[參考]。應該拿小一字起子,往有卡榫的地方插下去。我插在卡榫旁邊不太好拆,需要一些暴力,造成一些損傷。

接 UART 出來
  • 拆開後,正面下方的 TP_IN 及 TP_OUT 分別是 UART 的 Rx 及 Tx,如果接 FT232R 或其它轉 USB 的晶片或連接線,只需要再找一個 GND 接點。有人把 Ethernet 或 USB 的鐵殼當 GND,其實不是。除了背面的 TPGND 外,可以找的很多地方去接 GND。
  • baud rate 是 115200。
備份 u-boot 及 art:
  • u-boot 是 bootloader,損壞的話,將無法開機,也無法做任何更新動作,只能解焊 SPI Flash 透過燒錄器寫入好的 u-boot,才能讓 TL-WR703N 重新運作。有了 u-boot 之後,就可以更新其它任何部份。
  • art 是放無線校準後的資料,損壞的話,可以開機,但會影響到無線功能無法使用。這裡提到,如果沒經過校準,Wi-Fi 訊號可能會較差;也就是複製別台同樣型號及處理器的 art,未必適用。
  • 參考這裡,在 UART console 下用 Linux 的 cp 指令讀出 u-boot 及 art 分割,透過網頁存到 PC。應該也可以使用指令「dd if=/dev/mtd0 of=/tmp/boot.backup」跟「dd if=/dev/$(grep '"art"' /proc/mtd |cut -c 1-4) of=/tmp/art.backup」讀出。
加大 SPI Flash (例如改用 8MB SPI Flash)
  • firmware 修改:
    1. OpenWrt 的 tools/firmware-utils/src/mktplinkfw.c
      •  TL-WR703Nv1 的 fw_max_len 改成 0x7c0000
    2.  target/linux/ar71xx/files/arch/mips/ar71xx/mach-tl-wr703n.c
      • rootfs 的 .size 改成 0x6d0000
      • art 的 .offset 改成 0x7f0000
      • firmware 的 .size 改成 0x7d0000
    3. 編譯,結果在 bin/ar71xx/openwrt-ar71xx-tl-wr703n-v1-squashfs-*.bin
  • 最終 8MB SPI Flash 的內容應該是:
    • u-boot 複製自原本的 flash,放到 8MB flash
    • art 複製自原本的 flash,放到到最後分割,也就是位址 0x7f0000 開始的地方
    • firmware 需要改成支援 8MB Flash 後重新編譯產生,放到位址 0x20000 開始的地方
  • 解焊舊 SPI Flash,焊上新 8MB SPI Flash。
  • 參考
參考資料:

星期一, 10月 08, 2012

[OpenWrt] min. flash and RAM

OpenWrt 至少要有 4MB flash 及 16MB RAM。有些 2MB Flash 或 8MB RAM 的無線路由器 -- TL-WR702N 等,就無法執行 OpenWrt,但基於 Broadcom 處理器的在 DD-WRT 還勉強可以

星期六, 10月 06, 2012

OpenWrt LED

無線路由器有許多 LED 顯示狀態。在 OpenWrt 下,如何控制 LED 呢?

除了電源狀態 (PWR) 是有電就亮,及一些 Ethernet 狀態 (WAN 和 LAN 1 2 3 4) 是 Ethernet Controller 直接控制外,其它 LED 是接到 SoC 的 GPIO,Linux Kernel 有個 platform 子系統,並有一些針對 GPIO 的現成驅動程式,例如驅動程式 leds-gpio 用來控制 LED。只要把 GPIO 的位置,所使用的驅動程式及功能在編譯前設定好,編譯後的 Linux Kernel 就能支援這些 GPIO。
  • 準備資料結構 struct gpio_led,內含每個 LED 名稱、GPIO 接腳、是否 low 動作等。例如:
    static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = {
        {
            .name        = "tl-wr1043nd:green:wlan",
            .gpio        = TL_WR1043ND_GPIO_LED_WLAN,
            .active_low    = 1,
        }
    };
    不清楚 LED 名稱為何要取 tl-wr1043nd:green:wlan 這麼一長串
  • 透過 platform_device_alloc() 取得使用 "leds-gpio" 的資料結構 struct platform_device。(相反是 platform_device_put())
  • 建構資料結構 struct gpio_led_platform_data,包括 LED 數目,及 leds 欄位指到 struct gpio_led
  • 透過 platform_device_add_data() 加進 struct gpio_led_platform_data
  • 透過 platform_device_add() 登記到 Linux Kernel
上述例子是在 Linux 的 arch/mips/ar71xx/mach-tl-wr1043nd.c 執行 arch/mips/ar71xx/dev-leds-gpio.c 裡的 ar71xx_add_device_leds_gpio() 完成的。

編譯後的 Linux 就會有 /sys/class/leds/tl_wr1043nd:green:wlan/  目錄。使用方式,例如
點亮 LED:
echo 1 > /sys/class/leds/tl_wr1043nd:green:wlan/brightness
熄滅 LED
echo 0 > /sys/class/leds/tl_wr1043nd:green:wlan/brightness
應該還有其它用法,待了解。