Friday, July 31, 2009

SHOWSTOPPER

I have minor good news: both the network over USB and FTP server work fine.

And here are the bad news: there is a data corruption problem when writing to the miniSD in linux. Some users had reported filesystem corruption but seemed to be a minority and I suspected could be a compatibilidy problem in a certain type/brand of card.

This is a fscking showstopper and has become right now #1 in the priority list. The only workaround as of now is to NOT WRITE AT ALL to the miniSD. I know this means states cannot be saved (brightness, volume, game states, etc) since there is right now no safe place to store them.

I will dedicate all efforts to identify the problem and fix it as soon as possible, but this is likely to take some time since the error is not deterministic nor predictable.

If you want to check it out yourself, run in your A320 the following commands:

cd /boot
dd if=/dev/urandom bs=1M count=100 | tee test1.bin | md5sum
md5sum test1.bin
cp test1.bin test2.bin
md5sum test2.bin

The three calculated MD5 sums should be equal (the first one is calculated from the pseudorandom data as it comes out of /dev/urandom, the second one is calculated from the same data stored in file test1.bin, and the third is caculated from file test2.bin which is a copy of test1.bin.

The corruption seems to happen on writing. Reading is ok, which you can test yourself by calculating the MD5 sum of a large file many times. All will yield the same value, whereas whenever you copy the data to a new file the MD5 sum will change.

NOTE that this is not filesystem related, i.e. happens in the FAT and ext2/ext3 releases.

Timidity patch set

Robert2098 cleverly pointed out that a patch set is necessary for MIDI music in some games (those that use SDL_mixer, actually). Since SDL_mixer is part of the rootfs, I think that the patch set must be included too.

However, when I was just about to use the set found at the SDL_mixer page, I noticed that there is also the freepat project, which is the patch set included in my Ubuntu 9.04 desktop.

So, a question for those knowledgeable in the matter: which patch set should I include? (the one available in the SDL_mixer page is about 18M while freepat is about 33M... smaller is better given the limited amount of memory in the A320).

On a side note, I added support for partitionless cards. Not sure if it's really a good idea to allow two different card layouts. Will go out in the next release (which will include dual-boot and system, since changes in both were required). Bastian linked to a patch for u-boot so I thought it would be relatively easy to fix, but turned out not to work, but at that time I was already into it and ended up with my own working fix. Had to modify also the initramfs embedded in the kernel because it must now try two different devices as boot partition: mmcblk0 (partitionless cards) and mmcblk0p1 (partitioned cards).

Thursday, July 30, 2009

WARNING: FTP server may be broken (UPDATED)

Right after I got ethernet working in PIO mode, I made some transfers using FTP and just noticed that large files get corrupted. I cannot tell for sure that the problem is in FTP but it is the main suspect as transfer of same file using netcat resulted in no corruption.

I'll fix it ASAP, meanwhile, stick to using the original firmware to transfer files.

UPDATE: good news is that network and FTP server are both ok, very bad news is that corruption happens when writing to miniSD. See this post.

Ethernet over USB problem fixed (workaround, actually)

I've been digging into the USB ethernet problem. As I announced, I proceeded by elimination: backported all fixes (which turned out to be minor) to the ethernet gadget from recent kernels in order to see if the problem was there, and it wasn't (as expected anyway, just had to narrow the search). In the process I backported also fixes to the serial gadget, just for fun :-).

So the problem is in the Ingenic USB device code (driver/usb/gadget/jz4740_udc.c). After some serious testing I've found out that it is a DMA related problem. As I've said countless times I'm learning on the go and only know the basics of DMA, so I'll need some serious time to trace down and squash this bug.

Meanwhile, the driver has an option to disable DMA and use PIO (programmed I/O). It's slower (16Mbps versus 40Mbps in my setup) but seems to work consistently.

I've uploaded a new release with just this change, so ethernet is actually usable to transfer files and debug applications. Get it here. The rootfs has not changed, so you just need to copy the appropriate zImage for your LCD type.

Now, on a totally different matter, Bastian has pointed out one possible cause of dingux system installation not working for some people: you need a card with partitions. Some cards come with a filesystem starting right on the first block without a partition table. Your OS of choice deals with it but u-boot (that you flashed in your A320 when you installed dual-boot and who is in charge of loading zImage from the miniSD) seems to get confused if he can't find a partition table.

