Meefik's Blog

Freedom and Open Source

Сборка ядра Linux и модулей для Android

Дистрибутивы, запускаемые через Linux Deploy, работают с ядром Android (модифицированное ядро Linux), а потому изменить конфигурацию ядра или подключить новые модули можно только путем пересборки этого ядра, либо сборки модулей под данную версию ядра.

Инструкция

  • Скачать и подготовить Android NDK:
    wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2
    tar -jxf android-ndk-r9d-linux-x86.tar.bz2
    export ARCH=arm
    export CROSS_COMPILE=$(pwd)/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
    
  • Скачать и подготовить Android SDK, понадобятся утилиты adb и fastboot:
    wget http://dl.google.com/android/android-sdk_r13-linux_x86.tgz
    tar -zxf android-sdk_r13-linux_x86.tgz
    android-sdk-linux_x86/tools/android update sdk -u -t platform-tool
    export PATH=$PATH:$(pwd)/android-sdk-linux_x86/platform-tools
    
  • Получить исходники ядра данного устройства (в нашем случае это tinykernel-flo для Nexus 7 (2013), либо скачать аналогичную версию с kernel.org):
    git clone -b tiny-jb-mr2 https://github.com/meefik/tinykernel-flo
    cd tinykernel-flo
    
  • Получить файл конфигурации ядра с устройства (ядро должно быть собрано с поддержкой данной возможности):
    adb shell cat /proc/config.gz | gzip -d > .config
    

    либо из boot.img (как извлечь boot описано ниже):

    scripts/extract-ikconfig boot.img > .config
    
  • Если получить файл конфигурации ядра не получилось, то можно воспользоваться предварительной конфигурацией из поставки ядра (список конфигураций arch/arm/configs):
    make flo_defconfig
    
  • Узнать точную версию ядра устройства:
    adb shell cat /proc/version
    

    Рузультат команды:

    Linux version 3.4.0-g03485a6 (android-build@vpbs1.mtv.corp.google.com) (gcc version 4.7 (GCC) )
     #1 SMP PREEMPT Tue Mar 18 15:02:27 PDT 2014
    

    В данном случае полной версией ядра будет строка “3.4.0-g03485a6”.

  • Установить локальную версию ядра (то что отображается после основной версии 3.4.0):
    echo "-g03485a6" > .scmversion
    
  • Изменить конфигурацию ядра в файле .config или командой:
    make menuconfig
    

    В нашем случае в файл .config изменены следующие строки (включена поддержка модулей и включен модуль binfmt_misc):

    CONFIG_MODULES=y
    CONFIG_BINFMT_MISC=m
    
  • Запустить сборку ядра:
    make
    

    либо только модулей:

    make modules
    
  • Скачать утилиты для работы с загрузочным образом (boot.img):
    git clone https://github.com/meefik/binary-tools-android.git
    cd binary-tools-android
    
  • Получить загрузочный образ с устройства (ядро хранится на специальном boot разделе):
    adb shell su -с 'dd if=/dev/block/platform/msm_sdcc.1/by-name/boot' > boot.img
    

    Путь может отличаться на других устройствах, определить его можно командой:

    adb shell su -c 'ls /dev/block/platform/*/by-name/boot'
    
  • Получить информацию об образе:
    ./boot_info boot.img 
    

    Результат выглядит так:

    Page size: 2048 (0x00000800)
    Kernel size: 6722240 (0x006692c0)
    Ramdisk size: 492556 (0x0007840c)
    Second size: 0 (0x00000000)
    Board name: 
    Command line: 'console=ttyHSL0,115200,n8 androidboot.hardware=flo user_debug=31 msm_rtb.filter=0x3F ehci-hcd.park=3'
    Base address: 2149580800 (0x80200000)
    
  • Извлечь kernel и ramdisk из boot.img, заменить ядро и запаковать обратно:
    ./unmkbootimg boot.img
    ./mkbootimg --kernel ../tinykernel-flo/arch/arm/boot/zImage \
      --ramdisk initramfs.cpio.gz \
      --base 0x80200000 \
      --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=flo user_debug=31 msm_rtb.filter=0x3F ehci-hcd.park=3' \
      -o new_boot.img
    
  • Прошить устройство новым ядром:
    adb reboot bootloader
    fastboot flash boot new_boot.img
    
  • Загрузить модуль на устройстве:
    adb push ../tinykernel-flo/fs/binfmt_misc.ko /storage/sdcard0/binfmt_misc.ko
    adb shell
    su
    mount -o rw,remount /system
    mkdir /system/lib/modules
    cp /storage/sdcard0/binfmt_misc.ko /system/lib/modules/binfmt_misc.ko
    chmod 644 /system/lib/modules/binfmt_misc.ko
    insmod /system/lib/modules/binfmt_misc.ko
    exit
    exit
    
  • Следует учесть, что vermagic модуля должен полностью соответствовать версии ядра (с точностью до символа), иначе загрузить новый модуль не удастся. Необходимо узнать vermagic модуля и сравнить его с уже присутствующими на устройстве модулями:
    modinfo binfmt_misc.ko
    

    Результат выглядит примерно так:

    filename:       /path/to/kernel/fs/binfmt_misc.ko
    license:        GPL
    depends:        
    intree:         Y
    vermagic:       3.4.0-g03485a6 SMP preempt ARMv7