OpenWrt Forum Archive

Topic: Transcend WifiSD / PQI AirCard / FluCard Pro

The content of this topic has been archived between 29 Mar 2018 and 30 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.


Did anyone test the I/O speed for the card?

I use dd to test read and write performance on the Transcend WiFi SD.

For the sdcard, /mnt/sd, read speed is about 1.9 MB/s, and write speed is about 1.2 MB/s.

As reference, I tried same thing on /tmp, which should be the ramdisk, read speed is about 28 MB/s, and the write speed is about 23 MB/s.

I understand I/O speed in the embedded system should be slower, but I'm not sure whether it should as slow as this? I tested the card I/O speed on my MacBook host, which I got I/O speed about 20MB/s, so I think the card itself is fast.

And I found during the reading or writing on the /mnt/sd, [mmcqd]'s cpu usage is very high, almost always above 50% during the period.

I also tried the HTTP speed, if I download a file from /mnt/sd, I got about 950 KB/s, and if I download a file from /tmp, I got about 1.35 MB/s, which seems also quite slow, as the card support 802.11n.

Is there any bottleneck in the sdhc driver? or the speed I got just match performance of embedded system like these cards?

dancefire wrote:

Did anyone test the I/O speed for the card?

I can confirm your findings with my Transcend card:

# cd /mnt/sd
# ./busybox time ./busybox dd if=/dev/zero of=zero bs=4M count=10
10+0 records in
10+0 records out
real    0m 33.39s
user    0m 0.00s
sys     0m 6.33s
# ./busybox time ./busybox dd if=zero of=/dev/null
81920+0 records in
81920+0 records out
real    0m 17.77s
user    0m 0.55s
sys     0m 5.07s

That's 1.26 MB/s write, 2.36 MB/s read. Either the SDHC driver is poorly coded (we can't know until they release the source), or there's a limitation in the "switch" that prioritises the external host. I can only guess.

I've been looking over their modifications to the Busybox source, trying to figure out how files are synchronized between the two systems. Let me share what I've learned:

  1. /etc/init.d/rcS calls /usr/bin/ which forks the kcard_app Busybox applet during startup

  2. kcard_app registers a SIGUSR1 handler and gives its PID to the SDHC driver by sending an ioctl to /dev/ka-main

  3. When the SIGUSR1 handler is triggered by the driver, it requests a command from /dev/ka-main using another ioctl

  4. The kcard_* applets then do a lot of extraneous stuff (checking for control images) using hardcoded system calls (yuck!) and remount /mnt/sd a few times

I wrote a wrapper for the ioctl syscall so I could interact with /dev/ka-main from a shell script (source below). Here's a compiled version for those who don't have a cross-compiler set up. I'm not great at C, so please don't laugh at me too hard. Just drop it in /sbin.
I then wrote a shell script to perform the minimum necessary functions of the kcard_* applets, namely remounting /mnt/sd when instructed by the SDHC driver. There are a bunch of undocumented ioctls I found in their Busybox source too. Save it as /usr/bin/kcard_handler.
Finally, I wrote a new rcS by tracing through the existing one, removing extraneous crap (logging, wifi, http) and re-ordering parts, shaving the boot time down to 6.5 seconds. This script forks my custom kcard_handler if it exists.

The source code for all of the above can be found here:
For the super-lazy, an initramfs.gz with my changes applied can be found here. You'll have to start wifi/telnetd from if you haven't soldered a serial cable to the card.

From testing with my camera and computer, the SDHC driver appears to only care about updates to the DCIM folder, not the entire filesystem, partition or block device. Writing to the card with my computer makes it choke on failed reads when remounting, so I may be doing something wrong.
This is all the progress I think I can make until Transcend/KeyASIC decides to release the source for /lib/ka2000-sdhc.ko.
Hopefully this ends up helping people, especially the guy working on a builtroot config to replace the initramfs. I look forward to viewing your progress!

Now, I have some questions of my own:

  1. Has anyone had success using fakeroot as a normal user to unpack/repack the initramfs?

  2. Does anyone feel brave enough to start fuzzing for new ioctls? Both /dev/ka-pwm and /dev/ka-pwm1 are undocumented.