So, make sure you card is formatted FAT32 and has a partition table.

Wednesday, July 29, 2009

MP4nation sucks

I placed an order for a Gemei x760+ more than a month ago. When the order was placed the x760+ was shown as in stock (otherwise I would have sourced it from somewhere else). I opened a ticked ten days ago and they answered that it would be shipping in a couple of days. My order still shows as "processing" and I've opened another ticket asking for immediate shipment or refund.

I'm sorry for those that donated to purchase the x760+ and get Dingux support for it, but this is way out of my control. If I end up getting and refund, can you suggest a trustworthy place to order?.

Tuesday, July 28, 2009

(Yet another) release of system and toolchain

As usual, get them from here.

Summary of changes for system:
  • Enabled joystick support in SDL but forcing the dummy driver.
  • Minor fix in automatic subdirectory creation in /usr/local.
Summary of changes for toolchain:
  • Properly installed vorbis integer decoding library (Tremor) (hope so, untested).
  • Enabled joystick support in SDL but forcing the dummy driver.
Enabling SDL joystick support allows easier porting of applications that won't compile unless it is enabled (but they'll work perfectly if there is actually no joystick). Forcing the dummy joystick driver code minimizes the "fat" (=unecessary and unused code) added to the library.

Monday, July 27, 2009

Baffling dual-boot bug

There's one dual-boot bug that keeps me utterly baffled. I'm not sure if this is happening to others beside me because it involves the serial console connection. I'll describe it here with the dual purpose of confirming that it happens to others and requesting suggestions:

1- Install dual boot.
2- Plug the USB cable (either connected to a PC or just to the wall charger).
3- Reset the device while holding SELECT pressed.

The SPL dingux splash screen appears but it does not boot dingux, just hangs there. If you perform the same procedure but without the USB cable connected dual boot works file.

So what's so baffling and why didn't I notice this before?

It boots fine if the serial console cable is connected. And that's the cable one needs to see what's going on during the boot process. So if I connect it the problem dissapears, and if I don't connect it I can't see what's going on.

Question is: does this happen too to those that haven't installed the serial console?.

It may be that the SPL code fails to load u-boot, or that the u-boot code fails to load zImage. One could think that maybe the u-boot code is receiving some stray input from the unconnected serial console and stopping to wait for more input, but then, why does this happen only when the USB power is plugged?.

Looks like the only way to investigate this is to modify the SPL and u-boot sources to output debug stuff to screen.

UPDATE 1: just don't know why I didn't think of it before. I just connected the serial console AFTER the boot hangs and confirmed that u-boot has received some garbage input and is sitting there like a stupid waiting for further instructions. I'm not sure how the USB power applied is causing this garbage in the serial input when it's undriven, but that is definitely what's happening. The fix should be dead easy: modify u-boot to completely ignore any input.

UPDATE 2: fixed, should go in the next dual-boot release. Unless people reports this is causing problems, I'll wait until I make some other pending changes into the dual boot to make the release.

Sunday, July 26, 2009

On screen tearing

The final display device, your LCD, works at a fixed frequency which results in a certain refresh rate. Think of it as the screen being "painted" a lot of times per seconds. The "painting" of the screen is an standalone process that is performed by a chip on the LCD itself from its own memory. Think of what would happen if you change the memory contents while the screen is being painted. The only way to do this is to have some kind of syncronization signal from the LCD chip. That way, you wait until the right moment and update the memory contens while they are not being used.

Now think that things are even more complex: actually there are at least three processes and three memory buffers involved: an application normally has an internal buffer where it writes a whole screen before sending it to display. Then the framebuffer driver in the linux kernel has another buffer where contents sent by the application are stored, and finally there is the already mentioned LCD internal buffer. Transfers from one buffer to the next must all be synchronized somehow to the screen painting in order to avoid the tearing effect.

Now for the bad news: I'm yet to confirm it, but the A320 hardware design is... well, let's say it's not the best I've seen. I believe there is no way to read the "repaint" status of the LCD or get a synchronization signal which would allow the linux kernel framebuffer driver to transfer contents to the LCD memory in a way that would not cause some tearing. The LCD controller has registers that expose this information, but they cannot be read because the R/W signal is just not connected to the display. The CPU has a dedicated R/W signal for the LCD but the designers ignored it and just left the LCD stuck in write mode. You can write the registers but you cannot read them. This is also the cause of the impossibility of autodetecting the LCD type: again, both known LCD types have specific registers to identify the model, but we just can't read them !!!. There are some other blatant design mistakes for which they had to implement a workaround, but they are not related to tearing.

