Saturday, April 28, 2018

Revogi Smart Power Strip SOW323 , part two

After messing with the telnet interface for a bit, I managed to brick the device to the point it couldn't connect to the WiFi. Since I previously dumped the content of the SPI NOR, the obvious solution was to crack the device open and see what's inside.

It turns out there's no UART, no usable USB (the port is charge-only), no JTAG. But the SPI NOR is a nice SOIC8 chip, so let's pull it out. To make further experimentation possible, I wirebonded a DIP8 socket onto where the SOIC8 was and placed the SPI NOR itself onto a protoboard with DIP8 compatible footprint.

By using a SPI NOR programmer, I was able to reprogram the flash back with a working system image and the device boots again, great!

But looking at the cables coming out of the mainboard, there are two 4pin connectors on the board, white and black. You can see them between the USB port and the yellow transformer brick.

Poking at them with a scope turns, it turns out the top one is UART and the bottom one is just some power sequencing for something.

The UART is routed to a STMicro ARM chip controlling the relays and probably also the touch strip. The UART connector pinout is, top to bottom, CPU-to-STM data, STM-to-CPU data, GND, 3V3.

Using logic analyzer, it is easy to see the protocol. The CPU seems to be polling the STM all the time for what looks like the status of the sockets.

The polling protocol looks really trivial:
CPU sends:
0F 04 05 00 00 06 FF FF
STM replies (sockets off):
0F 04 05 00 00 06 FF FF
0F 04 05 00 00 06 FF FF
CPU sends:
0F 04 05 00 00 06 FF FF
STM replies (socket 1 on):
0F 04 05 00 01 07 FF FF
0F 04 05 00 01 07 FF FF


So presumably, byte 4 indicates socket status. Since byte 0, 0x0f, is in all frames, this is likely some preamble. Same for trailing byte 6 and 7, 0xff, is likely some end of frame indicator. Bytes 1, 2, 3 are likely some command field, while byte 5 might be a checksum of sorts.

Now, to make fiddling with the system easier, I figured how to stop the "switch" process which is hogging the ttyS0. Just replace /bin/switch with /bin/sh in /etc/inittab. I'm not convinced this is the right solution, but it does it's job. After a reboot, /dev/ttyS0 is available, so let's try sending the same poll command:

# /tmp/busybox stty -F /dev/ttyS0
speed 4800 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ;
swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O;
min = 1; time = 0;
-brkint -icrnl -imaxbel
-opost
-isig -icanon -iexten -echo


# /tmp/busybox hexdump -vC /dev/ttyS0 &

# /tmp/busybox echo -en '\x0f\x04\x05\x00\x00\x06\xff\xff' > /dev/ttyS0
# 00000050  0f 04 05 00 00 06 ff ff  0f 04 05 00 00 06 ff ff  |................|

The reply looks sensible, great! Now we can talk to the socket without needing the proprietary application. Further protocol analysis will be needed.

Friday, April 27, 2018

Revogi Smart Power Strip SOW323 IoT Security apocalypse

I started looking for a replacement for my trusty Gembird Silvershield USB-controlled 4-socket power plug, after some searching I discovered the Revogi Smart Power Strip SOW323. The device looks awesome, 6 controlled sockets, ethernet plug, power consumption monitoring, ~100EUR, just what I need! So I bought one and started looking around ...

The system security is state of the art, as one would expect from an IoT device.
# telnet 10.77.1.2
Trying 10.77.1.2...
Connected to 10.77.1.2.
Escape character is '^]'.
rlx-linux login: root
RLX Linux version 2.0
         _           _  _
        | |         | ||_|                
   _  _ | | _  _    | | _ ____  _   _  _  _
  | |/ || |\ \/ /   | || |  _ \| | | |\ \/ /
  | |_/ | |/    \   | || | | | | |_| |/    \
  |_|   |_|\_/\_/   |_||_|_| |_|\____|\_/\_/

For further information check:
http://processor.realtek.com/
#
Login is "root", the system doesn't even ask for password.

