Openwrt 编译以及常用的配置

本文最后更新于:2022年5月9日 晚上

〇、前言

由于业务上的需求,记录从 0 开始的 Openwrt 编译配置过程

一、环境篇

  1. 依赖环境

    1
    sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev gawk gcc-multilib flex git-core gettext libssl-dev ccache
  2. 下载安装更新

    1
    2
    3
    4
    5
    6
    # 下载最新的源代码
    # 可以使用 gitlib 上的版本
    git clone https://github.com/openwrt/openwrt

    ./scripts/feeds update -a
    ./scripts/feeds install -a
  3. 交叉编译环境搭建

    • 在 OpenWrt 官网下载 SDK,如 mt7621 SDK 链接地址

    • 将 SDK 解压到某个位置,如 /usr/local/openwrt_sdk

    • 设置交叉编译器的环境变量

    1
    2
    3
    4
    vim ~/.bashrc

    export PATH='/usr/local/openwrt_sdk/OpenWrt-SDK-15.05.1-ramips-mt7621_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mipsel_1004kc+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin':${PATH}
    export STAGING_DIR='/usr/local/openwrt_sdk/OpenWrt-SDK-15.05.1-ramips-mt7621_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir'

    如果安装成功,输入 mips 后按 Tab 键会出现 mipsel-openwrt-linux-

    • 交叉编译
    1
    mipsel-openwrt-linux-gcc helloworld.c -o helloworld

二、网络篇

  1. 默认添加 iptables 规则

    1
    2
    vim package/network/config/firewall/files/firewall.user
    + iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o tun0 -j MASQUERADE
  2. 允许包转发

    1
    2
    3
    4
    5
    6
    vim package/network/config/firewall/files/firewall.config
    config defaults
    option syn_flood 1
    option input ACCEPT
    option output ACCEPT
    -/+ option forward ACCEPT # 允许转发
  3. WiFi 默认开启、SSID 修改

    1
    2
    3
    4
    5
    vim package/kernel/mac80211/files/lib/wifi/mac80211.sh
    -/+ set wireless.radio${devidx}.disabled=0 # 0-默认开启 1-默认关闭
    -/+ set wireless.default_radio${devidx}.ssid=AP-TEST # SSID
    # SSID 可以实现名称后缀(以MAC地址做后缀)
    # set wireless.default_radio${devidx}.ssid=TS-$(cat /sys/class/net/eth0/address |sed 's/://g')
  4. 修改默认 LAN IP

    1
    2
    3
    4
    5
    6
    7
    vim package/base-files/files/bin/config_generate
    case "protocol" in
    static)
    local ipad
    case "$1" in
    -/+ lan) ipad=${ipaddr:-"192.168.1.1"} ;; # 改这里
    *) ipad=${ipaddr:-"192.168.$((addr_offset++)).1"} ;;
  5. 添加/修改网络接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    vim package/base-files/files/bin/config_generate

    // 默认为电信4G
    generate_static_network() {
    + uci -q batch <<-EOF
    + set network.ppp0='interface'
    + set network.ppp0.ifname='34G'
    + set network.ppp0.proto='3g'
    + set network.ppp0.apn='CTNET'
    + set network.ppp0.service='umts'
    + set network.ppp0.dialnumber='*99#'
    + set network.ppp0.username='ctnet@mycdma.cn'
    + set network.ppp0.password='vnet.mobi'
    + set network.ppp0.device='/dev/ttyUSB1'
    + set network.ppp0.dns='114.114.114.114'
    + EOF
  6. 查看网口的 port

    1
    2
    3
    # 安装 swconfig 工具
    swconfig list # 查看 switch 设备
    swconfig dev eth0 show # 查看网口及其状态,通过插拔网线可以看到端口状态的变化
  7. 修改 switch

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 确认网口后,修改网口 lan/wan 状态
    vim target/linux/ar71xx/base-files/etc/board.d/02_network

    ap143|\
    rb-433|\
    rb-433u)
    ucidef_set_interfaces_lan_wan "eth0" "eth1"
    ucidef_add_switch "switch0" \
    "2:lan" "3:lan" "4:lan" "0@eth1"
    ;;
  8. LAN 口 DHCP 自定义分配 DNS

    1
    2
    3
    4
    vim /etc/config/dhcp

    config dhcp 'lan'
    list 'dhcp_option' '6,8.8.8.8,1.1.1.1'
  9. 使用 dnsmasq 作为 DHCP 服务时设置 DNS

    1
    2
    3
    vim package/network/services/dnsmasq/files/dhcp.conf

    list 'dhcp_option' '6,8.8.8.8,1.1.1.1'