It is a shame: LCD synchronization is perfectly possible but they seem to have taken all steps to make it impossible. There might be a very twisted way to somewhat achieve synchronization, but I'm yet to investigate it.

Anyway, you may be wondering: why do some games/emulators show tearing in the original firmware and not in dingux or just the opposite?. It has to do with frequency mixing. The math behind it is far from simple, but it can be summarized this way: when you mix two frequencies you obtain both the sum and the substraction. If the framebuffer driver is refreshing the LCD at 70Hz and the LCD is refreshing the pixels at 50Hz you get both 20Hz and 120Hz. In this case you won't probably see any tearing because both frequencies are high enough, but now think what would happen if an application happens to refresh the framebuffer at 55Hz. You get 5Hz and 105Hz, and you bet the 5Hz are pretty visible.

Now think that as I said earlier, there are at least three processes/buffers involved and that each one works at its own frequency.

We can program the LCD refresh rate. We can set it higher or lower, it doesn't matter. What matters is its relation to the refresh rate of the application that is using the screen at a given time, and that, of course, changes from one application to another.

I'll keep on investigating about the whole LCD subsystem and find a way to mitigate the tearing effect, but bear in mind that with current hardware it might be impossible. Note also that as a last resort the LCD refresh rate could be changed in a per-application basis to minimize the tearing in each case.

System and toolchain updated

As usual, get it from the google code page download section (still uploading at the time of writing this post, so maybe you'll have to wait a bit, my upstream here is tiny).

ChangeLog (for the system):
  • Backported from kernel 2.6.24.6 fix for usb ethernet gadget. Now Windows RNDIS driver works (but ethernet communication is still broken and will fail a few seconds after starting and high bandwidth transfer via FTP).
  • Patched SDL so SDL_NOMOUSE=1 is no longer necessary.
  • Updated to busybox-1.14.2 + current patches.
  • Added symlink /etc/TZ ---> /usr/local/etc/timezone
  • Automatic creation of default subdirectories in /usr/local.
  • Automatic creation of default /usr/local/etc/timezone.
The only differences in the toolchain is that the I changed the owner to root before packing (the first release was owned by my user) and that the included SDL library also no longer needs SDL_NOMOUSE, but since this is only a problem when running in the A320 itself, if your application is dynamically linked you probably don't need to download the new toolchain.

I intended to fix the HOME=/ problem. Actually that default value is set by init, so the only way to change it was changing the init code which I felt was not the right thing to do. So the workaround of using a shell script as /usr/local/sbin/main and setting HOME=/usr/local/home there is still necessary. If you want to save some memory, remember to use "exec" to execute your menu application, because if you just call your executable you'll leave a whole shell sitting in memory and doing nothing but waiting for your process to exit.

Thursday, July 23, 2009

Battery charge/discharge graphs

batman52 took the trouble of sampling the battery voltage both during the discharge and charge cycles. This is what it looks like:


This should help setting the battery status thresholds. It has also helped identifying the GPIO pin used to sense the battery charge status provided by the not-yet-identified power management integrated circuit. Though this information is yet to be verified, I've updated the GPIO mapping tables.

You probably know already that you can read the battery voltage from /proc/jz/battery (in millivols). You can also read the GPIO pin status from gpio[0-3]_pxpin files in the same directory. Do not mess around with the other gpio[0-3]_* files since you could damage your hardware.

Tuesday, July 21, 2009

USB ethernet is broken

As many of you have reported, the USB ethernet gadget device didnot work with Windows. This is due to a kernel bug which was fixed in 2.6.24.6 (thanks to mofive for pointing this out). I've backported the trivial fix and now the A320 is detected as network device and the drivers seem to work with Windows at a first glance.

However, something else is badly broken: if you start a file transfer (from the A320 to the PC to keep the flash write delay out of the measurement) you'll see a high sustained throutput for a few seconds (about 40Mbit/s), and then the link crashes. In linux the link recovers after a delay, in windows the crash is permanent until you unplug and plug again the USB cable.

(note: iperf is available in the rootfs, you can use it to test transfer without using FTP)

The bug may be in the ethernet gadget code itself or in the JZ4740 USB driver code. I've traced the evolution of the ethernet gadget code through all subsequent kernel versions and there seem to be some fixes I could use. I intend to first try to backport these fixes and see it this solves the problem. If it does not, I'll then look to the JZ4740 USB driver code.

I will be releasing a new rootfs/toolchain tomorrow which will include the mentioned USB ethernet gadget fix to work with windows (but remember, it is broken anyway) and a modified SDL library that no longer requires "export SDL_NOMOUSE=1".

Monday, July 20, 2009

System installation pack and toolchain released

Big news. Grab both from the google code download section here.

The installation pack includes the kernel images and a root filesystem in ROMFS format. You just need to place both in the root directory of the first (and most likely only) FAT partition of your miniSD card. No need for ext2/ext3 any longer, which should make Windoze users quite happy.

Another big improvement is console and file transfer. As soon as linux boots your PC will detect a new network card and it will be assigned a network address (by a DHCP server in your A320). Telnet to 10.1.0.2 to get console access, FTP to 10.1.0.2 to transfer files.

Enabling networking in the kernel adds enlarges it noticeably, but this is compensated by the removal of ext2/ext3, which is not longer needed and is quite heavy too.

Dingux will try to run the file "local/sbin/main" in your miniSD on startup, and if it exits it will respawn it. Get your menu application of choice, rename it as "main" and place it in "local/sbin" to get it running on startup.

To system menu application developers, I'd advice to use the exec call to launch other applications. The launched application will replace yours in memory (so the menu won't be sitting silently in the background waiting for the application to end and using precious RAM), and when it exits your menu will be launched again.

