Android 10: Update kernel modules - android

Background: I am working with a Pixel 4, build QQ2A.200501.001.B2, which is Android 10. When I build the kernel from the official sources and flash it, the touchscreen, wlan and other features do not work. I tracked this down to the fact that the kernel modules in /vendor/lib/modules do not get updated, thus the new kernel can't load any of them. I tried flashing both only boot.img and the entire AOSP, same issue, they don't get updated. I can workaround this by manually pushing the kernel modules I built to the device and manually insmoding them in the right order.
So my questions are:
Why don't they get updated in the first place?
How can I update them along with the kernel when I flash?
Alternatively, how can I permanently update them after flashing?
Surely there must be an "official" way to do this? How are the kernel modules normally deployed?
Some notes:
I can't push them to /vendor/lib/modules because I can't remount /vendor writable:
flame:/ # mount -o rw,remount /vendor
'/dev/block/dm-5' is read-only
Disabling dm-verity doesn't seem to help.
I noticed that the AOSP source contains all the modules that are in /vendor/lib/modules, in the same place where it takes the kernel image form (in my case that's device/google/coral-kernel). So naturally, I tried replacing the modules there with the ones I built, but after building and flashing, I see that /vendor/lib/modules still contains the old modules.
The AOSP docs say that boot.img does not contain the ramdisk anymore, it's now in the system partititon. Also, OverlayFS is used and one should use a "vendor overlay" to update files there, if I read it right. However, on my device, there is no product/vendor_overlay directory like the docs say, only product/overlay/. I'm also not sure if this is the right way to tackle this or how I would go about creating such an overlay in my case.
Thanks

Ok. Several questions, several answers:
Why don't they get updated in the first place?
Because they are expected to be in /vendor/lib/modules, and when you recompile a kernel you're only creating the kernel binary which goes into the boot.img.
How can I update them along with the kernel when I flash?
You could compile the modules into the kernel. That makes your kernel a bit bigger, but relieves you from the need to insert these modules.
Alternatively, how can I permanently update them after flashing?
You can indeed modify /vendor like you've tried - but not the DM-verity block device (/dev/block/dm-5 in your case) - the underlying partition (/dev/block/sd?#, something, which you can see if you look at the links from /dev/block/by-name/vendor).
CAVEAT: This will cause dm-verity to fail mounting /vendor unless you correctly disable dm-verity!
Another avenue to try for testing: Linux kernel modules have a strict vermagic requirement (in simpler terms, the module string must match the 'uname -r' of the kernel, to ensure that critical kernel structures have not been modified). If you don't change the kernel magic (VERSION, PATCHLEVEL, SUBLEVEL and EXTRAVERSION from Makefile) (or "fake" them to the original kernel version your device came with) the modules should load.

Alternatively, how can I permanently update them after flashing?
You can use below command to disable verity :
adb root
adb disable-verity
adb shell sync
adb reboot
then push the .ko(s) to /vendor/lib/modules/ :
adb root
adb remount
adb push *.ko /vendor/lib/modules/
adb shell sync
adb reboot

Related

Expose a binary to other Android apps

I wanted to have git available as a CLI tool on my android device, usable via a local terminal app. I've successfully cross-compiled git for aarch64-linux-android and if I use a root shell to move it to one of the ext4 filesystems on the device I can invoke it successfully.
However, installing and using it with root is not desirable. I normally leave my device unrooted and only temporarily enable root to do experiments like this. Installation as root is not so bad, but it seems that the only ext4 filesystems mounted read/write are in locations that the terminal app cannot read from, so I cannot use it as a non-root user, which is a deal breaker *.
I'd prefer to package it as an APK if possible, so it can be sideloaded as a normal user. I'd also like to be able to invoke it from the terminal app. If I have to manually adjust $PATH, that's fine, but bonus points if the APK can place it somewhere on $PATH or have the OS extend $PATH on installation.
* (I know I can remount /system as r/w to install it as root, and that would make it usable to all applications. I don't want to modify /system because then "factory resets" are not ensured to bring me back to a working state. I know it'd be a relatively safe change. If this really is impossible, I'll do that, but an APK would be so much nicer)
I don't think you can do this. Android is designed to prevent such things: each APK can only run in a (somewhat) isolated container.
An APK cannot install an executable in the root folders. Modifying $PATH will also not work (if the system would even allow you to modify it) because each APK is executed by a different user, thus the environment will be different. I'm not even sure you can mark a file as executable on common folders.
One workaround to this would be to make the path of the executable (if you can mark a file as executable, that is) available through a ContentResolver.

How to flash the kernel image on android device?

I am trying to learn the kernel customization and for this I have target OnePlus 6T device. I am able to compile the kernel source code on my Ubuntu 18 with the following steps:
Download latest dtc from https://packages.ubuntu.com/cosmic/a...piler/download and install it.
Clone kernel source code: git clone https://github.com/OnePlusOSS/androi...lus_sdm845.git
Clone ToolChain: git clone -b linaro-4.9-arm-linux-androideabi https://github.com/ArchiDroid/Toolchain prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-linaro-4.8
Open terminal at prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-linaro-4.9 and run: export CROSS_COMPILE=$(pwd)/bin/aarch64-linux-android-
Navigate to kernel source code path in the same terminal.
export ARCH=arm64 && export SUBARCH=arm64
make clean
make mrproper
mkdir Out
make O=Out sdm845_defconfig
make O=Out DTC_EXT=dtc CONFIG_BUILD_ARM64_DT_OVERLAY=y DTC_EXT=dtc -j4
Following are the last lines of compilation:
CC drivers/media/platform/msm/broadcast/tspp.mod.o
CC drivers/media/platform/msm/dvb/adapter/mpq-adapter.mod.o
CC drivers/media/platform/msm/dvb/demux/mpq-dmx-hw-plugin.mod.o
GZIP arch/arm64/boot/Image.gz
CC drivers/soc/qcom/llcc_perfmon.mod.o
CC drivers/video/backlight/lcd.mod.o
CC net/bridge/br_netfilter.mod.o
LD [M] drivers/char/rdbg.ko
LD [M] drivers/media/platform/msm/broadcast/tspp.ko
LD [M] drivers/media/platform/msm/dvb/adapter/mpq-adapter.ko
LD [M] drivers/media/platform/msm/dvb/demux/mpq-dmx-hw-plugin.ko
LD [M] drivers/soc/qcom/llcc_perfmon.ko
LD [M] drivers/video/backlight/lcd.ko
LD [M] net/bridge/br_netfilter.ko
CAT arch/arm64/boot/Image.gz-dtb
make[1]: Leaving directory '/home/.../KernelCustomization/android_kernel_oneplus_sdm845/Out'
Now, the next step is to flash the image. I have rooted OnePlus 6T device and I am confused with the three image files generated after successful compilation i.e.
arch/arm64/boot/Image.gz-dtb
arch/arm64/boot/Image.gz
arch/arm64/boot/Image
I need a favour in:
What image can I use to flash on android device?
Is booting a image with TWRP is enough to flash kernel?
Found Google documentation
https://source.android.com/devices/bootloader/partitions-images
As per following lines from google documentation:
boot: The boot partition contains a kernel image and a RAM disk combined via mkbootimg. In order to flash the kernel directly without flashing a new boot partition, a virtual partition can be used:
kernel: The virtual kernel partition overwrites only the kernel (zImage, zImage-dtb, Image.gz-dtb) by writing the new image over the old one. To do this, it determines the start location of the existing kernel image in eMMC and copies to that location, keeping in mind that the new kernel image may be larger than the existing one. The bootloader can either make space by moving any data following it or abandoning the operation with an error. If the development kernel supplied is incompatible, you may need to update the dtb partition if present, or vendor or system partition with associated kernel modules.
I think I have to use arch/arm64/boot/Image.gz-dtb for flashing the kernel. My understanding is that Image.gz-dtb is a virtual image that can be used to flash only kernel on android.
Still, I am not able to figure out the correct step to flash it. I am wondering if I will do something wrong then I will break my device so I want to be sure before flashing that it will work.
Any help or guidance will be very helpful at this moment.
I found the steps that are needed to flash the custom kernel on android device i.e.
First we need to get the boot image of stock firmware we can get it by running following commands:
adb shell "ls -la /dev/block/platform/soc/1d84000.ufshc/by-name/" > MoreInfo\msm_partitions.txt
Note the boot partition name e.g. boot_a -> /dev/block/sde11 boot_b -> /dev/block/sde39
Missing steps to make boot.img with command dd command.
Download the latest Android Image Kitchen from this thread.
Run the following with the boot image: unpackimg.sh .img
Locate the zImage file and replace it with your kernel image (rename it to what came out of the boot image)
Run the following to repack: repackimg.sh
Flash the new boot image with fastboot or TWRP!
I need some more information on the missing steps. Actually the process written above is working on devices that has only one boot partition. Does any one know how can I flash my single kernel image on a device that has a/b partitioning?
Update:
I searched over the internet for A/B partitioning and I found that these are used for seamless updates i.e. One partition is active at a time and another partition which is inactive can be used to flash the update. On reboot, another partition will become active and One partition will become inactive. More Info: https://www.xda-developers.com/how-a...opment-on-xda/
If my understanding is true then I just need to follow following steps to find the correct image to be used at the first step of flashing the kernel:
fastboot getvar all | grep “current-slot”
dd if="path to boot of active slot" of=/sdcard/boot.img
Continue with boot.img and flash the kernel with above written steps for flashing a kernel.
Anyone who has this knowledge, please confirm. I will be very thankful to you.
A/B OTA update
Firstly, you need to confirm whether your phone is A/B OTA update or not by following command
fastboot getvar slot-count
If the command returns '2', then your phone supports A/B OTA update which means you have two boot
partitions 'boot_a' and 'boot_b', otherwise, there should only be one partition 'boot'
boot image
The images you built (Image.gz-dtb) are just kernel images with device tree. They
are not enough for flashing to boot partition since there should be ramdisk and boot arguments combined.
The ramdisk content contains normal boot binaries for non-A/B OTA system or recovery binaries for
A/B OTA system. You need to find official ramdisk images and combine with your kernel image. Normally
mkbootimg will be used to create boot image in AOSP android.
Flashing
fastboot flash boot boot.img
This works on both A/B and non-A/B system since image will be flashed to default active partition (boot_a
is by default if you do not have OTA or using 'fastboot set_active' to change it)
On A/B system, you can also use 'fastboot getvar current-slot' to get active slot and specific flash
partition 'fastboot flash boot_a boot.img' or 'fastboot flash boot_b boot.img'
XDA provides scripts to flash kernel images (Image.gz-dtb) with following steps:
a. Dump boot.img from your phone
b. Extract ramdisk.img from boot.img
c. Combine Image.gz-dtb with ramdisk.img to new boot.img
d. Flash new boot.img to boot partition
https://forum.xda-developers.com/oneplus-6t/development/kernel-holydragon-t3878107
provides customized kernel and flash scripts, you should check and find your suitable way to flash your kernel image.

Adb backup does not work

I need help from you guys, because I don't know what I did wrong with adb backup.
I want to backup my Samsung Galaxy S3 LTE (GT-I9305) without root. I googled it and found Full Android Backup with SDK Manager. I installed all i need for this like Java Development Kit 8 version 66 (JDK 8u66 x64) and Android Studio which contains SDK Manager. Then they sad i should download the Google USB Driver. I downloaded it but nothing happened. I thought it should work now and then I went to C:\Users\MYNAME\AppData\Local\Android\sdk\platform-tools and left-clicked adb whilst holding Shift. Then I clicked "Open command window here". After this I typed in "adb devices" and it said:
List of devices attached
3204cfaaf8611199 device
Then I typed in:
adb backup -apk -shared -all -f C:\Users\NAME\backup.ab
It said
Now unlock your device and confirm the backup operation.
I did this and my Smartphone opened "Full Backup" and then I was able to set a password for the backup. I don`t need a password and I just clicked "Back up my data" Then it went back to my homescreen and said "Starting backup..." as a toast message and immediately after this it said "Backup finished" and created a backup file with 40 bytes. I don't know what I should do now.
Rather than trying to find an old version of adb, it's easier to add quotes to the arguments to adb backup :
adb backup "-apk -shared -all -f C:\Users\NAME\backup.ab"
The line, which correctly invokes adb, needs to look like this at my side:
adb backup "-apk -obb -shared -all -system" -f phone-20180522-120000.adb
This line is for Linux, but should do for Windows and OS-X as well. For Linux (and probably OS-X), you can use a script like following, which automatically assigns a timestamp to the file:
adb backup "-apk -obb -shared -all -system" -f "${PHONE:-phone}-`date +%Y%m%d-%H%M%S`.adb`"
Important After doing a backup, verify your data! At my side, sometimes some corruption of the file shows up (and I doubt it is my computer, as I only observe such errors with adb).
Here is a check instruction I use:
set -o pipefail
for a in *.adb;
do
echo "$a";
dd if="$a" bs=24 skip=1 | zlib-flate -uncompress | tar tf - >/dev/null;
echo "ret=$?";
done
It should show ret=0, but it doen't.
If you see inflate: data: invalid code lengths set your archive is corrupted and - very likely - unusable for restore!
If you see tar: Unexpected EOF in archive your backup probably is usable (all backups end this way, I do not know why).
Even if you see just ret=0 there might be undiscovered errors which still prevent a restore.
There is definitively missing an adb verify command, to verify correctness of a backup!
FYI
I post this update, as all other answers were helpful, but not exact to the last detail. (When used with full quotes, a backup was done, but called backup.ab)
Here is my environment:
OS: Ubuntu 16.04
Phone: Android 7.0
ADB: 1.0.32
The full procedure was (just in case somebody stumbles upon this not knowing what is needed):
Zeroth: Install adb (on Ubuntu: sudo apt-get install android-tools-adb)
First: Enable USB debugging mode on the phone.
Second: Attach phone to USB of the computer with an USB data cable (a charge only cable is not enough)
Note that the Ubuntu Phone Manager might show up and ask you for the phone's PIN. You do not need that, close this if it happens.
Third: run adb devices - you should see something like XXXXXXXXXXXX unauthorized
After some time on your phone a message shows up which asks for USB debugging permission
Allow this once. For security reasons, you should not automatically trust the computer, as the fingerprint can be easily faked.
Note that if something is obstructing a single pixel of this confirmation window (like some accessibility feature button) you cannot tap on the OK. First move the obstructing window.
Forth: Now again run adb devices - you should see something like XXXXXXXXXXXX device
If more than one line shows up, you attached more than one phone to the computer. The easy way is to unplug all those you do not want to backup. (The complex way is to set the environment variable ANDROID_SERIAL=XXXXXXXXXXXX.)
Now run adb backup as shown above. Change the file to your needs.
This brings up a window which asks for backup permission.
Do not close the backup window while the backup is taken. When I tried this, the backup stopped and the resulting archive was broken.
You can give a password to encrypt your backup. I do not have any information on how secure the password is. But it is very likely, that you cannot restore the backup taken in case you ever forget this password.
I have no idea on how to restore such a backup to other phones. I even never tried the restore, so I cannot help here, too.
Notes:
adb help shows all possible options to adb backup
Close all open applications on your phone before the backup. I do not know if this is needed, but it certainly cannot hurt.
Leave the phone alone while the backup runs. I do not know if this is needed, but it certainly cannot hurt.
Do not be impatient. Leave the backup plenty of time. At my side I see a progress of about 100 MB/Minute (YMMV). So the backup takes about half an hour for my phone (2.5 GB).
Apparently adb backup does not completely backup everything!
I had a look into the backup (cd X && dd if=../XXXX.adb bs=24 skip=1 | zlib-flate -uncompress | tar xf -) and did not find all installed applications.
What I was able to find was (note that this list is incomplete):
Internal emulated SD-Card: shared/0
External SD-Card: shared/1
Apps: apps/ - many apps (like Google Authenticator) were missing
Calendar: apps/com.android.providers.calendar/db/calendar.db (probably)
What I was not able to find (note that this list is incomplete):
Alarms. (I was probably not able to detect the right app)
Full external SD-card (there is more on this card than what is shown below share/1. For example the apps, which are moved-to-SD.)
Conclusions:
Sometimes adb backup might create corrupt backups, which can go unnoticed. So either check your backup or do frequent backups and pretend to be lucky enough such that not all backups go corrupt.
With adb backup you get a backup of most of your precious data, like camera images and so on. It might be a bit difficult to unpack it, though.
adb backup is not enough to do a complete backup of your phone.
adb backup is not enough to backup your SD-card such, that if it breaks, you are able to replace it by a new one with the contents restored. This is very sad!
PS: The typo "Forth" is not an accidental one.
PPS: zlib-flate can be found in package qpdf on Ubuntu 18.04
This just worked using Ubuntu 15.10 ("wily") to backup a Galaxy SM-G900V running Android version 6.0.1.
Installed using:
sudo apt-get install android-tools-adb
Then I ran the following from the command line (without 'sudo'):
adb backup -apk -shared -all -f backup.adb
Result:
user#hostname:~/droid$ ls -lah
total 1.2GB
drwxrwxr-x 2 user user 4.0BK Mar 6 18:43 .
drwxr-xr-x 52 user user 4.0KB Mar 6 17:40 ..
-rw-r----- 1 user user 1.2GB Mar 6 18:29 backup.ab
Thank you "NG". I was beginning to think my phone was borked.
Forgot to add: Running adb version: Android Debug Bridge version 1.0.31
Seem not all apps can be backed up. Android apparently allow apps to disable backup :(
https://developer.android.com/guide/topics/manifest/application-element.html (search for allowbackup)
The problem is the adb version of your PC. Using adb version 1.0.31 the backup/restore will be sucessfull.
More info on: https://android.stackexchange.com/questions/83080/adb-backup-creates-0-byte-file-prompts-for-current-backup-password-even-though
and How to downgrade my SDK Version?
If your device has an adb version prior to 1.0.31, then you must use an adb version of 1.0.31 on PC. Versions of adb 1.0.32+ broken the backwards compatibility. Source: Issue 208337
Just incase anyone is still having trouble - In windows, I found putting the quotes around only the directory, for example "C:\Users\NAME\backup.ab" worked.
I found this solution :
adb backup -apk -shared -all -f "<path-where-the-backup-will-be-created>.ab"
And to restore :
adb restore "<path-where-the-backup-is>.ab"

Make persistent changes to init.rc

I want to change the init.rc file of an android pad. But after I change it and reboot the system, the original init.rc comes back.
How can I make the change to the init.rc persistently without rebuild the system (since I don't have the source code of the system)? Or is there any way to work around?
Unpack the uramdisk using following command in host PC(Linux)
mkdir /tmp/initrc cd /tmp/initrd
sudo mount /dev/sdb1 /mnt
sdb1 is partion where uramdisk/uInitrd resides.
dd bs=1 skip=64 if=/mnt/uInitrd of=initrd.gz
gunzip initrd.gz
At this point running the command file initrd should show:
mkdir fs
cd fs
cpio -id < ../initrd
Make changes to init.rc
Pack uramdisk using following commands:
find ./ | cpio -H newc -o > ../newinitrd
cd ..
gzip newinitrd
mkimage -A arm -O linux -C gzip -T ramdisk -n "My Android Ramdisk Image" -d newinitrd.gz uInitrd-new
A number of Android devices include code to prevent root modifications to the system files. The way this is done is by using the recovery partition. On reboot, they basically restore the system partition using the recovery image. If your system is doing that then you cannot make persistent changes - the best you could do would be to hook up something to run after reboot to re-apply your change. In CyanogenMod they had hooks in the init.rc to run sdcard scripts if found. Perhaps you can create an app or widget to then launch a script to make the mods required using a setuid root script from the data partition. Without building your own ROM you are quite restricted in this area.
Possibly you could fetch the recovery image and try unpacking that, making your changes and repacking and flashing it. But make sure you can recover with fastboot before you try this.
Try this site:
http://bootloader.wikidot.com/linux:boot:android
Read the section at the bottom:
•The Android boot image: boot.img
◦Unpack, re-pack boot image: http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack%2C_Edit%2C_and_Re-Pack_Boot_Images#Background
When an android system boots, uboot unpacks a special compressed ball of files in your boot partition called 'uRamdisk' to RAM, and defines those files to comprise the root directory of the system. uRamdisk normally contains a bunch of directories (system, data, media, etc.) that serve as mountpoints for partitions that contain the files that go in them, but also has some very basic files vital to your system, including the init binary and startup scripts like init.rc.
when you edit the init.rc, you've actually just edited the unpackaged copy of init.rc that resides in your RAM. To really change it then, you have to copy your uRamdisk, extract it, edit the init.rc from there, repackage uRamdisk and then replace the new one with the old one in /boot.
Try looking up the 'xuramdisk' and 'mkuramdisk' scripts, these make the process very simple.
Your root partition (where /init.rc lives) is a ramdisk which is unpacked from an initrd file and mounted every time your device boots. Any changes you make are to the ramdisk only, and will be lost on the next reboot.
If you can get the initrd file, you can mount it on your Linux host system, modify the files there, unmount it, and write it back to your Android.
The initrd file exists in its own partition on the device. If you can figure out which partition it is, you can grab it from the device onto your host, mount it, modify it, and write it back to the device. This is what tripler was talking about above.
In general, modifying boot.img is something that only system developers do. If you're building the entire Android system, you'll have access to the necessary source code. My workflow for this looks like this:
# Modify init.rc
m -j8 bootimage_signed
adb reboot bootloader
fastboot flash boot $OUT/boot.img
fastboot reboot
I don't know if you are still trying to do this but without knowing your exact device nobody can give you an exact answer.
Try taking a dd image of all your internal partitions and use some scripts like those included with android kitchen on xda forums. Your recovery and boot partitions will both have a ram disk but odds are you want to modify the init.rc in the boot.img not recovery, unless you only want the changes present in recovery mode.
The unyaffs thing doesn't apply to all devices and most devices have different partition layouts so you have to figure out which is boot and what type of fs it is. Maybe if you give your device specs you can get a better answer.
Please note that it may be easier for you to use an app like Scripter to run a script at boot time than modify this file.
Before following #tripler's instructions above you need a file called boot.img which can be extracted by (run on rooted Android device, untested without root):
dd if=/dev/block/platform/<someplatform>/by-name/boot of=/sdcard/boot.img
Then connect your Android to your computer and copy the boot.img file from there.
Script:
http://linuxclues.blogspot.ca/2012/11/split-bootimg-python-android.html
Here is a modified, easier to see version of tripler's instructions (assuming boot.img is in tmp):
cd /tmp
mkdir fs
# Now use the linked script above to split the boot.img file into ramdisk.gz and kernel
python split_boot_img.py -i boot.img -o parts
cd fs
gunzip -c ../parts/ramdisk.gz | cpio -id
# make changes to init.rc
At that point you will have to rebuild the boot.img back together before reflashing, which will be device-specific. Can't help you with that, sorry!
You have to edit/change the init.rc before building your Android pad file system. This is the preferred way, and always works.

Is it possible to gain root and/or install BusyBox on the Android Emulator?

It'd be nice to have the "Swiss Army knife" of BusyBox on my emulator. It would also be nice to have full root access. Does anyone have any experience doing this? I'm not familiar with qemu; is this even possible?
Update: The emulator has root by default (accessed via the adb shell command). Does anyone know where I can easily obtain a pre-built busybox binary?
The emulator is not set to secure mode, so it's adb shell should be a root shell.
There are several android builds of busybox, for example cyanogen alternative versions of Android use it to augment toolbox (which is Android's own limited re-implementation of the same concept under a non-gpl license). You should be able to get it from the cyanogen repositories and build it from source, or it's possible that just extracting the binaries from a same-android-version cyanogen update.zip would work (it may be in a compressed file system inside the update though)
There were also some writeups from pioneers who discovered the accidental root shell on the original G1 release and installed quite a bit of debian arm.

Categories

Resources