If you are following this blog you know I’m hacking an Wireless IP Camera VStarCam H6837WI and I have good news!
I found the Linux source code for SSD1935, thanks TEAC for releasing it. But I was wrong when I thought it should be very easy to get it working on my camera.
First, the machine ID used on TEAC WAP R8900 didn’t match the machine passed by u-boot, it was supposed to happen. I think neither Solomon Systech or TEAC was thinking to integrate it in the Linux mainline because they are using an invalid board ID (registered by other company).
Then I just need to select the right board ID, but Solomon used this board ID, used on VStarCam H6837WI, at least in three other boards. Then I just selected the board with same name used on the u-boot (it was a fault as you will see further below).
After compiling it and uploading the resulting uImage in the camera using ymodem transfer protocol on u-boot it didn’t start correctly.
Then I start debugging the low level kernel initialization, at first using ‘printascii’ (with DEBUG_LL activated), but with no luck. After many trials I decide to use other strategy, I decided to disassemble the original uImage retrieved from camera flash memory. This is the information from original uImage:
$ file uImage_h6837wi.bin uImage_h6837wi.bin: u-boot legacy uImage, Linux-2.6.24ssl, Linux/ARM, OS Kernel Image (Not compressed), 1467600 bytes, Mon Apr 8 17:01:50 2013, Load Address: 0x50C08000, Entry Point: 0x50C08000, Header CRC: 0xFFA94C01, Data CRC: 0xA90B8571
First I extracted the zImage from uImage and then decompressed it. After decompressing it to an Image I disassembled it and started to compare with the Image which I compiled.
This site helped too much: http://chdk.wikia.com/wiki/Gpl_Disassembling
I used these commands to create a disassembled file:
strings -t x Image | ./renumber.pl 0x50C08000 > Image.strings hexdump -C Image |./renumber.pl 0x50C08000 > Image.hex arm-linux-objcopy --change-addresses=0x50C08000 -I binary -O elf32-littlearm -B arm Image Image.elf arm-linux-objcopy --set-section-flags .data=code Image.elf arm-linux-objdump -d Image.elf > Image.dis
Then I noticed a visible difference at this position:
Then using ‘arm-linux-addr2line’ it returned:
$ arm-linux-addr2line -f -e vmlinux 0xc00080dc __create_page_tables .tmp_kallsyms2.S:0
I searched for ‘__create_page_tables’ and it returned the file ‘arch/arm/kernel/head.S’ then I opened this file and started comparing the assembly code, and found the difference at this line:
orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
Then I searched for ‘PHYS_OFFSET’ and found this file: ‘kernel/include/asm-arm/arch-magus/memory.h’ :
#ifdef CONFIG_ARCH_MAGUS_FPGA #define PHYS_OFFSET UL(0xE2000000) #elif defined CONFIG_ARCH_MAGUS_ADS #define PHYS_OFFSET UL(0x51000000) #elif defined CONFIG_ACCIO_CM5208 #define PHYS_OFFSET UL(0x51000000) #elif defined CONFIG_ACCIO_CM5210 #define PHYS_OFFSET UL(0x51000000) #elif defined CONFIG_ACCIO_A2818T #define PHYS_OFFSET UL(0x51000000) #elif defined CONFIG_ACCIO_LITE #define PHYS_OFFSET UL(0x50400000/*0x50C00000*/) #else #define PHYS_OFFSET UL(0x51000000) #endif
I noticed the address 0x50C00000 was commented (for my luck) and should be used for ‘ACCIO_LITE’, hmm I was using ‘ACCIO_A2818T’ because this was the board name I saw at u-boot bootloader source code. Then after removing 0x50400000 and using 0x50C00000 I reconfigured the kernel to use ACCIO_LITE.
Then I compiled the source code again, but no luck, it still no starting.
What should be wrong now?
I decide to compiled the kernel again and paying more attention at log messages, then I noticed these lines:
Data Size: 1471920 Bytes = 1437.42 kB = 1.40 MB Load Address: 0x50408000 Entry Point: 0x50408000 Image arch/arm/boot/uImage is ready
Ouch, it should be 0x50C08000, as in the original uImage file!
“Let’s search again like we did last year!”, replace ‘search’ by ‘twist’ to understand the lyrics 🙂
Searching for 0x50408000 returned this file:
This is the content:
zreladdr-$(CONFIG_ACCIO_LITE) := 0x50408000
Bingo! Replacing it by 0x50C08000 and compiling again fixed the booting issue.
See my compiled kernel booting here:
object$ loady ## Ready for binary (ymodem) download to 0x50C07FC0 at 115200 bps... CxyzModem - CRC mode, 11503(SOH)/0(STX)/0(CAN) packets, 8 retries ## Total Size = 0x001675f0 = 1471984 Bytes object$ bootm 0x50C07FC0 Starting kernel ... Uncompressing Linux............................................................................................. done, . [ 0.000000] Linux version 2.6.24ssl (alan@aureo) (gcc version 3.4.6) #1 PREEMPT Sun Dec 9 17:37:11 BRST 2012 [ 0.000000] CPU: ARM926EJ-S  revision 5 (ARMv5TEJ), cr=00053177 [ 0.000000] Machine: Solomon Magus Accio P1 [ 0.000000] Memory policy: ECC disabled, Data cache writeback [ 0.000000] CPU0: D VIVT write-back cache [ 0.000000] CPU0: I cache: 8192 bytes, associativity 4, 32 byte lines, 64 sets [ 0.000000] CPU0: D cache: 8192 bytes, associativity 4, 32 byte lines, 64 sets [ 0.000000] Built 1 zonelists in Zone order, mobility grouping off. Total pages: 5080 [ 0.000000] Kernel command line: mem=20M console=ttyS0,115200n8 init=/sbin/init root=/dev/mtdblock3 [ 0.000000] intc: init info - ver=1,0 [ 0.000000] gpio: init info - ver=1,0 [ 0.000000] clock: init info - ver=1,0 [ 0.000000] MAGUS Clocks : ARM-240.000 MHz, HCLK-120.000 MHz, PCLK-60.000 MHz, PERCLK1-60.000 MHz, PERCLK2-24.000 MHz [ 0.000000] PID hash table entries: 128 (order: 7, 512 bytes) [ 0.000000] Console: colour dummy device 80x30 [ 0.000000] console [ttyS0] enabled [ 0.020000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes) [ 0.020000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.030000] Memory: 20MB = 20MB total [ 0.040000] Memory: 17268KB available (2680K code, 229K data, 72K init) [ 0.280000] Mount-cache hash table entries: 512 [ 0.280000] CPU: Testing write buffer coherency: ok [ 0.300000] net_namespace: 64 bytes [ 0.310000] NET: Registered protocol family 16 [ 0.340000] dma: init info - ver 1.0 fifosize=128, 8 channels [ 0.340000] MAGUS cpu freq change driver v1.0 [ 0.350000] [ 0.350000] cpufreq: magus_set_target: request for target_freq = 240000 KHz [ 0.360000] cpufreq: magus_set_target: cur_pll_out = 240000 KHz, cur_arm_freq = 240000 KHz [ 0.390000] SCSI subsystem initialized [ 0.400000] usbcore: registered new interface driver usbfs [ 0.410000] usbcore: registered new interface driver hub [ 0.420000] usbcore: registered new device driver usb [ 0.480000] NET: Registered protocol family 2 [ 0.580000] IP route cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.590000] TCP established hash table entries: 1024 (order: 1, 8192 bytes) [ 0.600000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes) [ 0.600000] TCP: Hash tables configured (established 1024 bind 1024) [ 0.610000] TCP reno registered [ 0.640000] Power Management for MAGUS. V0.1.1 [ 0.640000] NetWinder Floating Point Emulator V0.97 (extended precision) [ 0.660000] yaffs Dec 9 2012 17:36:12 Installing. [ 0.670000] io scheduler noop registered [ 0.670000] io scheduler deadline registered (default) [ 0.680000] lcdc: init info - dsg=0 ver=0 [ 0.680000] abc=1, dbc=1 rdback=1 pp=0 lut=1 stn=1 dma=1 [ 0.690000] lcdc: init warn - actually ver 0001 [ 0.690000] SSL_FB: disable wid: 1 [ 0.700000] SSL_FB: disable wid: 2 [ 0.720000] Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing disabled [ 0.730000] ttyS0: autoconf (0x0000, 0xf000300c): uart: id=7000041 [ 0.740000] type=16550A [ 0.740000] serial8250: ttyS0 at MMIO 0x0 (irq = 16) is a 16550A [ 0.750000] ttyS1: autoconf (0x0000, 0xf000400c): uart: id=7000041 [ 0.760000] type=16550A [ 0.760000] serial8250: ttyS1 at MMIO 0x0 (irq = 17) is a 16550A [ 0.770000] Driver 'sd' needs updating - please use bus_type methods [ 0.780000] Driver 'sr' needs updating - please use bus_type methods [ 0.790000] NAND Driver, (c) 2007 Solomon Systech [ 0.790000] nfc: init info - ver=100 buf=4224 [ 1.800000] nfc nand reset tout [ 1.800000] nfc: init info - ver=100 buf=4224 [ 1.800000] No NAND device found!!! [ 1.810000] spi: init info - ver=1.0 fifo=16 slaves=5 master=1 [ 1.820000] spi: init info - ver=1.0 fifo=16 slaves=5 master=1 [ 1.940000] ehci ehci: ssl ehci [ 1.940000] ehci ehci: new USB bus registered, assigned bus number 1 [ 1.950000] ehci ehci: irq 14, io mem 0x08403000 [ 1.970000] ehci ehci: USB 0.0 started, EHCI 1.00, driver 10 Dec 2004 [ 1.980000] usb usb1: configuration #1 chosen from 1 choice [ 1.980000] hub 1-0:1.0: USB hub found [ 1.990000] hub 1-0:1.0: 1 port detected [ 2.100000] usb usb1: Product: ssl ehci [ 2.100000] usb usb1: Manufacturer: Linux 2.6.24ssl ssl ehci [ 2.110000] usb usb1: SerialNumber: ssl_ehci [ 2.110000] Initializing USB Mass Storage driver... [ 2.340000] CI reset done [ 2.400000] usb 1-1: new high speed USB device using ehci and address 2 [ 2.520000] CI reset done [ 2.630000] usb 1-1: configuration #1 chosen from 1 choice [ 2.650000] usb 1-1: Product: 802.11 n WLAN [ 2.650000] usb 1-1: Manufacturer: Ralink [ 2.660000] usb 1-1: SerialNumber: 1.0 [ 2.660000] usbcore: registered new interface driver usb-storage [ 2.670000] USB Mass Storage support registered. [ 2.680000] usbcore: registered new interface driver libusual [ 2.680000] i2c /dev entries driver [ 2.690000] i2c: init info - ver=1,0 [ 2.700000] [ 2.700000] cpufreq: magus_set_target: request for target_freq = 240000 KHz [ 2.710000] cpufreq: magus_set_target: cur_pll_out = 240000 KHz, cur_arm_freq = 240000 KHz [ 2.720000] TCP cubic registered [ 2.720000] NET: Registered protocol family 1 [ 2.730000] NET: Registered protocol family 17 [ 2.730000] VFS: Cannot open root device "mtdblock3" or unknown-block(0,0) [ 2.740000] Please append a correct "root=" boot option; here are the available partitions: [ 2.750000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
There is too much work to be done. I need to add flash memory support and layout to it load the file-system. No problem, now I can see it starting, then everything will be more easy 😉