I've tried to include as many libraries as possible in the root filesystem. If you need some library not included, link it statically as a temporary solution and email me: I'll try to include it in the next release.

You should notice an important boot speed improvement. The initialization sequence has been optimized in many ways, but the post noticeable is the active monitoring of the miniSD detection. Now the system waits just as long as needed until the miniSD block devices are created, while before there was a fixed delay of one second (the rootdelay kernel parameter was used and the minimum value you can set is one second).

UPDATE: note that existing applications do not work on this new root filesystem. They will have to be recompiled using the new toolchain. I bet developers will catch up quickly.

14528 problems (7 errors, 14521 warnings)

Yeah. Don't know what I'm doning wrong, but I'm leaving java (classpath) out of the rootfs for now. Ezelkov1 kindly provided a patch to get classpatch compiling but it does not seem to work for me, and I just don't have the time to search through 14528 "problems".

Wednesday, July 15, 2009

New A320 arrived

Today I went back home and picked up the package from Hong Kong. It's the A320 I purchased (with your generous donations, thanks againg), and it's got, as expected, the newer ILI9331 LCD controller.

I'll be dissecting it and adding the serial console connector tomorrow. As I did with the first A320, I'll shot a lot of photos and post a report.

For you guys waiting for the gemei x760+ support, I am sorry to report that I've checked with MP4nation and my order is still "processing". Hasn't even been shipped!!!. I just opened a ticket, let's see how is their customer support.

UPDATE: got reply from MP4nation:

I am sorry for the delay and the inconvenience caused, the item (or items) you had ordered became backordered. However it is now back in stock and your order is to be processed and sent within the next 2 working days.

Again we are sorry for the inconvenience caused.


So, assuming they finally ship it in a couple of days, and knowing how snail mail works here, I don't expect to be able to start working on the Gemei x760+ until first or second week of august. Sorry.

Sunday, July 12, 2009

WIP

Work in progress... miscellaneous updates in no particular order:

My neighbour told me that something has (finally!) arrived from Hong Kong. I may be the newer LCD A320 or the Gemei x760+. I'm living in a different place this month (you know: wife and kids, holidays, beach...), and won't be able to pick it up until next week.

I've just fixed the ethernet over usb. Next kernel/rootfs release will communicate only via ethernet: telnet for console (developers) and FTP for file transfer. This is how it works:
  1. A320 boots, sets up the usb0 interface (192.168.110.2) and launches DHCP, telnet and FTP daemons. The default gateway is set to 192.168.110.1.
  2. PC detects a new USB ethernet adapter plugged and gets an address via DHCP. It is assigned 192.168.110.1 by the DHCP server in the A320.
  3. Since the PC is the default gateway, if you configure routing you can get internet access from the A320.
