Compiling kernel modules for Atheros AR5B22 (AR9462) on Jetson TK1

I recently got a Atheros AR5B22 chip for my Jetson TK1 board, in order to make it support WiFi and Bluetooth. The system provided by NVIDIA (Linux4Tegra 21.4) doesn’t have Atheros driver built-in, so I have to compile it to make use of the device.

AR5B22 installed on Jetson TK1

This is what the chip looks like when installed on TK1. AR5B22 is the Mini PCIe reference design for AR9462, which features both 2.4GHz and 5GHz WiFi and Bluetooth 4.0, according to WikiDevi.

Since it belongs to 9xxx series, Linux kernel has the well-supported driver ath9k for it. Unlike other WiFi-Bluetooth-combo chips from Atheros, this one doesn’t specify which Bluetooth chip it uses (judging by BT 4.0 support, it should be AR3012), but nevertheless you still need ath3k driver and firmware for Bluetooth support. This has bugged me for quite a while, but I figured it out anyway (with hints from this Ubuntu bug report).

If you are familiar with how to compile Linux kernel modules for Jetson TK1, above is all you need to continue. The rest of this article are detailed steps for those who don’t know about this.

Note: The following steps are to compile directly on TK1, and features some hack-y steps for installing them. Also, I am NOT responsible for bricking your device.

  1. First make sure you have the latest Linux4Tegra (L4T) 21.4 installed on your Jetson TK1, which features basic bluetooth support. You can use Jetpack to flash it.
  2. The following steps are all carried out with a shell on TK1. It could be either over SSH (ssh [email protected]), or GNOME Terminal (Ctrl-Alt-T) from GUI if you have a monitor plugged in.
  3. Install the firmware (for ath3k) and dependency (for kernel config menu) packages on your TK1.
    sudo apt-get install linux-firmware libncurses5-dev
    
  4. Download and extract L4T kernel sources into your home directory.
    mkdir ~/kernel && cd ~/kernel
    wget -O kernel_src.tbz2 https://s.du9l.com/Iz4HK  # For L4T 21.4
    tar xf kernel_src.tbz2 && cd kernel
    
  5. Copy existent kernel config as a start.
    zcat /proc/config.gz > .config
    
  6. Enter kernel config menu, and change the following settings.
    make menuconfig
    
    • From “General setup” set “Local version” to “-gdacac96” (check with uname -a), otherwise your compiled module will report “Unknown symbol in module” and “ath9k: version magic … should be …” errors when you insert them.
    • Use “Exit” to go back to the top, then from “Device Drivers – Network device support – Wireless LAN”, press M on “Atheros Wireless Cards” to compile it as a module; then enter it, press M on “Atheros 802.11n wireless cards support”, and press Y on “Atheros bluetooth coexistence support” and “Atheros ath9k PCI/PCIe bus support”.
    • Again, “Exit” to the top, then from “Networking support – Bluetooth subsystem support (should already be M in 21.4 kernel) – Bluetooth device drivers”, press M on “Atheros firmware download driver”.
    • Use “Save” to save your work (default “.config” name is fine), and “Exit” until you are back to the shell.
  7. Use the following command to start the compilation. It usually needs ~5 minutes to finish.
    make -j4 modules
    
  8. Here comes the hack-y part: Officially you need sudo make modules_install to install the modules, but I just want to install the newly compiled ones into a separate folder, so I will use the following commands instead:
    sudo mkdir /lib/modules/`uname -r`/kernel/custom  # `uname -r` becomes "3.10.40-gdacac96" in this case
    find . -name 'ath*.ko' | xargs -I{} sudo cp {} /lib/modules/`uname -r`/kernel/custom/
    sudo depmod -a
    
  9. In order to use WiFi and Bluetooth together, you need to enable “Bluetooth coexistence” in ath9k module.
    echo "options ath9k btcoex_enable=1" | sudo tee /etc/modprobe.d/ath9k_btcoex.conf
    
  10. Finally, insert both modules into the kernel.
    sudo modprobe ath9k ath3k
    

You should now have both WiFi and Bluetooth working. You can check with the following commands:

iwconfig
hciconfig

Just to be clear, I used the above steps with the following hardware, but I suppose you can use the same drivers for any Atheros WiFi AR9xxx series and BT AR3xxx series chip (combo or separate), as long as the 3.10 kernel and ath9k & ath3k modules support them.