Sadly, the system is really cut down, most likely for security reasons, so it doesn't offer many useful commands:
#
arp        chmod      egrep      insmod     killall    modprobe   reboot     tar        vi
arping     cp         free       ip         ledbtn     mount      rm         telnetd
ash        cut        grep       iwconfig   ln         mv         rmmod      tftp
brctl      date       halt       iwcontrol  login      netstat    route      touch
busybox    depmod     hostname   iwlist     ls         ping       routed     udhcpc
cat        df         ifconfig   iwpriv     lsmod      poweroff   sh         udhcpd
cfg        echo       init       kill       mkdir      ps         switch     umount
But that's fine, there's the "tftp" command, so let's see:
# tftp -g -r /srv/tftp/test -l /tmp/test 10.0.0.1
# ls /tmp/test
/tmp/test
The syntax is a bit odd, but -g means "get", "-l" means local, "-r" means remote. The busybox version is 1.13.6 or so and oddly cut down. But this looks good, we can download files onto the Smart Power Strip.

Let's compile busybox with some more useful tools to dump the content of the flash, so we can politely ask vendor the for GPLed sources with a binary in hand.

The system runs RTL819x MIPS, uclibc 0.9.30 and Linux 2.6.30.9:

# cat /proc/cpuinfo
system type             : RTL819x
processor               : 0
cpu model               : 52481
BogoMIPS                : 379.28
hardware watchpoint     : no
tlb_entries             : 32
mips16 implemented      : yes
# ls /lib/ 
ld-uClibc-0.9.30.3.so   libcrypt.so.0           libm.so.0
ld-uClibc.so            libgcc.so               libpthread-0.9.30.3.so
ld-uClibc.so.0          libgcc_s.so             libpthread.so.0
ld.so.1                 libgcc_s.so.1           libuClibc-0.9.30.3.so
libc.so.0               libiw.so.29             modules
libcrypt-0.9.30.3.so    libm-0.9.30.3.so
libcrypt.so             libm.so
# ls /lib/modules/2.6.30.9/
build                modules.dep.bin      modules.pcimap
kernel               modules.ieee1394map  modules.seriomap
modules.alias        modules.inputmap     modules.symbols
modules.alias.bin    modules.isapnpmap    modules.symbols.bin
modules.ccwmap       modules.ofmap        modules.usbmap
modules.dep          modules.order        source
No modern MIPS toolchain would be able to produce binaries for that antique, but luckily there is RLX-linux SDK dump at github (link).

Then it's only a matter of doing a static build of busybox using the oldest SDK in the repo:
PATH=/path/to/rtl819x-toolchain/toolchain/rsdk-1.3.6-4181-EB-2.6.30-0.9.30/bin/:$PATH
export CROSS_COMPILE=mips-linux-
make menuconfig
make
And finally, transfer the static busybox binary to the system:
# tftp -g -r /srv/tftp/busybox -l /tmp/busybox 10.0.0.1
# chmod a+x /tmp/busybox 

# /tmp/busybox         
BusyBox v1.21.0 (2018-04-27 18:51:36 CEST) multi-call binary.

...
Good, replacement busybox with functionality like "netcat" is working. Finally, we can do something like this to pipe the content of flash over the network to a remote system:
cat /dev/mtdblock0 | /tmp/test/busybox nc 10.0.0.1 6666
cat /dev/mtdblock1 | /tmp/test/busybox nc 10.0.0.1 6666
Or back up the rootfs binaries for later analysis
# tar -cf /tmp/root.tar /bin /etc /home /init /lib /mnt /usr /var 
tar: removing leading '/' from member names
tar: /var/tmp/root.tar: file is the archive; skipping
# cat /tmp/root.tar | /tmp/busybox nc 10.0.0.1 6666

I can only finish this article with a famous quote, S in IoT stands for Security.

Friday, June 10, 2011

Toradex Colibri Tegra 2 -- first step

Just a quick post. Thanks to the work of ant micro guys on Toradex Colibri Tegra 250 U-Boot, I was able to use that as a jump start towards Tegra 250 Linux port. I did a very very basic port, the bootlog follows.

I will eventually work on this port more as it seems quite interesting.


U-Boot 2011.03-rc2 (Apr 27 2011 - 21:33:54)

TEGRA2
Board: TORADEX Colibri Tegra2
dynamic ram_size = 268435456
DRAM: 256 MiB
Using default environment

