Group: Hardware/Computers/e-readers/Kobo/Aura H2O Edition 2
Contents
Priority investigation
Which firmwares the hardware requires
Since Linux and u-boot sources are available, the most interesting information (for RYF certification) to look for is if some peripherals require a non-free firmware. The most common places where firmwares can be used or required are:
- The WiFi/bluetooth driver => Waiting for the corresponding source code (mail sent)
- The touchscreen driver
- There is also a ntxfw partition => find what it is
It might also be a good idea to double check that the e-paper display only needs some calibration data and doens't require any nonfree firmware
External interfaces
USB
Several interfaces are exposed through USB:
- It's possible to make the device switch to fastboot during boot
- If the device is not registered, you can switch to mass-storage by selecting "no wifi" during the device boot.
Power button
Touchscreen
Internal interfaces
Serial/UART
As it can be seen on one of the PCB pictures, near the battery, there is some holes with some markings: V, TX, RX, and a ground sign.
V |
|
TX |
|
RX |
|
GND | Ground |
The holes pitch are 2.54mm (0.1 inch), so it's compatible with most common pin-headers found in electronic shops like this one. The best is to use headers that are bent, this way:
- You could even be able to put back the cover if the pin headers height is small enough
- You can still easily use the e-book reader with the screen towards you while still having the serial port adapter plugged in.
However soldering on theses holes may seem trivial at first, but when doing it, the solder didn't want to connect to the pads. I had to raise the temperature to the maximum of my soldering iron to succeed. I also applied some extra flux in the process. (The soldering iron used was a TS100, and I used lead-free solder which works fine on other non-coated pads).
Also, when using the serial port, make sure that the serial adapter and its cable are (and stay) in a position where they cannot cause short circuit by having their metallic part touch some of the conductive part on the e-reader PCB.
Voltage | 3.3v |
Baudrate | 115200 |
Settings | 8N1 (the default almost everywhere) |
To get a shell you can login through the serial port with the user 'root':
(none) login: root [root@(none) ~]#
However once logged the console will probably freeze at some point. This is because the device has aggressive power management which makes the device goes into suspend.
To wake up the device, touching the screen is enough, however touching the screen all the time is not very convenient for development.
It seems to be an userspace application that makes the device goes into suspend. So we will overwrite /sys/power/state with a file that does nothing. We have ram filesystem mounted in /tmp, so we will use that to be saver (as it will not make permanent modifications):
[root@(none) ~]# mount [...] none on /tmp type tmpfs (rw,relatime,size=16384k) [...]
We can overwrite /sys/power/state like that:
[root@(none) ~]# touch /tmp/state [root@(none) ~]# mount -o bind /tmp/state /sys/power/state
This effectively prevent the device from going into suspend.
main storage
Partitions
With fdisk or by looking in /proc/partition we can see 3 partitions:
partition | size | function | source |
mmcblk0p1 | 256M | rootfs | cat /proc/cmdline: root=/dev/mmcblk0p1 |
mmcblk0p2 | 256M | Backup rootfs ? | after mounting it, there are some similar files. Strangely there are no kernel modules in this one. |
mmcblk0p3 | 6.8G | user data | mount: /dev/mmcblk0p3 on /mnt/onboard type vfat |
However if we look at update scripts or fastboot we have more partitions:
name | start | size (from fastboot) | function | source |
mbr | 0 | 1 | The MBR |
|
sn | 1 | 1 | The device serial number |
|
bootloader | 2 | 1022 | The bootloader (u-boot code) |
|
hwcfg | 1024 | 2 |
|
|
ntxfw | 1030 | 255 | Unknown, looks like some firmware |
|
waveform | 14336 | 20480 | The waveform for the e-ink display |
|
logo | 34816 | 4096 | empty |
|
bootenv | 1536 | 510 | Probably u-boot environment |
|
kernel | 2048 | 12284 | The linux kernel in zImage format |
|
dtb | 1286 | 250 | The device tree binary |
|
rootfs | 49152 | 524289 | The two rootfs concatenated |
|
vfat | 1097730 | 14139389 |
|
|
recoveryfs | 573441 | 524289 |
|
|
Exporting the internal eMMC as a block device
After getting a shell in u-boot we can look at the list of eMMC/SD cards:
eBR-1A # mmc list FSL_SDHC: 0 (eMMC) FSL_SDHC: 1
The second mmc listed above doesn't seem to exist:
eBR-1A # mmc dev 1 Card did not respond to voltage select!
This is probably because the u-boot code is based on the code for a Freescale developement/evaluation board and since device manufacturers need to ship products fast they probably didn't bother removing the code for that non-existing hardware.
There is a command called 'ums' in u-boot that can export the e-MMC card through USB and make it appear as a mass storage device (like an USB key or an USB hard disk) to the computer it's connected to.
To use it you need to first connect an usb cable between your computer and the e-book reader and then type 'ums 0 mmc 0' in u-boot like that:
eBR-1A # ums 0 mmc 0 UMS: LUN 0, dev 0, hwpart 0, sector 0xe90000
You can then see it on your laptop:
$ lsblk [...] sdb 8:16 1 7.3G 0 disk ├─sdb1 8:17 1 256M 0 part ├─sdb2 8:18 1 256M 0 part └─sdb3 8:19 1 6.8G 0 part
You can then use GNU ddrescue to backup the eMMC device:
ddrescue /dev/sdb kobo_emmc.img
Extracting the hidden partitions
Since the fastboot provides us the offset and that dd default is to operate on 512b at a time we can simply run the following commands:
dd if=kobo_emmc.img of=mbr.img count=1 dd if=kobo_emmc.img of=sn.img skip=1 count=1 dd if=kobo_emmc.img of=bootloader.img skip=2 count=1022 dd if=kobo_emmc.img of=hwcfg.img skip=1024 count=2 dd if=kobo_emmc.img of=ntxfw.img skip=1030 count=255 dd if=kobo_emmc.img of=waveform.img skip=14336 count=20480 dd if=kobo_emmc.img of=logo.img skip=34816 count=4096 dd if=kobo_emmc.img of=bootenv.img skip=1536 count=510 dd if=kobo_emmc.img of=kernel.img skip=2048 count=12284 dd if=kobo_emmc.img of=dtb.img skip=1286 count=250 dd if=kobo_emmc.img of=rootfs.img skip=49152 count=524289 dd if=kobo_emmc.img of=vfat.img skip=1097730 count=14139389 dd if=kobo_emmc.img of=recoveryfs.img skip=573441 count=524289
Fastboot
There is a fastboot command in u-boot. If you want to enable it from the u-boot shell you can do it like that:
# fastboot 0 ptn 0 name='mbr' start=0 len=1 ptn 1 name='sn' start=1 len=1 ptn 2 name='bootloader' start=2 len=1022 ptn 3 name='hwcfg' start=1024 len=2 ptn 4 name='ntxfw' start=1030 len=255 ptn 5 name='waveform' start=14336 len=20480 ptn 6 name='logo' start=34816 len=4096 ptn 7 name='bootenv' start=1536 len=510 ptn 8 name='kernel' start=2048 len=12284 ptn 9 name='dtb' start=1286 len=250 ptn 10 name='rootfs' start=49152 len=524289 ptn 11 name='vfat' start=1097730 len=14139389 ptn 12 name='recoveryfs' start=573441 len=524289
Here we have access to a lot more partition than with the block device export over USB.
PCB
Here are the chips on the top of the PCB. Caevats:
- you need a big screen to view properly the markings as it will line-break with smaller screens
- The markings might contain errors as they are tiny and some letter/number could be mixed up
- I didn't disassemble it enough to see the bottom because the connectors seemed really fragile (they even had glue inside them) so if I do, I fear that I won't be able to put everything back in place. There might be some more chips on the bottom.
Usage | Location | Package | Markings | Driver(s) | Documentation |
---|---|---|---|---|---|
512M RAM | 168-Ball PoP-FBGA |
NANYA 1718 NT6TL 128M 32BQ-G0 7201166 AEP 3TW |
? | ||
? | ? |
SEC 737 BO41 KLM8616EME H56P4788D |
? | ||
System on a chip | ? (BGA) |
MCIMX6V7DVN10AB XAA 1739 TAIW HMAAXK |
Lots of drivers | ||
WiFi chip (and potentially other features) | ? |
REALTEK 8189PTY H857492 GH438 |
? | ||
? | ? |
RICOH AC5T619 1137 7409N1 |
|||
Power management integrated circuit (and potentially other features) | ? |
TPS 65185 T1 7AI CS6S G4 |
? | ||
On the display flex cable | ? |
TT21000 -48L0I 1725 B03 PRD627959 PHI □ C 041 |
? |
Pictures
Some pictures of the top PCB taken with a camera:
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_01.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_02.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_03.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_04.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_05.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_06.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_07.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_08.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_09.jpeg
- https://archive.org/details/kobo_aura_H2O_edition_2_pcb_10.jpeg
Software
Kobo u-boot version
U-boot is a free software bootloader. The source code is provided by kobo.
It is based on one of the branches/commits of the freescale fork of u-boot for their I.MX System on a chip.
u-boot serial console
To get a shell in u-boot you will need to setup a serial cable, and press a key in the serial console during boot:
U-Boot 2016.03-00031-gcd5f70c (Aug 31 2017 - 13:17:25 +0800) CPU: Freescale i.MX6SLL rev1.1 996 MHz (running at 792 MHz) CPU: Commercial temperature grade (0C to 95C) at 43C Reset cause: WDOG Board: MX6SLL LPDDR2 NTX I2C: ready DRAM: 512 MiB __get_sd_number(),cfg23=0,cfg24=0 MMC: board_mmc_init() : isd=0 board_mmc_init() : wifi=2 FSL_SDHC: 0, FSL_SDHC: 1 In: serial Out: serial Err: serial ntx_hw_early_init() 0 ram p=80000000,size=536870912 switch to partitions #0, OK mmc0(part 0) is current device mmc read 0x9ffffe00 0x3ff 0x1 MMC read: dev # 0, block # 1023, count 1 ... 1 blocks read: OK mmc read 0x9ffffe00 0x400 0x1 MMC read: dev # 0, block # 1024, count 1 ... 1 blocks read: OK ntx_hw_late_init() mmc read 0x9ffffc00 0x1 0x1 MMC read: dev # 0, block # 1, count 1 ... 1 blocks read: OK NTXSN not avalible ! ntx_gpio_get_value(402) : error parameter ! null ptr ! ntx_config_fastboot_layout():10 binaries partition added ntx_config_fastboot_layout():3 mbr partition added check_and_clean: reg 0, flag_set 0 Fastboot: Normal Net: CPU Net Initialization Failed No ethernet found. Hit any key to stop autoboot: 0 eBR-1A #
u-boot environment
Here's the u-boot environment:
eBR-1A # printenv baudrate=115200 bootcmd=mmc dev ${mmcdev};if run loadimage; then run mmcboot; fi; bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; bootdelay=1 bootscript=echo Running bootscript from mmc ...; source console=ttymxc0 epdc_waveform=epdc_splash.bin fastboot_dev=mmc0 fdt_addr=0x83000000 fdt_file=undefined fdt_high=0xffffffff image=zImage initrd_addr=0x83800000 initrd_high=0xffffffff ip_dyn=yes loadaddr=0x80800000 loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script}; loadfdt=load_ntxdtb loadimage=load_ntxkernel mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" mmcargs=setenv bootargs console=${console},${baudrate} rootwait rw no_console_suspend mmcautodetect=no mmcboot=echo Booting from mmc ...; run mmcargs; if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else echo WARN: Cannot load the DT; fi; mmcdev=0 mmcpart=1 script=boot.scr stderr=serial stdin=serial stdout=serial Environment size: 1203/8188 bytes
u-boot booting process
Here the u-boot boot process in uncomon and relies on custom commands like load_ntxkernel to load and execute the Linux kernel and associated data like the dtb:
bootcmd=mmc dev ${mmcdev};if run loadimage; then run mmcboot; fi; loadimage=load_ntxkernel
Adding extra kernel commandline arguments
You can do that in u-boot by overriding mmcargs
setenv mmcargs setenv bootargs <your extra arguments> console=\${console},\${baudrate} rootwait rw no_console_suspend
Stock OS analysis
- The default OS forces the user to register or use some network services like Kobo, google, facebook, etc, however we can get a shell through the serial port.
Source code
- Some Heavily modified Linux 3.0.35 source code is provided by Kobo for this device. It is most probably based on an unknown branch in Freescale's fork of Linux for I.MX system on a chip.
- Some less interesting userspace source code is probably also provided at the same location.
Linux 3.0.35 sources
Board
The sources have multiples boards selected:
CONFIG_MACH_MX6Q_ARM2=y CONFIG_MACH_MX6SL_ARM2=y CONFIG_MACH_MX6SL_EVK=y CONFIG_MACH_MX6SL_NTX=y # CONFIG_MACH_MX6Q_SABRELITE is not set CONFIG_MACH_MX6Q_SABRESD=y
However there is a gen_bootimg.sh with inside:
./mkbootimg --kernel arch/arm/boot/zImage --ramdisk uramdisk.img --base 0x80800000 --cmdline "console=ttymxc0,115200 init=/init androidboot.console=ttymxc0 max17135:pass=2, fbmem=6M video=mxcepdcfb:E060SCM,bpp=16 no_console_suspend" --board evk_6sl_eink -o boot.img
This seem to indicate that the file describing the e-reader hardware is arch/arm/mach-mx6/board-mx6sl_evk.c (along with arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c)
The source code of this file seem to be derived from a single board computer from Freescale/NXP, but it is odd as some features not present in this e-reader hardware aren't disabled at compilation time.
GPU
According to the linux compilation configuration the GPU is unused:
# # MXC Vivante GPU support # # CONFIG_MXC_GPU_VIV is not set
WiFi
The WiFi chip seem to use an out of tree driver:
CONFIG_WLAN=y # CONFIG_USB_ZD1201 is not set # CONFIG_WIFI_CONTROL_FUNC is not set # CONFIG_BCM4329 is not set # CONFIG_BCMDHD is not set # CONFIG_HOSTAP is not set
This will need a bit more research to get some confirmation on that
Linux 4.1.15 sources
New sources for Linux seem to have been pushed the 30 April:
- They don't contain all the build scripts that the 3.0.35 did
- They seem to use the devicetre
How to build
Getting the kernel configuration and device tree source file name
To build it for the device we need:
- A configuration file, hopefully in my case it can be exrtacted from the device by running the following on the device:
# zcat /proc/config.gz
- To identify which device tree source file was used if we want to avoid reusing the one that is in the eMMC
We can start by looking the machine name:
# grep . /sys/firmware/devicetree/base/* [...] /sys/firmware/devicetree/base/compatible:fsl,imx6sll-lpddr3-arm2 /sys/firmware/devicetree/base/compatible:fsl,imx6sll /sys/firmware/devicetree/base/model:Freescale i.MX6SLL NTX Board
And grepping in the source to see the matching files:
$ grep "Freescale i.MX6SLL NTX Board" -r arch/arm/boot/dts/* arch/arm/boot/dts/imx6sll-e60k02.dts: model = "Freescale i.MX6SLL NTX Board"; arch/arm/boot/dts/imx6sll-e60ql2.dts: model = "Freescale i.MX6SLL NTX Board"; arch/arm/boot/dts/imx6sll-e60qm2.dts: model = "Freescale i.MX6SLL NTX Board"; arch/arm/boot/dts/imx6sll-e60qp2.dts: model = "Freescale i.MX6SLL NTX Board"; arch/arm/boot/dts/imx6sll-e70q02.dts: model = "Freescale i.MX6SLL NTX Board"; arch/arm/boot/dts/imx6sll-lpddr2-ntx.dts: model = "Freescale i.MX6SLL NTX Board"; arch/arm/boot/dts/imx6sll-t05r02.dts: model = "Freescale i.MX6SLL NTX Board";
Then on my board I've the 'cyttsp5' touchscreen controller:
# cd /sys/bus/i2c/devices # grep . 0-*/name 1-*/name 2-*/name 0-0036/name:lm3630a_bl 1-0024/name:cyttsp5_i2c_adapter 1-0068/name:tps6518x 2-0032/name:ricoh619
Now only two files are remainign:
$ grep "cyttsp5_i2c_adapter" $(grep "Freescale i.MX6SLL NTX Board" -r arch/arm/boot/dts/* | sed 's#:.*##') arch/arm/boot/dts/imx6sll-e60k02.dts: compatible = "cy,cyttsp5_i2c_adapter"; arch/arm/boot/dts/imx6sll-e60k02.dts: cy,adapter_id = "cyttsp5_i2c_adapter"; arch/arm/boot/dts/imx6sll-e60qm2.dts: compatible = "cy,cyttsp5_i2c_adapter"; arch/arm/boot/dts/imx6sll-e60qm2.dts: cy,adapter_id = "cyttsp5_i2c_adapter";
It is possible to visualize the difference between both files in a very convenient way like this:
$ meld arch/arm/boot/dts/imx6sll-e60k02.dts arch/arm/boot/dts/imx6sll-e60qm2.dts
It shows quite some difference in the way the system on a chip pins are configured.
For instance for arch/arm/boot/dts/imx6sll-e60qm2.dts we have:
pinctrl_elan_ts_gpio_sleep: elan_ts_gpio_grp_sleep { fsl,pins = < MX6SLL_PAD_SD1_DATA3__GPIO5_IO06 0x10059 /* TP_INT */ MX6SLL_PAD_SD1_DATA2__GPIO5_IO13 0x10059 /* TP_RST */ >; };
and for arch/arm/boot/dts/imx6sll-e60k02.dts we have:
pinctrl_elan_ts_gpio: elan_ts_gpio_grp { fsl,pins = < MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24 0x17059 /* TP_INT */ MX6SLL_PAD_GPIO4_IO18__GPIO4_IO18 0x10059 /* TP_RST */ MX6SLL_PAD_GPIO4_IO17__GPIO4_IO17 0x10059 /* TP_SWDIO */ >; };
Fortunately the Linux kernel exports that information at runtime, and we can access it like that:
# mount -t debugfs none /sys/kernel/debug/ # cd /sys/kernel/debug/pinctrl
After grepping we can see the following line in pinctrl-handles:
type: MUX_GROUP controller 20e0000.iomuxc group: elan_ts_gpio_grp (34) function: imx6sll-lpddr3-arm2 type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6SLL_PAD_GPIO4_IO24 (147) 00017059 type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6SLL_PAD_GPIO4_IO18 (146) 00010059 type: CONFIGS_PIN controller 20e0000.iomuxc pin MX6SLL_PAD_GPIO4_IO17 (149) 00010059
Note that to open pinctrl-handles with a text editor on the device you need to copy it somewhere first, like in /tmp/
In my case the device tree file that works for my hardware is the arch/arm/boot/dts/imx6sll-e60qm2.dts
kernel logs
runtime informations
Here's the kernel version of the device I got:
# uname -r 4.1.15-00104-gcd6a6a6
The boot kernel parameters are available in /proc/cmdline:
console=ttymxc0,115200 rootwait rw no_console_suspend hwcfg_p=0x9ffffe00 hwcfg_sz=110 waveform_p=0x9fdc8a00 waveform_sz=2323160 ntxfw_p=0x9fdc6400 ntxfw_sz=9474 mem=509M boot_port=0 rootfstype=ext4 root=/dev/mmcblk0p1 quiet
- The kernel configuration is available at /proc/config.gz
- The device uses a devicertee that is passed by the bootloader:
# grep . /sys/firmware/devicetree/base/* [...] /sys/firmware/devicetree/base/compatible:fsl,imx6sll-lpddr3-arm2 /sys/firmware/devicetree/base/compatible:fsl,imx6sll /sys/firmware/devicetree/base/model:Freescale i.MX6SLL NTX Board