(Last edited by kcard on 2 Oct 2013, 03:19)

kcard: that kcard handler you wrote will be useful. I have cross-compiling working, and I'm learning my way around buildroot enough to customize the rootfs. As soon as my initramfs boots, I'll put up a repo with my work.

Ideally, any original code in my initramfs should either be in ash or lua. The idea here being that users can audit and contribute to the code without worrying about a cross-compile environment. Lua has a decent posix lib, so I might just take what you've done and port it to lua.

In my rootfs, I intend on using the writable 1M partition for a lot of user configurable stuff. This includes conf for hostapd, busybox httpd, telnet, ftp and dropbear ssh, as well as the ability to add new init scripts. Since you will be able to configure httpd, you'll also be able to keep lua scripts in the writable partition that are run as CGIs. (Interestingly, my PQI Air Card has a 1.8MB writable partition)

I hope to have lua libs for google drive, dropbox, and on the device. It will also have dropbear (ssh) and rsync binaries on it. There will be lots of ways to get your files off of the internal SD card.

At the rate I'm going (slowly, with family and a full-time job), it might be done early next week.

kcard: it seems that /dev/ka-pwm and ka-pwm1 are intended to control speakers. See busybox-1.20.2_KA/kcard/buzzer.c in the kcard busybox source. It seems that pwm stands for pulse-width modulation in this case. It looks like buzzer.c makes it pretty clear how to use this device node, however this is most likely an unused feature of the chipset that these cards are based on. We don't have speakers, and might not even have a place to wire one up.

The buzzer is used during the development time for debug purpose, but our consumer version don't feature any.
It may be available through a test point but I never really looked for it.

dankrause wrote:


Ah, I knew I had overlooked something. Thanks for informing me.

dankrause wrote:

(Interestingly, my PQI Air Card has a 1.8MB writable partition)

Huh, mine is 1.5 MiB. Is it because I'm using Dmitry Grinberg's kernel? I thought it was supposed to be 1 MiB (size of mtd_jffs2.bin), leaving the remaining 1 MiB for NOR provisioning.

dankrause wrote:

Ideally, any original code in my initramfs should either be in ash or lua.

I've always held the opinion that this is the "right way" to do it, especially for embedded systems. Any task requiring something more complicated than ash should be performed in a lightweight and easily understandable scripting language. Some people would choose Perl, but I think Lua fits those specifications much better.

pixelk: Thanks, that should help!

dankrause wrote:

Looks like it's available on the Flucard.

And now you forced me to buy one ! Are you proud of you ? ARE YOU PROUD OF YOU ?