In: serial
Out: serial
Err: serial
Net: Net Initialization Skipped
No ethernet found.
Colibri Tegra2 # usb reset ; setenv serverip 10.0.0.1 ; setenv ipaddr 10.0.0.2 ; setenv netmask 255.255.255.0 ; tftpboot 0x01000000 10.0.0.1:uImage ; bootm 0x01000000
(Re)start USB...
USB: Register 10011 NbrPorts 1
USB EHCI 1.00
scanning bus for devices... 2 USB Device(s) found
scanning bus for storage devices... 0 Storage Device(s) found
scanning bus for ethernet devices... 1 Ethernet Device(s) found
Waiting for Ethernet connection... done.
Using asx0 device
TFTP from server 10.0.0.1; our IP address is 10.0.0.2
Filename 'uImage'.
Load address: 0x1000000
Loading: EHCI timed out on TD - token=0x8008d80
T #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##
done
Bytes transferred = 2336144 (23a590 hex)
## Booting kernel from Legacy Image at 01000000 ...
Image Name: Linux-3.0.0-rc1-08421-g4f2e4c1-d
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2336080 Bytes = 2.2 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 3.0.0-rc1-08421-g4f2e4c1-dirty (root@mashiro) (gcc version 4.4.5 (Debian 4.4.5-8) ) #11 SMP PREEMPT Fri Jun 10 05:18:47 CEST 2011
[ 0.000000] CPU: ARMv7 Processor [411fc090] revision 0 (ARMv7), cr=10c5387f
[ 0.000000] CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine: Toradex Colibri Tegra2
[ 0.000000] Memory policy: ECC disabled, Data cache writealloc
[ 0.000000] Tegra SKU: 8 CPU Process: 0 Core Process: 0
[ 0.000000] L310 cache controller enabled
[ 0.000000] l2x0: 8 ways, CACHE_ID 0x410000c4, AUX_CTRL 0x6e080001, Cache size: 65536 B
[ 0.000000] PERCPU: Embedded 7 pages/cpu @c06ef000 s4960 r8192 d15520 u32768
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024
[ 0.000000] Kernel command line: mem=256M@0x0 console=ttyS0,115200
[ 0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Memory: 256MB = 256MB total
[ 0.000000] Memory: 254776k/254776k available, 7368k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[ 0.000000] DMA : 0xffc00000 - 0xffe00000 ( 2 MB)
[ 0.000000] vmalloc : 0xd0800000 - 0xfe000000 ( 728 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xd0000000 ( 256 MB)
[ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[ 0.000000] .init : 0xc0008000 - 0xc00e3000 ( 876 kB)
[ 0.000000] .text : 0xc00e3000 - 0xc0474ddc (3656 kB)
[ 0.000000] .data : 0xc0476000 - 0xc04a5ce0 ( 192 kB)
[ 0.000000] Preemptible hierarchical RCU implementation.
[ 0.000000] NR_IRQS:416
[ 0.000000] sched_clock: 32 bits at 1000kHz, resolution 1000ns, wraps every 4294967ms
[ 0.005600] Calibrating delay loop... 1987.37 BogoMIPS (lpj=9936896)
[ 0.060049] pid_max: default: 32768 minimum: 301
[ 0.060431] Mount-cache hash table entries: 512
[ 0.061121] Initializing cgroup subsys debug
[ 0.061131] Initializing cgroup subsys cpuacct
[ 0.061157] Initializing cgroup subsys freezer
[ 0.061216] CPU: Testing write buffer coherency: ok
[ 0.061406] Calibrating local timer... 249.49MHz.
[ 0.260476] CPU1: Booted secondary processor
[ 0.320055] Brought up 2 CPUs
[ 0.320064] SMP: Total of 2 processors activated (3981.31 BogoMIPS).
[ 0.325413] print_constraints: dummy:
[ 0.325634] NET: Registered protocol family 16
[ 0.333888] bio: create slab at 0
[ 0.334557] vgaarb: loaded
[ 0.335681] Switching to clocksource timer_us
[ 0.337174] NET: Registered protocol family 2
[ 0.337330] IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.337807] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[ 0.337944] TCP bind hash table entries: 8192 (order: 4, 98304 bytes)
[ 0.338055] TCP: Hash tables configured (established 8192 bind 8192)
[ 0.338063] TCP reno registered
[ 0.338072] UDP hash table entries: 128 (order: 0, 4096 bytes)
[ 0.338167] UDP-Lite hash table entries: 128 (order: 0, 4096 bytes)
[ 0.338532] NET: Registered protocol family 1
[ 0.339113] RPC: Registered named UNIX socket transport module.
[ 0.339121] RPC: Registered udp transport module.
[ 0.339127] RPC: Registered tcp transport module.
[ 0.339133] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.340005] Switched to NOHz mode on CPU #0
[ 0.340479] Switched to NOHz mode on CPU #1
[ 0.799161] io scheduler noop registered (default)
[ 0.799366] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 1.145889] ttyS0: detected caps 00001100 should be 00003100
[ 1.145903] serial8250.0: ttyS0 at MMIO 0x70006000 (irq = 68) is a XScale
[ 1.507896] console [ttyS0] enabled
[ 1.628949] loop: module loaded
[ 1.632324] i2c-core: driver [apds9802als] using legacy suspend method
[ 1.638867] i2c-core: driver [apds9802als] using legacy resume method
[ 1.645365] i2c-core: driver [isl29003] using legacy suspend method
[ 1.651637] i2c-core: driver [isl29003] using legacy resume method
[ 1.658610] sdhci: Secure Digital Host Controller Interface driver
[ 1.664775] sdhci: Copyright(c) Pierre Ossman
[ 1.669576] TCP cubic registered
[ 1.672953] NET: Registered protocol family 10
[ 1.678392] Mobile IPv6
[ 1.680831] IPv6 over IPv4 tunneling driver
[ 1.686364] NET: Registered protocol family 17
[ 1.690824] NET: Registered protocol family 15
[ 1.695255] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 1
[ 1.702955] Registering SWP/SWPB emulation handler
[ 1.713026] Kernel not built with RTC support, ALARM timers will not wake from suspend
[ 1.721309] Freeing init memory: 876K
(II) mounting sysfs to /sys
(II) mounting procfs to /proc
(II) mounting devpts to /dev/pts
(II) mounting debugfs to /sys/kernel/debug
(II) ifconfig usb0 10.0.0.2 netmask 255.255.255.0
ifconfig: SIOCSIFADDR: No such device
/bin/sh: can't access tty; job control turned off
~ # cat /proc/cpuinfo
Processor : ARMv7 Processor rev 0 (v7l)
processor : 0
BogoMIPS : 1987.37