I think I have now a quite complete uclibc based toolchain and rootfs. I'm still working in a FAT-only rootfs, which should be ready for release sometime next week.

I've included all the SDL stuff except SGE, because it doesn't use autotools and the included makefile is not cross-compile ready. I could not compile Allegro either: looks like it's too bound to i386 architectures. If you can port it, I'll be glad to include it in the next kernel/rootfs release.

Wednesday, July 8, 2009

Call for system library requests

I've been recenly using an uclibc toolchain and polishing a minimal rootfs (not the quick hack I released with the first working kernel). This setup won't need an ext2/ext3 partition, just a couple of files you'll have to place in your existing miniSD FAT parition.

This, however, comes at a price: the root filesystem is readonly (romfs... we have plenty of space, no need to lose microseconds decompressing cramfs or squashfs). This means you cannot install anything in the root filesystem, and will have to use the FAT partition. This is OK for almost everything but for system libraries, because they use symbolic links which cannot be created on a FAT filesystem. There are ways to achieve this (comments on this later), but none is simple and certainly not for the first release.

So I intend to release what might become the reference rootfs and development kit, and as such, I would like it to include all the required libraries for applications. So far it includes most of the general purpose libraries that buildroot allows to install plus SDL and derivatives.

I would like to hear from you, devs that are porting apps to dingux: what libraries are your applications using?.

And finally, some right-off-of-the-top-of-my-head ideas on a way to allow addition of system libraries to a romfs based root filesystem:
  • Allow expansion of the rootfs vía filesystem overlays: unionfs (heavyweigth but high functionality) or mini_fo (lightweight but limited functionality).
  • Mount /usr/local/lib as a tmpfs (i.e. ram disk) and on startup create there symbolic links to extra libraries in the FAT partition. Each extra library would have to come with a special file that would define the symbolic links to be created.
Any other ideas?

Tuesday, July 7, 2009

New kernel binaries

I just compiled and uploaded the latest kernel for ILI9325 and ILI9331 LCD controllers (choose yours).

These are the changes:
  • Battery reading implemented.
  • LCD backlight working.
  • Fixed kernel oops when USB cable unplugged.
The later is a long standing bug. It turns out the USB device controller was calling a non-existent suspend function when the cable was unplugged. One hour chase, one second fix.

On a side note, thanks for your valuable comments and suggestions in the previous post.

Sunday, July 5, 2009

Implementing system controls

I will comment how I have though that the system controls could be implemented, as always, in order to get some feedback both from final users and developers.

I think that the most important limitation of the A320 is its 32MB of RAM, and that is why I think we need a"only one foreground application running" approach for dingux. These would be the sequence of events after rootfs is mounted by the kernel:
  1. /sbin/init is executed
  2. /sbin/init executes the initialization scripts, launching any required daemons.
  3. /sbin/init executes the main system menu application in "respawn" mode. At this point we have the daemons, the init process and the main menu system application running.
  4. When the main system menu application wants to launch an external application, it does it by using the exec call. This means that the process is replaced in memory. At this point we have the daemons, the init process and the external application running.
  5. When the external application finishes, the init process notices and respawns the main system menu application.
This way, we avoid having some MB of memory locked by the main system menu while it's not actually running. This is an approach completely different to the used in desktop systems, where the window manager and desktop applications are "always there" retaining control of the system.

This approach poses a problem: who takes care of the system controls (volume, LCD brightness and such) ?. It cannot be the main menu system application because then we would not be able to change settings while running an emulator or other application.

I've come up with an scheme that I think would do the job:
  • Modify the keyboard kernel driver to appear as two different input devices. All the special key combinations (power+whatever) would be generated by the second input device, and there would be a special mode entered by one of these combinations in which normal keycodes would also be sent to the second input device.
  • Modify the framebuffer kernel driver to appear as two different framebuffer devices. The second framebuffer would be shown (only while it is in open) as a traslucent overlay over the first framebuffer. The traslucency would be done in software and thus would use quite a chunk of CPU power, but this will be ok in the usage scenarios I will describe.
  • Make a system daemon process that will be listening to the event queue of the second input device, and will open and use the second framebuffer whenever it wants to show an overlay screen.