三、系统篇

  1. 开机自启

    1
    2
    3
    vim package/base-files/files/etc/rc.local
    + /etc/init.d/cron enable
    + /etc/init.d/cron start
  2. 查看分区

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    cat /proc/mtd

    dev: size erasesize name
    mtd0: 00080000 00010000 "u-boot"
    mtd1: 00170000 00010000 "kernel"
    mtd2: 00e00000 00010000 "rootfs"
    mtd3: 00900000 00010000 "rootfs_data"
    mtd4: 00010000 00010000 "art"
    mtd5: 00f70000 00010000 "firmware"
    mtd6: 01000000 00010000 "all"
  3. 查看分区

    1
    cat /proc/cmdline
  4. 修改分区

    1
    2
    3
    4
    vim target/linux/ar71xx/image/legacy.mk
    -/+ ap147_mtdlayout=mtdparts=...
    // 改成想要的分区,如果修改了顺序,需要修改下一处的最后一个单词 RKuImage, 按修改后的顺序填写
    -/+ $(eval $(call SingleProfile,AthLzma,64k,AP147_010,ap147-010,AP147-010,ttyS0,115200,$$(ap147_mtdlayout),KRuImage))
  5. 喂狗

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    vim build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.111/arch/mips/ath79/mach-ap147.c

    #include <linux/gpio.h>

    #define AP147_GPIO_XWDT 17 // watchdog gpio
    #define XWDT_AUTOFEED_DURATION (HZ / 3) // 喂狗时间
    static int gpio_external_wdt = -1;
    static int wdt_timeout = -1, wdt_autofeed_count = 0;
    static void watchdog_fire(unsigned long);
    static struct timer_list watchdog_ticktock = TIMER_INITIALIZER(watchdog_fire, 0, 0);

    static void external_wdt_toggle(void) {
    static u32 data;
    data ++;
    gpio_set_value(gpio_external_wdt, data & 0x01);
    }

    static void watchdog_fire(unsigned long data) {
    if(wdt_timeout > 0)
    wdt_autofeed_count++;

    if((wdt_timeout < 0) || (wdt_autofeed_count < wdt_timeout)) {
    external_wdt_toggle();
    mod_timer(&watchdog_ticktock, jiffies + XWDT_AUTOFEED_DURATION);
    }
    }

    static void enable_external_wdt(int gpio) {
    printk("register watchdog init\n");
    gpio_external_wdt = gpio;
    wdt_timeout = -1;
    mod_timer(&watchdog_ticktock, jiffies + XWDT_AUTOFEED_DURATION);
    }

    void __init ap147_setup(vodi) {
    ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE);
    ath79_gpio_output_select(AP147_GPIO_XWDT, 0);
    enable_external_wdt(AP147_GPIO_XWDT);
    }
  6. 查看系统 GPIO

    1
    2
    3
    4
    5
    6
    7
    cat /sys/kernel/debug/gpio

    GPIOs 0-17, platform/ath79-gpio, ath79:
    gpio-1 ( |ap143:green:sys ) out lo
    gpio-3 ( |WPS button ) in hi
    gpio-12 ( |wlan_2g ) out lo
    gpio-13 ( |ap143:green:status ) out hi
  7. RESET 按钮的设置

    注册 RESET 的 GPIO

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    vim build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.111/arch/mips/ath79/mach-ap143.c

    // 添加 RESET GPIO
    #define AP143_GPIO_BTN_RESET 3

    // 注册 RESET BUTTON
    static struct gpio_keys_button ap143_gpio_keys[] __initdata = {
    {
    ...
    },
    {
    .desc = "RESET button",
    .type = EV_KEY,
    .code = KEY_RESTART,
    .debounce_interval = AP143_KEYS_DEBOUNCE_INTERVAL,
    .gpio = AP143_GPIO_BTN_RESET,
    .active_low = 1,
    }
    };

    添加 reset 脚本(按下去时间 > 5 reset)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    vim ./package/base-files/files/etc/rc.button/reset

    #!/bin/sh

    . /lib/functions.sh

    case "$ACTION" in
    pressed)
    return 5
    ;;
    timeout)
    . /etc/diag.sh
    set_state failsafe
    ;;
    released)
    if [ "$SEEN" -lt 1 ]
    then
    echo "REBOOT" > /dev/console
    sync
    reboot
    elif [ "$SEEN" -gt 5 ]
    then
    echo "FACTORY RESET" > /dev/console
    jffs2reset -y && reboot &
    fi
    ;;
    esac

    return 0
  8. 修改 LUCI 界面初始化的小字及首页 URL

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    vim feeds/luci/modules/luci-base/root/www/index.html or
    vim package/feeds/luci/luci-base/root/www/index.html

    package/feeds/luci/luci-base

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Cache-Control" content="no-cache" />
    -/+ <meta http-equiv="refresh" content="0; URL=/cgi-bin/luci/login" /> <!-- 你想要的首页的URL -->

    </head>
    <body style="background-color: white">
    <!-- 你想要的首页的URL -->
    <!-- 你想要的提示 -->
    -/+ <a style="color: black; font-family: arial, helvetica, sans-serif;" href="/cgi-bin/luci/login">欢迎登录xxx</a>
    </body>
    </html>
  9. LED 灯配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    vim build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.111/arch/mips/ath79/mach-ap143.c

    // LED GPIO 定义
    #define AP143_GPIO_LED_WLAN 12
    #define AP143_GPIO_LED_SYS 1
    #define AP143_GPIO_LED_WPS 13
    #define AP143_GPIO_LED_STATUS 13
    #define AP143_GPIO_LED_WAN 11
    #define AP143_GPIO_LED_LAN1 4
    #define AP143_GPIO_LED_LAN2 16
    #define AP143_GPIO_LED_LAN3 15
    #define AP143_GPIO_LED_LAN4 14

    // LED GPIO 注册
    static struct gpio_led ap143_leds_gpio[] __initdata = {
    {
    .name = "ap143:green:status",
    .gpio = AP143_GPIO_LED_STATUS,
    .active_low = 1,
    },
    {
    .name = "ap143:green:wlan",
    .gpio = AP143_GPIO_LED_WLAN,
    .active_low = 1,
    },
    {
    .name = "ap143:green:sys",
    .gpio = AP143_GPIO_LED_SYS,
    .active_low = 0,
    }
    };

    // LED 闪烁
    // 未配置的灯会常亮或者常灭
    static void __init ap143_gpio_led_setup(void)
    {
    ath79_gpio_direction_select(AP143_GPIO_LED_WAN, true);
    ath79_gpio_direction_select(AP143_GPIO_LED_LAN1, true);
    ath79_gpio_direction_select(AP143_GPIO_LED_LAN2, true);
    ath79_gpio_direction_select(AP143_GPIO_LED_LAN3, true);
    ath79_gpio_direction_select(AP143_GPIO_LED_LAN4, true);

    ath79_gpio_output_select(AP143_GPIO_LED_WAN,
    QCA953X_GPIO_OUT_MUX_LED_LINK5);
    ath79_gpio_output_select(AP143_GPIO_LED_LAN1,
    QCA953X_GPIO_OUT_MUX_LED_LINK1);
    ath79_gpio_output_select(AP143_GPIO_LED_LAN2,
    QCA953X_GPIO_OUT_MUX_LED_LINK2);
    ath79_gpio_output_select(AP143_GPIO_LED_LAN3,
    QCA953X_GPIO_OUT_MUX_LED_LINK3);
    ath79_gpio_output_select(AP143_GPIO_LED_LAN4,
    QCA953X_GPIO_OUT_MUX_LED_LINK4);

    ath79_register_leds_gpio(-1, ARRAY_SIZE(ap143_leds_gpio),
    ap143_leds_gpio);
    ath79_register_gpio_keys_polled(-1, AP143_KEYS_POLL_INTERVAL,
    ARRAY_SIZE(ap143_gpio_keys),
    ap143_gpio_keys);

    ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE);
    }
  10. 添加用户

    1
    2
    3
    4
    # 按照相同格式在一下文件中添加记录
    vim package/base-files/files/etc/passwd
    vim package/base-files/files/etc/shadow
    vim package/base-files/files/etc/group
  11. 添加用户到 sudo 组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    vim package/feeds/packages/sudo/Makefile

    define Package/sudo/install
    ···
    chmod 0755 $(1)/etc/sudoers
    echo "admin ALL=(ALL) NOPASSWD:ALL" >> $(1)/etc/sudoers
    chmod 0440 $(1)/etc/sudoers
    ···
    endef
  12. mt7621 的网卡 MAC 地址配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    vim target/linux/ramips/dts/Leguang-Nxc200p-16M.dts

    &ethernet {
    mtd-mac-address = <&factory 0xe000>;
    };

    # 57344 = 0xe000
    target/linux/ramips/base-files/etc/board.d/02_network
    rb750gr3)
    lan_mac=$(mtd_get_mac_binary factory 57344)
    wan_mac=$(macaddr_add "$lan_mac" 1)