processor : 1
BogoMIPS : 1993.93

Features : swp half thumb fastmult vfp edsp vfpv3 vfpv3d16
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x1
CPU part : 0xc09
CPU revision : 0

Hardware : Toradex Colibri Tegra2
Revision : 0000
Serial : 0000000000000000

Friday, June 3, 2011

It's been half a year again ...

It's been more than half a year since I last published here. It's just about time to sum things up again.

Firstly, this whole lag is because there was that Operating Systems class where our team wrote a complete OS for MIPS R4kc, including kernel threads, memory management, disk driver, SMP support, userland support etc.

Then, me and Cyril Hrubis started lecturing class "NSWI075 -- Linux kernel" on the university we both study at, Charles University in Prague, Faculty of Mathematics and Physics. The class was enjoyable, even though it was a lot of work to prepare for each of the lectures. Even through this stuff went on, we even managed to make a 2-and-half day long hack-a-ton for our students.

This actually resulted in us finding there are some very capable people in the class, which already got some patches mainline. This is actually quite positive information. Here we also even got tiny bits of device tree on Intel/Marvell PXA!

In parallel with NSWI075, I got involved in a project where our task was to analyze and potentially improve capabilities of Linux in certain network operation. This is where I got to taste real device tree based thing and also got a taste of PowerPC machine. The device in this case was the completely boring MPC5200-based board.

Other than university projects, firstly, I got Efika Smartbook. The device is actually very nice and interesting and I'm very happy with it. I worked on U-Boot for this thing, which still isn't quite ready. There is still a reset problem on the Smartbook, which I didn't have time to debug yet. Though with a tiny change in Linux or U-Boot, the system works fine.

Hardware-wise, there was another event where I got a new toy. That was, FOSDEM. I bought there the Ben Nanonote MIPS/JZ4740 based handheld. It's an awesome thing, but due to Operating Systems class and stuff, I wasn't able to hack on it at all.

FOSDEM though requires a special paragraph or two here. We called it a school field-trip, since the group of people I went there with were all my students from NSWI106 -- Administration of UNIX class. We met a few other friends on the airport, though the most interesting was the first evening in there. Delirium Cafe, where we had some Belgian beer, made things very interesting. So much we left the hotel the other day sometimes past noon.

When we arrived at FOSDEM, we quickly met with many well-known people. For me, it was a friend I sometimes meet even here in Prague since he's local -- Pavel Machek. As for the foreigners though, it was Hector Oron, Wookey, rtp, Loic Minier and many others from the Debian/ARM team. There were obviously many others. Lastly, I must not forget to mention that for whole that time, I had no other than ARM-based hardware with me. I had no x86 laptop with me and I had no trouble at all. As for FOSDEM, it was really enjoyable and next year I'll likely go with a bigger group of friends, but that's all.