Usage cases:
  • The user presses the "volume up" key combination (power+up), the system daemon opens the second framebuffer device and shows a "volume up" splash screen for a short period.
  • The user presses the "menu" key combination (power+select), the system daemon opens the second framebuffer device and shows a menu where you can terminate the current running application (which would be identified by looking at who is using the first framebuffer), use a virtual keyboard to send keystrokes to the current running application (i.e. generated by the first input device) etc.
The rationale of the CPU intensive traslucency not being important is as follows: if you are using special key combinations to change the volume, you won't mind if the currently running application slows down a little for a short time. If you are using the virtual keyboard, the currently running application will be stopped in an input box dialog, so you won't notice the slowdown.

You may be thinking that the system daemon would be an application "stuck in memory" which defeats the initial purpose of saving memory. The system daemon will have to be implemented as very optimized code in terms of memory usage code, but most importantly, it will have only a reduced and limited set of feattures, while the system menu application can grow as necessary, including lots of eyecandy, an audio player (instead of an external application), etc.

Someone is already working in suck a daemon and my mission is to provide the required kernel space functionality. As usual, I kindly request your comments and suggestions. In particular, I'm learning about some kernel subsystems on the go, so if you have more experience in input and/or framebuffer devices, I'll be specially glad to hear you opinion on the feasibility of this whole approach.

UPDATE: I did a quick check and it seems that all input events from all input devices reach the controlling tty (makes sense because if you plug two keyboards to a linux box you can type from any of them), which means having two input devices is not the right way to divert certain input events to different processes. An easy way to achieve similar functionality would be to use a dedicated char device only known to the system control daemon, from which it would get special keystrokes and "kidnapped" normal keystrokes in menu mode. This would also solve an issue I didn't notice when writing this entry: if we implement a virtual keyboard in userspace, how do we "inject" the resulting virtual keystrokes back in the input subsystem?.

Well, I guess I could just use special keycodes for all operations to be handled by the system control daemon and assume that the current running application will just ignore them. However, I don't think "assuming" is good practice in general...

Battery reading and LCD backlight working

Some updates to the kernel (will try to find some time tomorrow to compile and release new binaries):

I just got battery reading working (thanks tor...@pltn.org). You can get the voltage in millivolts by reading from /proc/jz/battery. At the moment, and until we have some charge/discharge voltage curves, we cannot relate voltage level to battery charge status.

I know that most (if not all) of you are using the serial console over the USB cable to access your A320, and since the kernel panics when unpluging the cable, it is not possible to trace the discharge curve unless one builds an special USB cable without the +5V line. So in the next days I'll work on fixing the cable unplug bug, and then ask for help on tracing the battery charge/discharge curves.

I also got the LCD backlight working. The FBIOSETBACKLIGH ioctl command now works, but I also implemented a procfs interface and since it doesn't require kernel headers (from the userspace developer's point of view), I would strongly advice to use it instead of ioctls.

Just read/write a value between 0 and 100 to /proc/jz/lcd_backlight. As a refinement I might add a linearization table (the apparent brightness increase is much larger from 0 to 10 than from 90 to 100).

Finally, a couple of notes about the keyboard mapping:
  1. I replaced KEY_KEYBOARD by KEY_MENU (power+select). This keycode is intended to bring up an overlay screen which might include a virtual keyboard, but which will certainly include more functions (volume, brightness, process control, etc). So makes a little more sense to use MENU than KEYBOARD:
  2. I added the KEY_EXIT keycode (power+left shoulder). It is intended to kill the "foreground" application, that is, the one using the framebuffer.
Note: when I say "intended" I mean that an userspace daemon will be needed that will capture those keycodes, bring up the overlay screen, etc.

Thursday, July 2, 2009

Look ma, net, no wires

batman52 made an interesting comment in the previous post: WiFi.

Indeed, much to my surprise there are miniSDIO WiFi cards on the market. The JZ4740 docs says that the SD/MMC controller supports SDIO, so in theory it should be possible to add WiFi to the A320.

Of course this is a long shot and there are much more important things yet to get working, but just imagine the possibilities... I just have to give it a try. I think it is worth investing some of the donated money in purchasing one of these cards. What do you think?.

Request for comments on file transfer