四、软件篇

  1. 添加自己的程序 - HelloWorld(含依赖库的 helloworld 程序)

    • 创建 hellloworld 包
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cd package
    mkdir helloworld

    // 目录如下
    helloworld/
    ├── Makefile // Helloworld.ipk 的整体 Makefile;
    └── src // 源程序
    ├── main.c // 源文件
    └── Makefile // 源 MakeFile
    • 源文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    vim helloworld/src/main.c 

    #include <stdio.h>

    int main(void) {
    if (sodium_init() == -1) return -1; // 依赖库,测试是否包含libsodium
    printf("\n********************************\n");
    printf(" hello world! \n");
    printf("********************************\n\n");
    return 0;
    }
    • 源 Makefile
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    vim helloworld/src/Makefile 

    OBJECTS=helloworld
    LIBS += -lsodium

    all:$(OBJECTS)
    PKG_NAME=docs

    helloworld:main.o
    $(CC) $(LDFLAGS) $(LIBS) -std=c99 $^ -o $@

    main.o:main.c
    $(CC) $(CFLAGS) -std=c99 -c $<

    .PHONY:clean
    clean:
    @-rm *.o helloworld
    • 整体 Makefile
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    vim helloworld/Makefile 
    #
    ## Copyright (C) 2014 OpenWrt.org
    #
    ## This is free software, licensed under the GNU General Public License v2.
    # See /LICENSE for more information.
    #

    include $(TOPDIR)/rules.mk # 必须

    PKG_NAME:=helloworld # 包名
    PKG_VERSION:=1.0 # 版本号
    PKG_RELEASE:=1 # 构建号

    include $(INCLUDE_DIR)/package.mk # 必须

    PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) # 构建包的路径

    # 包的简介以及 menuconfig 的位置
    define Package/$(PKG_NAME)
    SECTION:=utils
    CATEGORY:=Utilities
    TITLE:=helloworld -- a Test Program
    DEPENDS:=+libsodium # 依赖库
    endef

    # 包的描述,可以为空
    define Package/$(PKG_NAME)/description
    a test program, Hello World!
    endef

    # 构建包之前的准备,可以为空,会自动创建
    define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR) # 创建 构建包的路径
    cp -r ./src/* $(PKG_BUILD_DIR)/ # 将源码copy到上述路径
    endef

    define Build/Configure
    endef

    define Build/Compile
    endef

    # 安装包所要做的全部事情
    define Package/$(PKG_NAME)/install
    # 设置固件中程序(helloworld)存放在 /usr/sbin/ 下
    $(INSTALL_DIR) $(1)/usr/sbin
    # (INSTALL_BIN) 相当于 cp 命令
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/
    endef

    $(eval $(call BuildPackage,$(PKG_NAME))) # 必须有

    #
    # define Package/$(PKG_NAME)/install
    # 可以使用 shell 命令,可操作性很高
    # 注意:每条shell语句只能一行写完,不能分行(注意 if/where/def 等也只能写一行)
    #
    # 修改文件前需要先创建该文件
    # 例如:往计划任务添加一行指令
    # touch $(1)/etc/crontabs/root
    # if [ `grep -c "/etc/init.d/network restart" $(1)/etc/crontabs/root` -eq '0' ]; then echo "* * * * * /etc/init.d/network restart > /dev/null" >> $(1)/etc/crontabs/root; fi
    #
    # 复制文件前需要先创建文件夹
    # 例如:创建 helloworld 的开机自启脚本(脚本内容同 linux,名称为helloworld, 路径为$(PKG_BUILD_DIR)/bin/helloworld)
    # mkdir -p $(1)/etc/init.d
    # cp $(PKG_BUILD_DIR)/bin/helloworld $(1)/etc/init.d/
    # 可以使用 cp -r 复制文件夹
    • 在 make menuconfig 中选择 helloworld 程序
    1
    2
    3
    4
    # 位置根据 整体 Makefile 中 define Package/$(PKG_NAME) 的 CATEGORY 定义
    make menuconfig
    * Utilities
    * helloworld

五、模块篇

  1. 添加 LONGSUNG U9300C 4G模块支持(ap147)

    • 内核选项
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    make kernel_menuconfig
    Device Drives
    * Network device support
    * PPP(point-to-point protocol) support
    * PPP BSD-Compress compression
    * PPP Deflate compression
    * PPP filtering
    * PPP MPPE compression (encryption)
    * PPP multilink support
    * PPP over Ethernet
    * PPP support for async serial ports
    * PPP support for sync tty ports
    * SLIP (serial line) support
    * CSLIP compressed headers
    * USB Support
    * Support for Host-side USB
    * USB Modem (CDC ACM) support
    M USB Serial Converter support
    * USB Generic Serial Driver
    M USB driver for GSM and CDMA modems
    • 编译选项
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    make menuconfig
    Kernel modules
    USB Support
    * kmod-usb-acm
    * kmod-usb-net
    * * * * all
    * kmod-usb-net2280
    * kmod-usb-ohci
    * kmod-usb-serial
    * * * * all
    * kmod-usb-uhci
    * kmod-usb-wdm
    * kmod-usb2
    Network
    * WWAN
    * comgt
    * comgt-directip
    * comgt-ncm
    * uqmi
    * chat
    * ppp
    * umbim
    * wwan
    Utilities
    * usb-modeswitch
    • 添加驱动支持
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    vim build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.111/drivers/usb/serial/option.c

    // 添加 LONGSUNG U9300C 的 VID(0x1C9E)和PID(0x9B3C)
    #define LONGSUNG_VENDOR_ID 0x1C9E
    #define LONGSUNG_U9300_PRODUCT_ID 0x9B3C

    // 禁止 interface 4 加载驱动
    struct option_blacklist_info {
    const unsigned long sendsetup;
    const unsigned long reserved;
    };

    static const struct option_blacklist_info longsung_u9300_blacklist = {
    .reserved = BIT(4),
    };

    // 在 option_ids 数组中添加黑名单
    static const struct usb_device_id option_ids[] = {
    { USB_DEVICE(LONGSUNG_VENDOR_ID,LONGSUNG_U9300_PRODUCT_ID),
    .driver_info = (kernel_ulong_t)&longsung_u9300_blacklist},
    ···
    { }
    }

    // 使用 usb-serial.ko 驱动的用户,需要在 usb-serial.c 文件中的 usb_serial_probe()函数中增加如下判断来过滤NDIS接口
    vim build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.9.111/drivers/usb/serial/usb-serial.c

    static int usb_serial_probe(struct usb_interface *interface,
    const struct usb_device_id *id)
    {
    ···
    mutex_lock(&table_lock);
    /*************LONGSUNG **************************/
    if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1C9E) &&
    (le16_to_cpu(dev->descriptor.idProduct) == 0x9B3C)) {
    if(interface->cur_altsetting->desc.bInterfaceNumber == 4) {
    printk(KERN_INFO"Discover the 4th interface for U9300C NDIS.\n");
    mutex_unlock(&table_lock);
    return -ENODEV;
    }
    }
    ···
    }
    • 编译,刷写

    • 验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # /dev/ 下出现 ttyUSB0-ttyUSB2 说明 U9300C 的驱动基本没问题
    # 注意:LONGSUNG U9300C 的串口中 AT(ttyUSB2),Modem(ttyUSB1)可以发送 AT 命令,其它不能
    # 也可以通过在 Utilities --> Termi --> minicom 来调试
    cat /dev/ttyUSB2 &
    # 查询版本信息
    echo AT+LCTSW > /dev/ttyUSB2
    # 查询信号,将会得到信号强度和误码率信息
    echo AT+CSQ > /dev/ttyUSB2
    # 查询注册状态
    echo AT+CREG? > /dev/ttyUSB2
    # 网络运营商信息
    echo AT+COPS? > /dev/ttyUSB2
    # 上述几个命令有输出就没问题
    # 查询网络运营商中
    # 中国移动 -- "CHINA MOBILE"
    # 中国联通 -- "CHN-UNICOM"/"UNICOM"
    # 中国电信 -- "CHN-CT"
    killall cat
    • 启动
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    vim /etc/config/network

    # 添加 电信-4G
    config interface '34g-ppp0'
    option ifname 'ppp0'
    option proto '3g'
    option apn 'CTNET'
    option service 'umts'
    option dialnumber '*99#'
    option username 'ctnet@mycdma.cn'
    option password 'vnet.mobi'
    option device '/dev/ttyUSB1'
    option dns '114.114.114.114'

    # 实测:移动和联通同样可以使用上面的配置
    # 移动apn为 CMNET 联通apn为 3GNET