Next important event was my visit of DENX. Meeting Wolfgang Denk, Detlev Zundel and others from that was an awesome experience. Seeing how the company works and how they work with the hardware was something awesome. Here again I saw a lot of interesting hardware and had a great time with those people.

But due to me being too busy with all the stuff happening, I got barely any time to hack on kernel. I got a few fixes in, but most of the stuff I tried pushing down on my students. I really hope I'll be able to bring in a few new kernel hackers soon.

Sunday, October 31, 2010

Erratum ENGcm09395 and OpenOCD

Apparently, the Erratum ENGcm09395 for iMX515 made the OpenOCD problems clear. It states the location of ROM Table is misreported. But still, I wanted to implement the ROM Table location autodetection as Oyvind Harboe hinted me to.

Therefore I added a function for handling quirks as this and did some code shuffling in OpenOCD. The patches for this are already in the OpenOCD mailing list. I'm still a bit uncertain about them, but I hope after one or two iterations, they will land in mainline OpenOCD.

Saturday, October 30, 2010

Studies, U-Boot, OpenOCD and CortexA8

The lack of additions on this blog recently wasn't caused by me disappearing out of the blue. It was caused by me preparing for my degree's exams, then fighting with U-Boot and recently working on a new hardware. Read on.

Studies
In case you're only interested in technical stuff, you can skip this part, which is mostly about gaining my bachelor's degree at the Faculty of Mathematics and Physics Charles University and the OpenBSD thesis.

Due to rather personal than other circumstances, I ended up finishing my first academic degree at the end of the summer rather than at the beginning of it. Well, whatever.

That means, the OpenBSD hacking days are past me since I finished my bachelor's thesis. I believe I wrote about this in some of the previous blogs, but now it's officially past me and sealed away. In the end, the thesis was graded A by both the opponent (Mgr. Martin Decky) and the supervisor (RNDr. Leo Galambos, Ph.D.) so the final grade from the thesis was A as well.

Note, the grading system in our country is different than in most other countries. Here, it's numeric, but "1" is equal to A, "2" to B, "3" to C and "4" to Failed. I'll hereby stick with the system using letters to make it less confusing.

Then I had to prepare for the exams, which were really thorough so the preparation certainly couldn't be underestimated. That took me about a month where I didn't hack on stuff much, I was just reviewing patches and from time to time I sent some minor fixes. At the exam, I finished with a total grade of B.

Apparently, on the diploma, there is only one grade, not two (one from thesis and one from examination), so the examination committee has to ultimately decide this grade. My final grade was A, which is what will be on my bachelor's diploma, which I'll receive later next month.

U-Boot
Once the exam was past me, I got back to maintaining U-Boot PXA. Apparently, there were a lot of changes going on inside the U-Boot.

Firstly, Wolfgang Denk pushed me to rework pxa-regs.h so the standard accessors can be used to access PXA CPU registers instead of the preprocessor goo that was there before. This was a patch over 6000 lines big as it affected a lot of code in U-Boot, not only pxa-regs.h. Obviously, platform code as well as drivers were affected and had to be patched to use {read[blw],write[bwl]}() accessors. Catching all the damaged code wasn't really easy in some cases, but I think I caught them all.

With that out of the way, I checked pxa-lcd driver and fixed various, mostly coding-style related problems and added a few new LCD definitions. Then, I fixed PXA250 UART problem, where the UART was omitted in U-Boot from the initialization routine on PXA25x and PXA26x.

Also, the Palm LifeDrive, Palm Tungsten|C and Balloon3 support went in, Voipac PXA270 got various bugs fixed and there were also fixes for the memory init code by Mikhail Kshevetskiy. I also got an USB3.0 flash disk, but apparently, it didn't work with USB on PXA in U-Boot, so I submitted a patch for this.

Then though, Heiko Schocher introduced a change in U-Boot, which allows it to relocate in RAM. More into detail, this change allows U-Boot to always sit at the end of RAM, which is useful on systems where there are various models with different size of RAM detected at runtime. This change broke the PXA port of U-Boot altogether.