$ lspci |grep Atheros
# 01:00.0 Network controller: Qualcomm Atheros AR9462 Wireless Network Adapter (rev 01)
$ lsusb |grep Atheros
# Bus 001 Device 003: ID 0cf3:3004 Atheros Communications, Inc.

配置路由器使用联通 PPPoE IPv6

博主所在的济南联通,很早以前说已经开通了公众 IPv6 网络,但是从 2015 年底才开始陆续有人报告可以获取到 IPv6 地址了。这里面具体怎么回事我就不追究了,今天我也终于成功的在电脑和路由器上配置好了 IPv6 网络。

更新:经过测试,使用 OpenWrt 官方最新的 15.05.1 版本,默认安装无需配置即可获取 IPv6 地址,而且软件库中有更多软件包可用,因此建议直接使用新版,而不要使用 PandoraBox 等版本旧、不开源的分支。小米路由器 Mini其它路由器都可以在官网查询支持情况。

联通在我这里使用的是 PPPoE 拨号上网,在 Windows 系统上无需配置就可以直接获取到 IPv6 地址,所以这篇文章主要说一下 OpenWrt 系统路由器的配置。

1. 第一步当然是准备一个支持 OpenWrt 系统(版本最少是 Attitude Adjustment 12.09.1,建议是 Barrier Breaker 14.07 或更高)的路由器。博主用的是小米路由器 Mini (R1CM),其本身虽然是定制的 OpenWrt 系统,但是界面没法像原版系统一样方便的修改参数,而且没有可用的 opkg 包管理软件(类似于 apt-get),最好还是刷成原始的 OpenWrt 系统。

还是以我手中的小米路由器为例,首先要将系统刷成开发版固件,然后去官网开放 SSH 权限,再接下来就是去下载 PandoraBox(一个国产的 OpenWrt 分支,适配很多国产路由器)并刷机。我使用的刷机命令是:

wget -O /tmp/pandora.bin http://.../xxx.bin  # 此处是你的路由器对应的 PandoraBox ROM 地址
mtd -r write /tmp/pandora.bin OS1  # "OS1" 可能根据路由器型号不同也不一样

2. 刷好机并进入后台后,请先确认左侧“系统”-“软件包”中有“odhcp6c”这个软件。如果没有的话,建议先“刷新列表”,然后在“可用软件包”中安装它。这个软件是用于通过 DHCP 协议自动获取 IPv6 地址的,因此对本教程至关重要。在 12.09.1 系统中可能不提供这个软件,那么建议下载类似的软件包(通常名字中含有 dhcp 和 6)。

3. 接下来,可以转到左侧“网络”-“接口”,默认内置了三个选项:LAN、WAN 和 WAN6。如果你的系统没有 WAN6,可以在接口中新建一个接口,并将“协议”设置为“DHCPv6 client”并点击“切换协议”。

接下来,在 WAN6 接口中按照如下配置:(括号内是 /etc/config/network 中对应的配置项,都在 config ‘interface’ ‘wan6’ 这一段中)

  • 基本设置:
    • Request IPv6-address:Disabled(option reqaddress ‘none’)
    • Request IPv6-prefix of length:自动(option reqprefix ‘auto’)
  • 物理设置:
    • 接口:自定义接口,并输入 @wan(option ifname ‘@wan’)

这样完成了 DHCP 获取 IPv6 地址的配置,可以先“保存”(不必现在应用)。接下来配置一下 PPPoE 上网信息,在左侧找到“接口”-“WAN”,并进行如下配置:(括号同上,属于 config ‘interface’ ‘wan’ 这一段)

  • 基本设置:
    • 协议:选择 PPPoE,但是如果你是其它网络,可以按自己的情况选择“静态地址”、“DHCP 客户端”等。(option proto ‘pppoe’)
    • PAP/CHAP 用户名、密码:输入宽带拨号的用户名和密码即可。(option username ‘xxx’ / option password ‘xxx’)
  • 高级设置:
    • 在 PPP 链路上启用 IPv6 协商:打勾(option ipv6 ‘1’)