So far, my initramfs is built with the following features:

  • A fully featured busybox (with some things removed that don't apply to these cards)

  • lua and a handful of libs for it (cgi, posix, etc.)

  • rsync

  • dropbear

  • dhcpd

  • iptables

  • dtach (I want to get dvtm as well, to complement this, but I have to add it to buildroot first)

  • hostapd

I'm currently playing around with everything in /etc to get it booting properly and using /mnt/mtd for any conf a user would be interested in.

The total size of my initramfs image is currently 2.1MB. It'll get a bit bigger before I'm done, but there will still be some breathing room.

I am also running into an interesting problem with hostapd. I can't get buildroot to spit out a build of it that works on my PQI Air Card. Luckily for me, the build of hostapd that comes with the stock firmware is statically linked, and I'm just injecting that instead of building it. I could trim off 200KB or so with a dynamically linked hostapd that I build myself though. When I get all this in a repo, maybe someone will figure that out.

Edit for formatting and clarity.

(Last edited by dankrause on 3 Oct 2013, 02:13)

Could you include a ftp of sftp server in the package (even if not started by default) ?
A lightweight http server supporting cgi would be a nice touch too.

busybox comes with the following services:

  • httpd

  • telnetd

  • ftpd

  • inetd

  • tcpsvd

  • udpsvd

  • udhcpd

  • dnsd

  • tftpd

  • ntpd

They're all included in my rootfs, and I'm currently working to make sure they can all be configured without rebuilding initramfs3.gz


great work. Could anybody point towards how to set up the card as a WiFi client to an existing network/AP rather than acting as an AP of its own.

Thanks in advance.

So I've built my initramfs3.gz replacement, and my PQI AirCard boots. Unfortunately, wifi doesn't come up. Troubleshooting that is a pain in the ass without a serial console. I don't have the equipment to get access to the hardware console at the moment. I'm still working on the wifi issue though, it'll just take a while. I'm sure it's something simple that I just can't see without a console. I'm troubleshooting by adding a ton of logging to my init scripts.

In addition to that, I might actually be able to get buildroot to build a usable kernel, using Dmitry Grinberg's kernel patch. It will essentially be the same kernel as the one he released, but you'll be able to re-build it with different options using the same buildroot setup that builds the initramfs.

As long as I can get past the wifi issue, it's still looking like it'll be ready early next week.

Edit: typo

(Last edited by dankrause on 4 Oct 2013, 19:53)

It can be done, we have the technology !

(sorry for the piss poor picture quality, I don't have space for the soldering gear AND the DSLR tripod)
ground soldered, still 2 to go
those two are very close, but with the apropriate gear it's not that difficult
Everything fits \o/

The card is done and glued together (and still works wink ), it only remains for me to solder the Serial to USB board and voilà !

(Last edited by pixelk on 5 Oct 2013, 18:16)

That ultrastick looks like it's just an sdio 3g card. There's no reason to believe that it has an OS at all, let alone a hackable linux/busybox system. However, a 3g variant of these keyasic-based cards would be awesome.

(Last edited by dankrause on 7 Oct 2013, 20:07)

So I'm still stuck on a wifi-related issue. Thanks to pixelk, I have a modified PQI Air Card with console access on the way. I've temporarily stopped work on this until the card arrives, because I'm not making any real progress.

I was just reading that article. What I personally think is that he'd be better served by wiring the serial tx and rx to pins 8 and 9 (unused) of the SD card. That would be a lot less hacky than passing commands through the SD storage.

When you are soldering things on with a microscope and accidentally rip a trace off, you start to look for better solutions.  Also, there is already a terminal running on that port.

Besides, hopefully people are going to improve the interface there, possibly support some of the RAM-based or other non-flash mechanisms to communicate outside.

Yeah, I agree that the pads are tough to work with - I wouldn't attempt it myself. It would be nice to get access to that serial port without some wires dangling out. Disabling the terminal on that port is trivial, especially when you build your own userland. I'm working on doing that from scratch with buildroot right now.

It would also be pretty interesting to reverse engineer the SDHC hardware in there, and have a modified kernel module for it. You'd have your AVR abusing the SPI bus to communicate with the host. I doubt someone will the skill do accomplish that would be interested enough in this little wifi sd card to actually go through with it though.

Cnlohr, I see that your board uses a ATMega168. Would it be possible to port your code to arduino ? I lack the expertise in AVR programming to do so myself. It would unleash this beast for a LOT of people (anybody can get an arduino and a SD Shield).

I do think it would be possible to use the 1-bit mode, if 1-bit support was added to the kernel driver, I do not expect SPI mode to be supportable at all since it appears to be electrically incompatible with the host:  (The area that's in the middle is the card yelling back at me on the MOSI line)

Regarding an SD Shield on an arduino... If 1-bit mode could be supported by a driver, then it is feasible, however, as of now, it does not appear to be the case.

It would take a custom shield, and a custom module for an arduino at this point... I don't actually own an arduino or the pins to make something I make become a shield sad.   I have never worked with arduinos, the build environment was too clunky when I played with my friend's.  But, if people want it, I would consider trying to figure out how all that works to make a 4-bit SD bus compatible arduino library...

The arduino build environment hasn't changed much. It's a bane for experienced avr programmer as much as a strength for noobs like me. In my opinion the best solution would be to port your 4-bit protocol implementation to an arduino lib.
If you see any way I could help you in this project please do tell me.