Eee Note kernel hacking

Discussion in 'Asus (Android)' started by RomaVis, Apr 3, 2012.

Thread Status:
Not open for further replies.
  1. RomaVis

    RomaVis Pen Pal - Newbie

    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    6
    Hi, folks.

    As you know, original FW is based on the ancient 2.6.21 linux kernel. I can't understand the reason of using such an old kernel in 2010 year...
    Of course, to support such a rich set of devices, that 2.6.21 was heavily modified.. At first, by Marvell, then by ASUS...
    And the result is unsatisfactory :( That kernel is _completely_ different and incompatible with the current mainline (3.1.. 3.3).

    So, if we want to get modern kernel running on EeeNote, we must do that from scratch :) Original ASUS sources are very helpful, of course..

    Why we need modern kernel running on EeeNote?
    Despite there are very few(if at all are) differences in the user program to kernel interface, we are interested in kernel porting because of one great reason: Android. If we can provide patches for mainline kernel that are compliant with kernel coding standards, they can be applied to Android kernel and.. there will be Android on our device :)

    Of course, as for me, the great reason is just programmer's interest ;)

    So, what must be done in order to port modern kernel?

    First of all, the 3.1.6 kernel compiles for Eee Note and successfully runs just out of box.. But it doesn't know about(or even can't use) Note's hardware.

    We must provide machine description to the kernel, in which we configure and register all the platform devices we have(MMC, audio codec, camera, usb host controller, usb device controller..).

    The second and the most problematic part is drivers for that hardware.
    Mainline 3.1.6 kernel has many drivers for PXA3** periphery (and, of course, PXA3** support at all). Some of them are working out of box, some need to be slightly patched, and some are not suitable at all..

    Here i can explain some problems encountered during porting:

    >>MMC/SD subsystem. PXA303 has two independent MMC/SD/SDIO controllers (MCI), which can work either in 1-bit, 4-bit or SPI mode. In the SPI mode, each controller can drive up to two devices (cards). However, our hardware uses 4-bit mode for each card (it can't be overriden).
    It is wired as following:
    • 2nd MCI hosts Wi-Fi adapter (built around Marvell SD8686) connected via SDIO.
    • 1st MCI hosts BOTH of microSD cards(internal and external) at a time.

    The problem is in fact with microSD.
    Cards are connected literally in parallel :( Except for CMD lines... CMD line switching is done by reconfiguring MFP (CMD line of the active card is connected to CMD line of MCI, second card's CMD is tied to high level to "deselect" the card). Such a design is uncommon and we have no appropriate driver in the kernel (mainline "pxamci" driver can be used to host only one device per controller).

    So, second MCI is driven by "pxamci" driver, which works correctly with SDIO and seems to be stable enough.

    For the first MCI i have written my own "pxamci-multi" driver, based on "pxamci" code, which implements proper locking, busy signaling handling, and is visible to the system as two independent MMC hosts (one per card).
    It has some bugs and isn't rock stable, but at least works :) Of course, i'll try to make it stable and fast as much as hardware design allows.

    >>Framebuffer There is "pxafb" driver in mainline to make use of PXA's framebuffer. All we had to do is provide correct display timings and parameters (which i carefully copied from ASUS sources ;) ).
    BUT... a problem arises: our display is somewhat special and won't work with 50% duty cycle pixel clock. We can handle this situation by setting PCDDIV bit in LCCR4 register of LCD controller. But for unknown reason "pxafb" driver dropped the support for that since some kernel version...

    Simple patch, and we are set :) Display works perfectly. I use _16 bits_ color depth in framebuffer, because in this way we haven't to think about palettes.

    Our display is physically connected via 16-bit interface and uses _GREEN_ channel (as in RGB565 format) as color (it is 6 bits wide in RGB565, so we have 64 levels of black) and just ignores red and blue. So we can simply use 16-bit depth, if implement proper color mixing (it is done by setting "grayscale" flag in display/framebuffer description).
    Also, using the original "8 bit grayscale" mode requires additional patch to "pxafb" ;) And, perhaps, Android won't be happy to bother with palettes...

    >>USB Device controller The one thing i've began to cope with, but haven't done yet..
    It seems to be straightforward: we already have "pxa27x-udc" driver (which works with pxa303) in mainline.
    We just need to disable UDC at bootup (because of bootloader bug? "pxa27x-udc" won't work correctly if probed with already enabled UDC), and perhaps slightly patch the driver..
    Also we must supply it with simple "gpio_vbus" transceiver (also mainline) to detect cable plug/unplug by monitoring GPIO (it is GPIO0_2 in our device).

    I've proceeded up to the moment, where it correctly enables hardware controller, detects cable plug/unplug, uses different gadgets(mass storage, RNDIS ethernet, and so on)... But the host(my notebook) doesn't see EeeNote!
    Perhaps i should take care of pullup resistors on USB data lines, which, i suppose, are enabled by some GPIOs.. I've not found that yet :(

    My next step is to slightly rewrite "pxamci-multi" driver to improve speed and stability, and then try to understand how the MAX8660 PMIC (the heart of power management in our device) was handled in original kernel.
    Maybe, i'll find something about USB pullups there... Of course, the final stage is to integrate PMIC support in new kernel. Without it, we can't even put EeeNote to suspend or power off... And it consumes a lot of battery without correct power distribution scheme :)

    After that, there can be any talks about touchscreen/audio/USB host(as i understand, it is possible!) etc. support.


    Complete listing goes here (supported peripherals in 3.1.6):
    • microSD cards - full support, unstable. Some patches to driver are required
    • WiFi - full support, seems stable. Mainline "Libertas" driver works perfectly with SD8686. SDIO is held by "pxamci" driver
    • LCD - full support, stable. Nothing to say, all works as it have to ;)
    • Touchscreen - no support. Porting of Wacom driver required (however, it doesn't look like somewhat hard)
    • "Suspend" (power) button - handled by gpio_keys driver. Full support ;)
    • Sensor keys - perhaps, support is OK via pxa27x_keypad driver. I just haven't tested it yet (but it inits successfully and creates /dev/input/event descriptor). However, PMIC can be involved in power distribution to the sensor..
    • Audio - no support. Porting of codec driver for ALSA required..
    • USB device (slave) - work in progress ;) It almost works, but EeeNote is invisible to the host.
    • USB host - it is supported by mainline driver, but the problem similar to "pullup resistors" may arise. And we need proper cable, of course.. I haven't tested it yet (and i have no need to)
    • USB OTG - no support. pxa27x-udc doesn't support it, so there wouldn't be support for OTG.
    • Battery charger - no support. We have to use simple mainline "gpio_charger" driver (it reports status by two GPIO lines). I just haven't done that yet. But there shouldn't be any problems, i suppose.
    • Battery gauge - no support. As i remember, we have to port BQ27541 driver. It just needs some amount of time to be done :)
    • PMIC - MAX8660. No support yet. There is mainline MAX8660 driver, but i haven't tried to make use of it (it isn't such a simple work - we have to carefully set up proper "regulator"-"consumer" relations).
    • Power Management - No support at all. It is complex work... i can't say anything related to difficulty yet.

    Some notes...
    Bootloader is really SICK:
    1) It doesn't bother itself with complete hardware uninit while giving control to the kernel. So, USB enabled at boot seems normal :mad:
    2) Kernel image size is limited to.. 2 MiB :mad: Today i have to use LZMA for kernel compression, which is SLOOOW (decompressing time is approx. 5 secs). Also i've spent around 1 day debugging initial bootup (head.S) to find that it just don't load more than 2 MiB...
    3) Initrd image size is limited to.. 2 MiB :mad:
    4) Is it some sort of bootloader bug? I don't know. It just sometimes totally HANGS at bootup, before even booting kernel (at the line "Fuse config ..." in console). I saw that several times after unsuccessful kernel bootup and manual reset(by pressing "Reset" button).
    Moreover, it continues to hang after that on every manual reset! So, the only way to recover is to unplug battery... :(

    I hate ASUS programmers for that "bootloader". Couldn't they just use U-Boot?
    It is needless to talk about its "rich" recovery abilities (if you can't boot your normal linux)... :mad:

    Also, some info:
    BL loads ATAGS at address 0x80000100
    Initrd at address 0x80600000
    Kernel at address 0x80800000 (however, during decompress it relocates itself to another address. The default is 0x80008000)
    BL passes following ATAGS: INIT, MEM, bootloader_version, device test mode(DVT), board revision.

    Also, i have taken two low-quality(sorry, guys..) photos.
    The first depicts framebuffer console output(yeah! It works! I couldn't get it work on original kernel because of stupid colormap the framebuffer driver uses).
    The second features X11 running with twm and some "Cadence IC" windows opened (X11 forwarded over SSH via WiFi).
    I can't say if it is buggy or not because touchscreen support isn't implemented yet. Of course, X11 eats some memory ;)

    The distro i've put there is Arch Linux ARM (it is just for testing purposes).

    P.S
    No manuals, FAQs and images. The kernel at the moment is not suitable for any kind of everyday usage, there is no complete base system with minimal set of graphical utilities working stable, and so on...

    Of course, i'll share current unstable code, if you need it :)
     

    Attached Files:

  2. chris-lawrence

    chris-lawrence Pen Pal - Newbie

    Messages:
    37
    Likes Received:
    0
    Trophy Points:
    15
    Very in depth -- very interesting. Seems like a massive tangle!
     
  3. anomaly

    anomaly Pen Pal - Newbie

    Messages:
    40
    Likes Received:
    0
    Trophy Points:
    15
    Heya RomaVis,

    Regarding the bootloader limitations: is it possible to load only a minimal, uncompressed kernel with only the bare minimum device drivers to access a storage medium compiled static and kexec + rc in order to chainload a full kernel without the size restrictions? This is essentially what the ipaq devs were doing 'back in the day' to work around craptacular oem bootloaders (L.A.B. - Linux as Bootloader)
     
  4. Jamie-B

    Jamie-B Scribbler - Standard Member

    Messages:
    260
    Likes Received:
    31
    Trophy Points:
    41
    Awesome to see you back, RomaVis!! :D I have no skills which could be used to contribute to this, but am obviously very excited to follow your work. Very entertaining to read how many obstacles you've overcome so far, too.
     
  5. andy840119

    andy840119 Pen Pal - Newbie

    Messages:
    53
    Likes Received:
    0
    Trophy Points:
    15
    =.=b
    can you post the .img file??
    that is interesting~
     
  6. RomaVis

    RomaVis Pen Pal - Newbie

    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    6
    andy840119, what do you understand as ".img" file?

    anomaly, of course, it is possible (3.1.6 features complete kexec support on ARM - i've tried it). It is clear that total system boot time would be significantly increased..
    I think that LZMAed kernel would boot a lot faster :) (but, at some moment in the future even LZMA can become larger than 2MiB).

    There is another way: port U-Boot to our device and load it with original bootloader as "linux kernel". I think it would be faster than using "L.A.B". But porting U-Boot is a complex work (of course, if we want to support both microSD cards at a time and maybe loading firmware via USB). On the other side, with a kernel ported, implementing "L.A.B" is simple ;)

    Also, there is and idea to replace original "Update Engine" located in NAND (the structure of it follows the microSD: one partition is for bootloader itself, the second is kernel, the third is initrd, and the largest 100+ MiB partition is unused at the moment) with either U-Boot or "L.A.B".
    Then we would be completely independent from microSD partitioning, and accidentally erasing bootloader is nearly impossible (if NAND support is disabled in the normal kernel)

    However, my main goal today is kernel porting, not implementing different bootloader ;) I just have no time for that..
     
  7. lroncero

    lroncero Pen Pal - Newbie

    Messages:
    62
    Likes Received:
    0
    Trophy Points:
    15
    Hi Romavis, I really admire your work. As Jamie-B, I cannot be of help here, but I would love to follow your job.

    I have only started using Linux a few months ago (Crunchbang Linux) and I love its performance. How come the programmers in ASUS did not port a newer kernel or just made it open for others to install other Linux OS?

    Thanks for sharing your achievements. If any can be of help I am sure this forum is the right place.

    Please let us know of your progress.

    Luis
     
  8. DaEvil1

    DaEvil1 Pen Pal - Newbie

    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    15
    I pretty much assume it's because of the ARM processor. They probably started working on the eee Note not long after the first iPad and started working with what was available to use on a simple ARM processor. And as as someone who programs quite a bit, I know how easy it is to program oneself into being dependant on legacy stuff (such as an old Kernel.) And then you have the choice between continuing developing the code, or scratch 40-80% of it, and start mostly from the ground again. Considering that the eee Note is more of a cult-product than anything else, I'm not surprised they didn't put the effort into getting rid of the legacy dependencies.
     
  9. RomaVis

    RomaVis Pen Pal - Newbie

    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    6
    Hi, guys.

    Some progress was made during last days..
    First of all, i've almost completely rewritten the MMC/SD driver. I haven't yet tested it with agressive communication between two cards, but primarily with one active card it works good (timeout constants must be adjusted due to random timeout errors).

    Next, to the machine description i added support for:
    -MAX8660 regulators (however, it seems usable only to turn on/off camera power, if V6 really supplies camera).
    -BQ27541 gauge. Since now we know, how much time device can run battery-powered, battery current, battery life and so on.. Essential information.
    -BQ24072 charger. However, it can only signal, whether it is charging now, or not (connected via GPIO). BQ27541 also can give us that info ;)

    I've also tried to get audio working (ALC5611 is compatible with WM9713, driver for which is in mainline), but realised that it needs writing some sort of driver wrapper.. Not as hard as MMC/SD, though ;)

    ---

    The most interesting question for me during last month was WHAT and HOW controls that small white LED, located near the "Power button"..
    So, i've scanned (by i2cdetect utility) the I2C bus (standard, not PWR-I2C) and found unknown chip at address "0x2c".

    Other chips on I2C are known: 0x34 is MAX8660 and 0x55 is BQ27541 inside our battery.

    Next, i searched through ASUS' source code and found an enormous mess of code inside "gpio_keys.c", which communicates with that "0x2c" chip via I2C.
    The main purpose of that mess is to.. provide interface to sensor keys!

    So, there is no any "Keypad" in EeeNote. I was confused by the keypad-related code in the ASUS' kernel, but that are just remains of original "Zylonite" code left by ASUS' coders.

    Beside touch-related code, i've found the "set_Senled" procedure which, i suppose, controls the behavior of LED ;)
    So, there is very interesting unknown IC underneath the EeeNote's mainboard, at the sensor keys board, implementing driver of which in the kernel is essential.

    At the moment, i even don't know the part # of that IC, because i've lost my Torx T5 screwdriver and can't disassemble EeeNote more.

    So, if someone have unscrewed (or can easily do that) the main PCB of EeeNote from the front panel, i would be grateful if you can take photos of sensor board and write down IC marking

    --

    Also, i've understood EeeNote's shutdown sequence:
    It just turns off V6 and V7 regulators of MAX8660 (V6 supplies power to camera in our device, as ASUS' code stays, and V7 is "reserved"), V3 and V4 can't be powered off while CPU is in running state (blocked by PWR_EN signal).

    Next, various peripherals are disabled and CPU goes to S3D4C4 (deep sleep mode). It automatically deasserts SYS_EN and PWR_EN signals leading to complete MAX8660 shutdown (V1, V2, V3, V4, V5 supplies disabled). It seems that all the board(except for charger) is powered by MAX8660 :)

    Mainline kernel implements some support for S2D3C4 (sleep mode), S0D1C2, S0D2C2 (standby modes) but neither of that works "out-of-box"... I'll have to fix it.

    So, the primary goal today is to implement S3D4C4 mode, shutdown routine, fix sleep and standby modes.
     
  10. Jamie-B

    Jamie-B Scribbler - Standard Member

    Messages:
    260
    Likes Received:
    31
    Trophy Points:
    41
Loading...
Thread Status:
Not open for further replies.

Share This Page