internal sd card

If open the device, you can easily replace the internal sd card. Structure: 3 partitions: - operating system - rescue - data

In an open device you easily find the serial console.

Room before the first partition

The information source is debug output by serial console and SD_OFFSET_* defines in uboot/board/freescale/mx6sll_ntx/ntx_comm.c

  • various blobs

  • 0x400: uboot.imx

  • 0xa0c00: dtb (prepended with length header)

  • 0xc0000: uboot env, length 8192 bytes

  • 0x100000: zImage (prepended with length header)

  • 0x700000: waveform (prepended with length header), required by the epd

  • hwcfg (probably some relict from pre-dtb times, mainline kernel we can live without)

  • ntxfw (also some config stuff, on a mainline kernel we can live without)

length header = FF F5 AF FF 78 56 34 12 LLLLLLLL 00 00 00 00

LLLLLLLL = length in little endian

It is positioned 16 Bytes before the data, e.g. at 0xa0bf0 for the dtb.

HWCfg contents

{m_hdr = {cMagicNameA = "HW CONFIG "
cVersionNameA = "v3.0"
bHWConfigSize = 69 'E'}
m_val = {bPCB = 74 'J'
bKeyPad = 12 '\f'
bAudioCodec = 0 '\000'
bAudioAmp = 0 '\000'
bWifi = 8 '\b'
bBT = 0 '\000'
   bMobile = 0 '\000'
bTouchCtrl = 14 '\016'
bTouchType = 3 '\003'
bDisplayCtrl = 15 '\017'
bDisplayPanel = 6 '\006'
bRSensor = 0 '\000'
bMicroP = 2 '\002'
bCustomer = 9 '\t'
bBattery = 14 '\016'
   bLed = 4 '\004'
bRamSize = 3 '\003'
bIFlash = 0 '\000'
bExternalMem = 0 '\000'
bRootFsType = 2 '\002'
bSysPartType = 2 '\002'
bProgressXHiByte = 1 '\001'
bProgressXLoByte = 104 'h'
bProgressYHiByte = 2 '\002'
   bProgressYLoByte = 228 '\344'
bProgressCnts = 0 '\000'
bContentType = 0 '\000'
bCPU = 10 '\n'
bUIStyle = 1 '\001'
bRamType = 5 '\005'
bUIConfig = 0 '\000'
bDisplayResolution = 5 '\005'
bFrontLight = 1 '\001'
   bCPUFreq = 0 '\000'
bHallSensor = 1 '\001'
bDisplayBusWidth = 0 '\000'
bFrontLight_Flags = 6 '\006'
bPCB_Flags = 17 '\021'
bFrontLight_LED_Driver = 4 '\004'
bVCOM_10mV_HiByte = 0 '\000'
   bVCOM_10mV_LoByte = 0 '\000'
bPCB_REV = 16 '\020'
bPCB_LVL = 0 '\000'
bHOME_LED_PWM = 0 '\000'
bPMIC = 1 '\001'
bFL_PWM = 2 '\002'
bRTC = 1 '\001'
bBootOpt = 0 '\000'
bTouch2Ctrl = 0 '\000'
   bTouch2Type = 0 '\000'
bGPS = 0 '\000'
bFM = 0 '\000'
bRSensor2 = 0 '\000'
bLightSensor = 0 '\000'
bTPFWIDByte0 = 0 '\000'
bTPFWIDByte1 = 0 '\000'
bTPFWIDByte2 = 0 '\000'
bTPFWIDByte3 = 0 '\000'
   bTPFWIDByte4 = 0 '\000'
bTPFWIDByte5 = 0 '\000'
bTPFWIDByte6 = 0 '\000'
bTPFWIDByte7 = 0 '\000'
bGPU = 0 '\000'
bPCB_Flags2 = 0 '\000'
bEPD_Flags = 0 '\000'
bLAN = 0 '\000'
bMobileIF = 0 '\000'
   bPIR = 0 '\000'
bPanelLaminationSrc = 0 '\000'}
m_bReserveA = '\000' <repeats 24 times>}

Preparing a new sd card and keep the old one as a backup