六、编译刷机篇

  1. 备份分区

    1
    dd if=/dev/mtd5 of=/tmp/firmware_backup.bin
  2. 备份及恢复路由器配置文件

    1
    2
    3
    4
    # 备份
    sysupgrade -b /tmp/back.tar.gz
    # 恢复
    sysupgrade -f /tmp/back.tar.gz
  3. 恢复出厂设置

    1
    2
    3
    4
    # 删除 /overlay 分区信息并重启
    rm -rvf /overlay/* && reboot
    # 或者使用 mtd
    mtd -r erase rootfs_data
  4. 编译菜单选择

    1
    make menuconfig
  5. 编译内核选择

    1
    2
    3
    # 注意:内核大小有限制,一般为 1472k
    # 过大会报 uImage is too big,不会生成 sysupgrade.bin 文件
    make kernel_menuconfig
  6. 编译

    1
    2
    3
    4
    # 官方不建议以 root 用户进行编译
    # V=s 表示输出日志
    # -j1 表示单线程编译,线程数可以修改
    make V=s -j1
  7. 刷写固件

    1
    mtd write openwrt.bin firmware
  8. TFTP刷写固件(要先确定地址)

    1
    2
    3
    4
    5
    6
    7
    # 使用串口连接路由器并进入uboot
    # 仅适用于特定路由,参数需要修改
    # 第一段意思是上传固件到 0x80060000 地址
    # 第二段意思是从 0x9f050000 地址开始,擦除上传固件大小的内存
    # 第三段意思是把上传的固件刷入 0x9f050000 地址,长度为固件的大小
    # 第四段 重启
    tftp 0x80060000 firmware_backup.bin &&erase 0x9f050000 +$filesize&&cp.b $fileaddr 0x9f050000 $filesize&&re