As some of you have already noticed, all the networking stuff is disabled in my binary kernel image releases. This is because the A320 is not a networked device and as such in principle it doesnot make much sense to waste precious memory. Note that module loading is also disabled for the same reason (static hardware, reduces kernel memory usage). I'll later explain why all this is relevant.

File transfer is not yet enabled in the released kernels. The reasons for this are:
  • The storage device gadget driver (which would be the "standard way") is not tested yet.
  • The storage device gadget driver accesses the storage as raw block devices, and thus requires exclusive access to them. In other words: the filesystem is mounted by the host PC. This is why you can see the ext2/ext3 partition from a linux PC despite the fact that the original firmware does not support it.
  • Having a serial console is a MUST for application developers. This is provided by the serial gadget driver, which is enabled now (and has a hideous bug that crashes the kernel when unplugging the USB cable).
  • You can't use more than one gadget device simultaneously in the 2.6.24.3 kernel. Though I think this is solved in recent kernels by implementing composite gadget devices, backporting it to the 2.6.24.3 kernel is a huge task, and even if that is achieved, the composite device we would need (serial + storage) is not implemented yet even in the latest kernel.
To summarize: we need the serial console and it is not usable together with the storage gadget function. The obvious way to solve this is backporting composite gadget device support from recent kernels and coding a new serial + storage device.

I can think of several ther alternative ways to get what we need:
  1. Using a serial file transfer protocol over the serial gadget. This is rather inconvenient and definitely not for the end user. I know next to nothing about OBEX, but I'm given to understand that it can work also over a serial line. Maybe its usage would be simpler that a classic protocols for the end user.
  2. Module loading/unloading of the serial and storage gadget devices. This requires enabling module loading (which enlarges the kernel), is cumbersome to implement, and probably requires fixing first the above mentioned unplug bug.
  3. Establishing a network connection, either by using the ethernet gadget device or by using SLIP over the serial gadget (the first would be easier). Once the network connection is established you can telnet to get console access and you can transfer files via FTP or SCP. This requires enabling the kernel and user space networking stuff, and would probably be a bit inconvenient for the end user, since it would require to configure the gadget network card.
My guess is that backporting + coding a new composite USB device is the way to go. It's a fairly large task and requires good knowledge of the kernel USB stuff (which I don't have). It would take time, but I guess this is acceptable since right now we have a working way to transfer files.

All your comments and suggestions are welcome.

Wednesday, July 1, 2009

Porting a menu frontend

I got a little time to check out frontend menu systems for the A320. As always, the way to go is reuse existing open source software, and I came up with two candidates: gmenu2x and gp2xmb. If you know some other, please let me know.

You may recall that one of the first quick ports I did when I got linux running on the A320 was gmenu2x. I did that using the huge glibc and other stuff from the Ingenic toolchain, but this time I wanted to do it the right way: using an uclibc toolchain.

I quickly went over OpenEmbedded and settled with buildroot. It's the tool by the uclibc guys and has a nice kernel like configure menu to which I'm used. I succesfully built the toolchain, and I recommend using buildroot for compiling just the toolchain and some basic libraries. For bigger or specialized libraries (like SDL), I recommend configuring and building manually using the just built toolchain. I'll be testing this toolchain in the following days and release a new uclibc based rootfs.

These are the porting results:
  • gmenu2x: unable to get the latest stable version working in linux nor in the A320. The svn code compiled and sort of worked both in linux and in the A320 but despite the icons seems to be loaded they're not shown on screen. Didn't go any further because I do not intend to debug the gmenu2x code.
  • gp2xmb: got the svn code working almos right from the start, both in linux and in the A320. The sound is choppy in both cases, which leads me to believe it's not a problem of the kernel sound driver (reminder: still using the buggy and ugly OSS driver).
Personally I prefer gp2xmb. There's quite a lot of work to be done to adapt to the A320 (plus the sound problem), but the code seems quite clean and well structured. Check out the video:

Note: it should be only the second half, but for some reasong I could not edit it without breaking further the audio sync (in which you can notice it's choppy), sorry. You see how I reset dingux using POWER+START+SELECT, boot into the original firmware, power off, power on and get a bit too late to select dingux thus booting again into original firmware, etc. Notice that in the latest dual-boot release you can press SELECT to boot dingux anytime while the dingux splash screen is show, that is, you actually need not to power on while pressing SELECT.