这样也完成了上外网配置,还是先“保存”。最后进行一下“接口”-“LAN”中的配置:(属于 config ‘interface’ ‘lan’ 这一段)

  • 上部分“基本设置”:
    • IPv6 assignment length:64(option ip6assign ’64’)
  • 下部分“IPv6 Settings”:
    • Always announce default router:打勾(option ra_default ‘1’)

全部搞定,此时选择“保存&应用”,然后等待大概一分钟(PPPoE 拨号、获取 IPv6 地址的时间),路由器和所连接设备应当都能获得 IPv6 地址了。

路由器配置成功后,可以从以下两处看到效果:

(1) “状态”-“总览”-“网络”:

(2) “网络”-“接口”:

大概解释一下其中的意思:2408:802a::ee3a/64 这个地址,是路由器 WAN 口本身获得的 IPv6 地址,在路由器上使用 ping6 等命令,就是通过这个 IP 向外访问。而2408:802a::0:1/64 这个 IPv6 网段,是路由器从网络中申请到的专用子网段,用于分配给连接到路由器的设备。

回忆今天的华为上机考试题

今天下午参加了华为在济南的上机考试(据说上午也有一批,题不一样)。回忆一下考的题目,总体还是很水,但是最后一题还是可耻的 WA 了……

  1. 初级题(100分,6个点):送分,输入a和b,输出[a,b]之间的素数,没有时间、空间限制,而且题干用中文把算法都给描述出来了,考验你是否会打开VS或Eclipse、编译、运行……
  2. 中级题(200分,4个点):输入一串逗号分隔(脑残)的数,不超过1000且无重复,输出这串数中可以被其它数整除的数,要求按输入顺序。基本也是送分,除了输入比较恶心(一般都是输入n,然后输入n个数;这个我只能用字符串一位一位处理了)。
    样例:输入”3,4,2,6″,输出”4 6″。
  3. 高级题(300分,4个点):有N个岛,给出岛间距离,全部连通最少需要多少距离的桥?输入n(3<=n<=1000),再输入n*n的邻接矩阵表示距离(没有给出距离的范围……都没说是不是整数……),输出最短桥距离。
    明显是MST,写完贪心(Kruskal,只记得这一种,也不让上网搜)交上去WA 2/4,而且只能提交五次,改了4种版本之后依然稳定的2/4,最后就只拿到一半分。交完最后一次才想到,是不是距离可能有浮点数……
    样例输入(自己编的):
    3
    0 123 456
    123 0 789
    456 789 0
    输出:579

总之是很水的题目,而且要吐槽的是做完之后不能走(15分钟做完前两题、45分钟败完5次提交,剩下一小时就瞪着监考老师),还要做职业测试(精神病测试),做完一遍因为做的太水又被迫做了第二遍……呵呵哒。

PS: 考场上有个孩子,可怜兮兮的给监考老师说,老师我没用过VS,我只会用Code::Blocks,这个VS简单的程序也报错,blah blah……当时我就傻了,还真有只用过Code::Blocks的大神orz……

PSS: 蒋震机房的XP+VS2005真是亮瞎了朕的氪金狗眼,新建工程Debug报缺少DLL,必须先修改一个“FAT32什么什么”的选项才能用……

Another afternoon wasted: How to choose two fonts with fontconfig

After upgrading to Ubuntu 16.04, the font in my GNOME is a mess (again). So I spent another afternoon trying to figure out how to choose the fonts I need using fontconfig.

This is what I achieved using Source Sans Pro and Source Han Sans CN. The default was to use DejaVu Sans and SimSun.

My goal is to use two fonts, an English one for displaying generic characters, and a Chinese one for, um, Chinese. Although I can use a single Chinese font for both, but the English characters displayed in Chinese font is disastrous. So basically I want to tell fontconfig to use the two fonts in a preferred order: Use English one wherever possible, and fallback to the native one when the former can’t do the job.

Actually I have solved this before, but I forgot what I did back then. So I had to spend another afternoon Googling and reading their long and non-standardized docs on how to express my request in their weird XML tags. After several attempts, I found that the following configuration works just fine.