Take the sd card out of the Kobo (while it is powered off) and put it into your sd card reader. dd if=/dev/sdX of=kobo-backup (sdX is your sd card reader)

insert a new (probably bigger) sd card and play back dd if=kobo-backup of=/dev/sdX (sdX is your sd card reader)

now you can - delete the three partitions (if you do not want to use the original system) - resize the fat partition with tools like fatresize - add new partitions for altenative systems. Important: do not start any partition before sector 49152 unless you modified uboot to not search anything there

Uboot

Normally uboot loads the various blobs and then boots the kernel. Version is 2016.03, that means it can read ext4 but things need to be formatted with -O ^64bit.

Output possibilities

ledG - switches the power led on or off

Input possibilities

after running the mf_key command the power key can be queried by gpio input 136. Probably also the cover (via hall sensor) status can be queried.

Boot choice

If you want to be able to choose the system to boot, you can use this environment: uboot-env.txt

To update the environment you can use this tool: envtokobodisk.sh ./envtokobodisk.sh uboot-env.txt /dev/sdX

How it works: After poweron the led blinks several times and when turning off the led, the power key status is read, if the key is pressed the corresponding boot choice is used. In this example:

  • the default is choosen if the power key is never pressed (system from 1. partition, with kernel+dtb from default location)

  • pressed during 2. led off: root from /dev/mmcblk0p5 default location of kernel+dtb

  • pressed during 3. led off: executing boot/boot.scr from /dev/mmcblk0p5

  • pressed during 4. led off: executing boot/boot.scr from /dev/mmcblk0p6

Uboot has some pitfalls: the bootz command is patched so that it

  • loads a kernel if load_ntxkernel is not called

  • loads additional blobs (configuration, waveform, devicetree)

  • appends things to the kernel commandline like addresses of these additional blobs, and quiet

So if you want to load a kernel from file, first call load_ntxkernel, then load the kernel in the usual way.

Kernel

There is the vendor kernel at: github.com/kobolabs/Kobo-Reader

It is a heavily patched 4.1.15 kernel

Compiling the vendor kernel

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_kobo_defconfig zImage modules dtbs -j 5

This will be a bit noisy with gcc-8, better stick to gcc-6

The devicetree will be located in arch/arm/boot/dts/imx6sll-e60k02.dtb

Mainline kernel status

Kernel v5.5

contains a devicetree (imx6sll-kobo-clarahd.dts)

What works with that:

  • SD card access

  • USB gadget (so you can use g_ether and log in over ssh)

  • cpufreq

  • hall sensor (cover detection)

  • serial console

  • led

  • regulator part of PMIC

  • poweroff via commands

  • detection of wifi module (=sdio card), done via a combination of simple-powerseq and a fixed, gpio-controlled regulator

  • backlight (separate backlight_warm and backlight_cold)

Kernel v5.6

  • devicetree for tolino shine 3 (same board, but equipped with imx6sl instead of imx6sll)

  • power button gives events to user space (not only forced power off)

Kernel v5.7

  • RTC support

  • ADC driver, can read out VUSB and battery voltage (device tree misses interrupt entry, is fixed in v5.8-rc1)

with additional patches (https://github.com/akemnade/linux branch merged-5.7 and 5.8, there is also a kobo_defconfig):

  • touchscreen: slightly patched things copied over from vendor kernel

  • EPD

accepted for kernel v5.10

  • fuel gauge (another subdevice of the PMIC)

Out-of-tree modules:

EPD waveform:

  • can be in /lib/firmware/imx/epdc/epdc_PENG060D.fw

  • or as a fallback in /lib/firmware/imx/epdc/epdc.fw

  • can be extracted using extract-waveform.pl

  • Kobo vendor kernel gets a memory block passed over from bootloader

The wifi module seems not to power down the card completely. You will see that the wifi-regulator is still on, but rmmod 8189fs helps

X11

To trigger updates to the epd, you have to either enable set CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE=y in the vendor kernel config or use the patched xf86-video-fbdev from here branch kobo-epd-0.5.0. The first one gives uglier refreshes because it only detects memory ranges to be refreshed, wich means you always refresh a horizontal stripe with y>=min(changed_pixels_y) and y<max(changed_pixels_y)