This was a good enough motivation to completely rework the PXA init code. I rewrote half of the start.S assembler bootstrap from scratch, because the code there was really old, messy and and with the relocation patches in, no longer suitable for the purpose. The start.S can no longer use RAM until certain point, but it needs to use stack. Sure, for stack, SRAM can be used on PXA27x, but there are PXA CPUs older than that which have no SRAM. This set me in front of a challenge -- where should I point stack pointer register is there's no RAM.

The solution is somehow easy, but needs you to understand how the caches on ARMv5/XScale core work. What was the trick? It was easy, the caches allow the user to lock entries in them. That is, they allow the user to write into the cached area, while convince the CPU not to actually write the data into that area, but only keep them in cache. But for using caches, MMU has to be enabled. So the big picture is, I manually generated an 1:1 VA:PA mapping MMU table within the U-Boot binary and at the bootstrap, I point the CPU at this table and enable MMU. Within this table, at the place which indexes RAM start +1MB*, I made a special entry that configures the area as cachable. Then I used the information from the XScale core documentation to lock 4 kb of data to create a tiny, 4 kb in-cache RAM. So writing to that area of RAM behaves as if the RAM was where and was working, even though there's no backing store. The rest was just a matter of pointing a stack pointer there, end of the fairy tale.

This wasn't the only thing about relocation patches though. Because there was no need to init the RAM in assembler code anymore, I could push the RAM init into the C routines which were executed much later. I did this and in current state, most of the hardware initialization takes place much later. This has one very big advantage in the long-term. As the hardware is not initialized in C code, it'll now be easily possible to walk a Flattened Device Tree and do the hardware initialization according to that. So imagine having single U-Boot binary work many CPUs and only supplying a FDT for each board. That's the long-term plan now.

There were other changes related to this relocation stuff, which in the end generated about 30 patches in total. One more thing is interesting though. Because there are boards which have multiple variants and it's not possible to detect which variant is which on the fly, there started to appear a Makefile pollution in U-Boot, which Wolfgang Denk didn't like. We discussed this and came to a conclusion about a solution. I implemented first version, then he improved it and committed it. So now, all of the U-Boot board variant setup should happen in boards.cfg finally and there's no longer need to touch Makefile.

OpenOCD and CortexA8
About a month ago, I received an Genesi USA EfikaMX Smarttop from their developer sponsorship program called Power Developer. My task was to support this device with OpenOCD so common people can JTAG it with those cheap FT2232-based JTAG dongles.

The system contains an Freescale iMX515 CPU, for which apparently there were some previous unsuccessful attempts to make it work. I based my efforts on these, but did a further investigation of the matter. "Sadly", all the support for Cortex A8 was already in place, which spoiled my fun ;-)

And in the end, it turned out the solution of the problem was very simple. The people trying to get iMX515 working with OpenOCD forget, that the Cortex A8 support there was OMAP3-centric. The DAP address was hardcoded for OMAP3, which has it at 0x54011000 address, but for iMX515, the DAP address is at 0x60008000. Adjusting this in the source code made the CPU mostly work.

The problem with this though is, that this stuff should be auto-detectable. So far, I was digging in the CortexA8 stuff for about two days so I have still a lot to learn about this. But I was hinted by Oyvind Harboe and Zack Welch to use the "dap info 1" command and look around that. The command reads the MEM-AP's BASE register to figure out the location of ROM Table. And by parsing the ROM table, it's possible to figure out the location of DAP, which is exactly the address I mentioned in previous paragraph that needs to be autodetected.

The problem is, this command for some reason misdetects the location of ROM Table and returns the ROM Table is empty. By manually adjusting the source code and pointing the command to a proper location of ROM Table, the parsing algoright catches up and correctly dumps the contents. You can keep an eye on further development of this matter for example here (or the OpenOCD mailing list obviously).

There, you can also find preliminary patches with which the iMX515 works, but the autodetection of ROM Table base is still missing. So, if you want to use iMX515 with OpenOCD, you can, but those three patches won't probably make it into mainline OpenOCD until the autodetection problem is solved.

Monday, August 16, 2010

U-Boot: PXA27x Matrix keypad driver

Today, I hacked together a PXA27x matrix keypad driver for U-Boot bootloader. It behaves as a usual stdin. Then I made ZipitZ2 utilize this new driver. I also implemented support for various modifier keys directly into the driver for convenience's sake. The driver still has a few rough edges and needs some more care, but it does it's job on ZipitZ2 well.

The source code can be found in u-boot-pxa -devel branch.