The whole XML below should be saved as ~/.config/fontconfig/conf.d/99-xiaodu.conf (create non-existent folders when needed), which is the preferred location for user-specific fontconfig files.

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <!-- For other languages -->
  <match target="pattern">
    <test qual="any" name="family">
     <string>sans-serif</string>
   </test>
   <edit name="family" mode="prepend" binding="strong">
      <string>Arial</string>
    </edit>
 </match>
  <match target="pattern">
    <test qual="any" name="family">
     <string>serif</string>
    </test>
   <edit name="family" mode="prepend" binding="strong">
      <string>Times New Roman</string>
    </edit>
 </match>
  <match target="pattern">
    <test qual="any" name="family">
     <string>monospace</string>
    </test>
   <edit name="family" mode="prepend" binding="strong">
      <string>Inconsolata</string>
    </edit>
 </match>
  <!-- For Chinese -->
  <match target="pattern">
    <test name="lang">
      <string>zh-cn</string>
    </test>
   <test qual="any" name="family">
     <string>sans-serif</string>
   </test>
   <edit name="family" mode="prepend" binding="strong">
      <string>Arial</string>
      <string>Source Han Sans CN</string>
   </edit>
 </match>
  <match target="pattern">
    <test name="lang">
      <string>zh-cn</string>
    </test>
   <test qual="any" name="family">
     <string>serif</string>
    </test>
   <edit name="family" mode="prepend" binding="strong">
      <string>Times New Roman</string>
      <string>Simsun</string>
   </edit>
 </match>
  <match target="pattern">
    <test name="lang">
      <string>zh-cn</string>
    </test>
   <test qual="any" name="family">
     <string>monospace</string>
    </test>
   <edit name="family" mode="prepend" binding="strong">
      <string>Inconsolata</string>
      <string>Source Han Sans CN</string>
   </edit>
 </match>

</fontconfig>

Basically this file tells fontconfig, when the locale is zh-cn (Chinese), it should to prepend the two fonts (English and Chinese) to the matching list; otherwise just prepend the English one.

Notice that the first font in each <edit> block is the English font, where the second is the native font. You should replace the language code (RFC3066 style) and all six font names using your favorite text editor, with respect to the fonts’ types (sans, serif or mono). If you want to test your work, use fc-match with something like $ LANG=zh-CN fc-match -s sans | head -2.

I just hope one day there would be a nice GUI for all this crap.

中文摘要:这篇文章介绍如何在 Ubuntu 中通过配置 fontconfig 同时选择要使用的英文和中文字体,使用英文字体显示一般字符,中文字体显示中文字符。

回忆一下 360 实习编程题

现在两批人都考完了,来透个题。规定上说不能用笔抄,没说不能用脑子记。省略全部废话,只说题干。总体来说就是一个字:

1. 两个人A、B,从一个整数范围(说是N,目测是[1,N],题出的非常模糊)里面各选一个数a和b,然后用一个均匀随机生成器在范围里生成一个数c,看谁离c近赢,相同距离算b赢。

现在输入是N和a,求b选几的时候胜率最大,相同胜率取最小。

样例:3 1 (输出2)、4 3 (输出2),完美的避开了是0还是1开始的问题……

</题干> 卤煮做了40%(还做出过20%,应该是5个点),还想出一个边界条件没写对,不知道剩下的错在哪里。

2. 给定字符串s,由a~z和小数点“.”组成,定义操作a(s),表示将s中最早出现的连续两个点替换成一个点;定义函数f(s),表示进行多少次操作a可以使得字符串中没有连续的点。

输入为n(字符串长度),m(字符串替换操作);第二行为n长字符串;第3行开始的m行,每行有k和c,表示将s中第k个字符(从1开始数,傻叉)替换为c。要求在每次替换后,输出替换后s’当前f(s’)的值。

样例:原来的巨长无比,我就随便编一个:4 1 a..b 4 . (输出2)。

</题干> 水题,只要注意是1开始这个大坑。读入后先计算原始的f(s),然后每次操作后,拿出操作位左右各一位,判断这三位在变化前后的diff,加到原始f(s)即可(当然,过后要真的替换)。

————————————————

2/5的WA啊,哪有这么多边界条件啊,我猜是大数据点输出的时候变成了科学记数法,但是我安装了跟OJ一样的g++版本,并没有被科学……天知道为什么,呵呵哒。

另外理论题考了好多设计模式、算法、数据库的细节题,理论渣表示全靠蒙,不服跑个分。