[Q] Unpacking boot.img from Aorths CM10 - Samsung Galaxy Tab Plus

I wanted to modify one of the kernel init.rc's to switch from nl80211 to wext and help debug the wireless instabilities (can't connect to all of the networks that i frequent).
I found out that these files are inside the ramdisk stored somewhere in the boot.img that is flashed to the boot partition.
So I downloaded the lastest Nov 6th CM10 from aorth (Thanks for all your efforts there!) and tried to unpack the boot.img.
However, the unpack-bootimg.pl/split-bootimg perl scripts that can be found around here fail me.
Taking the file to a hex editor reveals that that is probably expected (no "ANDROID!" header), and i can't find any padded 00000 1F8B myself.
What am I doing wrong? Is it in another format and clockwordmod does something to it before flashing?

Found out it's a zimage. All done. Don't know if my new image works though yet.

If anyone's listening: Turns out that -Dwext does not work. wpa_supplicant says "unknown driver". Might be that wpa_supplicant can't handle it or that the interface just isn't built into the kernel anymore.
As to the zimage:
This tool http://forum.xda-developers.com/showthread.php?t=1294436 works.
Repacked the kernel on an Ubuntu box with the gcc-4.6-arm-linux-gnueabi package as the cross compiler.
Flashed with dd onto mmcblk0p5, which contains the normal boot kernel. (P6200, don't know about any other variants).

i am listening dude, and waiting for your updates. The new driver is not happy with one of my routers, and i would like to use the older one.
Enviado de meu MB525 usando o Tapatalk 2

I re-built the smdk4210 kernel with the cyanogenmod_p6800_defconfig and found WEXT support to be in it.
wpa_supplicant -h reveals that it itself does not support wext. So i figure I should take the wpa_supplicant from an older release (supposedly before Oct 2nd) and see if that helps.

At least on the p6210 the 10/02 release has the old driver.
Enviado de meu MB525 usando o Tapatalk 2

It's done.
So in this archive http://www.quadrant-epsilon.de/cm10-11-06-with-wext.zip you can find the result.
SHA256 eb4dccfe59c141a253c128c8e9f4989573e937c480e6c2f9d5a06186836d10b2 cm10-with-wext.zip
Included is a new boot.img for P6200 and P6210 variants. Kernel is unmodified taken from aorths CM10 Nov 6th archive.
The only change in the boot.img concerns init.smdk4210.rc to have the wpa_supplicant take -Dwext instead of -Dnl80211 as a parameter.
This necessitates an older version of the wpa_supplicant, which I took from aorths CM10 October 2nd archive.
So to install this: Make sure you have some other boot.img ready in case anything goes wrong, in case it wont boot and/or you won't have wireless connectivity anymore.
Transfer the files in the zip to your tab and flash the correct boot.img via console:
dd if=cm10-11-06-p62X0-new.boot.img of=/dev/block/mmcblk0p5
(terrible things might happen if you get that last number wrong, I hope it's correct also for the P6210?)
Save your old /system/bin/wpa_supplicant in case you need to revert to it.
Then overwrite /system/bin/wpa_supplicant with the included wpa_supplicant_new
Reboot.
Note: This is only a nasty workaround for a problem in the wireless driver, the wext driver is deprecated and shouldn't be used anymore. You shouldn't use this if don't have problems with nl80211. For me, this workaround enables me to connect to an older, probably not very standard-conform router that the nl80211 interface can't cope with (yet).
Only tested on the P6200 variant!

Thanks buddy, it worked great. I have flashed the 11/06 cm, flashed the boot.img with mobile odin and replaced the wpa bin. Now my tab and old router are talking.
By the way, do you think it's possible to mount and access the boot partition directly on the tab? I think it would be easier to change that very script.

The boot partition does not contain a normal filesystem, instead it is a kernel image with a built-in initramfs. I don't think there is any filesystem-handler for that even on normal linux boxes, and putting it back together needs an ARM compiler in any case. So it's not easily done on the phone/tablet itself.

nightflier2 said:
Found out it's a zimage. All done. Don't know if my new image works though yet.
Click to expand...
Click to collapse
\o/ I do undestand that bit now. the boot.img IS the the direct file(zImage) to be used with the tool you recommended.
nightflier2 said:
The boot partition does not contain a normal filesystem, instead it is a kernel image with a built-in initramfs. I don't think there is any filesystem-handler for that even on normal linux boxes, and putting it back together needs an ARM compiler in any case. So it's not easily done on the phone/tablet itself.
Click to expand...
Click to collapse
Got it, did all the steps editing the files and recompiling the boot.img and now i am enjoying the new CM version.
Thanks again

For those who can't do it themselves:
Updated boot images for both variants, based on Aorth's Nov 26th build: http://quadrant-epsilon.de/cm10-11-26-with-wext.zip

Related

[Q] Porting AOSP (Froyo) to G Tablet

Hello,
First of all, I am not attempting to compete with the other awesome images for the G Tablet available. I am doing this process to learn, and maybe contribute to the community.
I have grabbed the AOSP directly from Google's repo tree, and compiled it in two different ways: Generic build, modifying BoardConfig.mk and other files as necessary. I have also used the Device/Vendor files from the Cyanogen Beta 4 harmony repo tree, and compiled a harmony target with AOSP.
When I compiled the generic build (or the the targeted build), I made sure all proprietary files from the tablet had been extracted and replaced in my system.img. (I got this list from the extract-files.sh script in Cyanogen harmony repo).
I have found that using the stock boot.img from the original nvflash files will boot nearly any system.img (from my update.zip in clockwork). I used this original boot.img, combined with my system.img from the AOSP build (with the proprietary files in place), and made an updater-script which installed things. I found that the system.img was properly extracted to /system.
The problem that occurs -- when booting, the Viewsonic bootup screen will load the GTablet screen, but it will eventually loop back to the Viewsonic screen and report "deleting msc" prior to returning to Recovery Mode on it's own.
I have enabled ADB persistence in the boot ramdisk, and it works fine as long as it's not my system.img. When I use the AOSP system.img, adb devices shows the device, but adb shell/logcat fail until the device power cycles.
Does anyone know what I might be missing?
Also want to add:
I have tried the stock boot.img, which lacks a 'cmdline' parameter, and I have tried using the cmdline parameters from the Cyan Harmony boot.img specifications. I am not sure if this might have something to do with the issue or not.
kornyone said:
Hello,
First of all, I am not attempting to compete with the other awesome images for the G Tablet available. I am doing this process to learn, and maybe contribute to the community.
I have grabbed the AOSP directly from Google's repo tree, and compiled it in two different ways: Generic build, modifying BoardConfig.mk and other files as necessary. I have also used the Device/Vendor files from the Cyanogen Beta 4 harmony repo tree, and compiled a harmony target with AOSP.
When I compiled the generic build (or the the targeted build), I made sure all proprietary files from the tablet had been extracted and replaced in my system.img. (I got this list from the extract-files.sh script in Cyanogen harmony repo).
I have found that using the stock boot.img from the original nvflash files will boot nearly any system.img (from my update.zip in clockwork). I used this original boot.img, combined with my system.img from the AOSP build (with the proprietary files in place), and made an updater-script which installed things. I found that the system.img was properly extracted to /system.
The problem that occurs -- when booting, the Viewsonic bootup screen will load the GTablet screen, but it will eventually loop back to the Viewsonic screen and report "deleting msc" prior to returning to Recovery Mode on it's own.
I have enabled ADB persistence in the boot ramdisk, and it works fine as long as it's not my system.img. When I use the AOSP system.img, adb devices shows the device, but adb shell/logcat fail until the device power cycles.
Does anyone know what I might be missing?
Click to expand...
Click to collapse
Did you ever get your AOSP build to boot?
tjohnsonjr said:
Did you ever get your AOSP build to boot?
Click to expand...
Click to collapse
I did. It's in the Dev section now

[PATCHES] Kexec syscall support, boots kernels from SD or USB (11/6/11, GB support)

11/6/11 Update: Added statically-linked kexec to kexec_patches.tar.gz and example update.zips. Now works in stock recovery and CM7 CWM (with a kexec-patched kernel).
10/19/11 Update: Added patches for the recently released GB sources to kexec_patches.tar.gz.
Attached is a set of patches (kexec_patches.tar.gz) against EC05, and the recently released GB sources, to implement kexec syscall support in the Epic's kernel. kexec enables the booting of kernels "directly" from the SD card or over USB without having to flash them to the device first. This allows us to easily use, test, and switch between many kernels, not just the one (two with recovery) there's room for on flash.
When used in conjuction with modified init.rc scripts, this allows entire ROMs (with their own kernels) to run from SD card. In short, this allows us to run custom-kernel ROMs (e.g,. CyanogenMod) alongside each other or a stock kernel without having to flash back and forth.
Also attached is a modified version of the kexec userspace tool (also in kexec_patches.tar.gz, along with source and patches) that facilitates the proces of loading and kexecing a kernel image. Finally, attached is a demo EC05 kernel with kexec enabled (demo_kernel.tar.gz; mostly stock: RFS support only, testkeys recovery w/adbd, but does inlcude the keyboard patches), example update.zips that kexec an SD-card kernel from recovery--either as a normal boot (boot_zImage.zip) or recovery boot (boot_zImage_recovery.zip), and a script (patch_decomp_cachebufram.sh) to binary patch unmodified kernels to kexec boot faster.
Note, this thread is primarilly intended for kernel developers. Kexec probably won't be of great utility to end users until commonly-used kernels are patched. Also, although stock kernels can be kexec'd, they need some init.rc modifications boot an entire ROM from SD card. Hopefully the fine folks here will come up with a user-friendly implementation of this work that's easy for everyone to use.
Instructions:
Flash a kexec-enabled kernel (e.g., the attached demo kernel) to either /dev/block/bml7 or /dev/block/bml8. For testing purposes, this kernel needs either "ro.secure=0" or "ro.debuggable=1" set in default.prop, and also needs recovery.rc/fota.rc modified to spawn the adbd service, so that an adb root shell is available while in recovery. Also copy the attached kexec tool to a convenient location on the device (e.g., /data/local/tmp/kexec).
Reboot into recovery. If the kexec kernel is installed to bml7, run "adb reboot recovery" while the phone is running. If installed to bml8, power down and boot into recovery by holding the volume-down, camera, and power buttons.
Make sure adb is running as root. If it's not, try running "adb root".
Find the kernel (zImage) you wish to boot. These can be extracted from a kernel update.zip or Odin .tar file, or use the demo kernel again.
Push the zImage into RAM (tmpfs) with:
Code:
adb push zImage /tmp
Now, open an adb root shell with "adb shell" and run the commands:
Code:
mount -ro remount /dev/block/stl6 /mnt/.lfs
mount -ro remount /dev/block/stl9 /system
mount -ro remount /dev/block/stl10 /data
mount -ro remount /dev/block/stl11 /cache
/data/local/tmp/kexec --load-hardboot --mem-min=0x50000000 --append="console=ttySAC2,115200 loglevel=4" /tmp/zImage
sync
/data/local/tmp/kexec -e
after which the phone will reboot, show the SAMSUNG logo, and eventually boot the kexec'd kernel. Do note that when booting unmodified kernels (see below), the SAMSUNG logo will persist for ~30 seconds longer than usual.
Also note that kexec performs an "abrupt" reboot, i.e., it doesn't shutdown the system normally. Hence it's important to kexec from recovery where few services are running. It's also prudent to remount file systems read-only and sync them to avoid any potential (although unlikely) of corruption.
In the future, kexec could be better integrated into the Android framework to allow for a clean shutdown. Otherwise, probably the best way to deploy kexec is through an update.zip file that boots a kernel from the SD card. See the attached example update.zips.
Technical details:
kexec is feature of Linux that allows it to directly execute (boot) a new kernel in place of itself, allowing Linux to effectively serve as its own bootloader.
The kexec procedure is two step. The first "kexec" command loads a zImage from disk, constructs parameters (e.g., the kernel command line), and stages it in memory, after which Linux continues to run as normal. The second "kexec" command tells Linux to execute (boot) the staged kernel.
In the standard implementation, Linux "soft boots" kexec'd kernels. That is, on "kexec -e" the running instance of Linux shuts-down all devices, drivers, and goes through the process of unloading itself as it does during a normal reboot. However, instead of invoking a hardware reboot, Linux, at the final stage of unloading itself, jumps to start executing the new kernel.
This soft boot process requires that Linux hardware drivers are fully capable of unloading, reloading, and reinitializing the associated hardware without hardware-reboot or bootloader assistance. Since, for many built-in drivers, this capability is only used by kexec, hardware is often left in an unexpected or unknown state on unload, and thus the kexec'd kernel hangs on boot. Unfortunately this is the case with the Epic kernel, and soft booting doesn't work.
To work around this, the attached patches implement a "hard boot" method for kexecing kernels. Here, we use kexec to stage a kernel in memory as usual. On "kexec -e", Linux shuts-down as before, and at the very end of the unloading process it does two things: (i) scribble some information on how to boot the kexec'd kernel to a "special place" in memory, and (ii) performs a hardware reboot, invoking the Epic bootloader as a normal reboot does.
On reboot, the bootloader loads the (previously-running) bml7 or bml8 kernel and starts executing it. Here, the hardboot patch modifies the Linux the zImage decompressor code to check the "special place" in memory to see if we're actually kexecing a different kernel. If so, it switches over to the other kernel, already staged elsewhere in memory.
Known Issues:
Kernel Command Line:
Kexec (via hardboot) can boot stock or non-kexec-modified custom kernels. However, unless the copy_atags patch is applied, they can only use the kernel command line provided by the bootloader, as opposed to the custom command line provided by kexec. Although this isn't a problem when kexecing from a bml7 boot kernel, kexecing from a bml8 kernel runs recovery (fota.rc) instead of a normal boot (init.rc).
With the copy_atags patch, the command line for the kexec'd kernel must be provided by with kexec's --append option. These are the command lines provided by the bootloader in normal boot and recovery scenarios, any of which may be used:
Code:
Normal boot (init.rc):
console=ttySAC2,115200 loglevel=4
"adb reboot recovery" (recovery.rc):
bootmode=2 console=ttySAC2,115200 loglevel=4
Three-finger recovery boot (fota.rc):
bootmode=3 console=ttySAC2,115200 loglevel=4
Slow Booting:
Kexec booting of a stock or non-kexec-modified custom kernel is known take significantly longer than a regular boot, sitting at the SAMSUNG logo for 35 seconds instead of 8. The decomp_cachebufram patch resolves this issue for modified kernels. In addition, the attached patch_decomp_cachebufram.sh script will binary patch the decompressor code for any (to my knowledge) Epic kernel.
Many more details on the patches themselves are in the accompanying READMEs.
Mirror links:
Kernel & kexec-tools patches: kexec_patches.tar.gz
Kexec EC05 demonstration kernel: demo_kernel.tar.gz
Recovery script to boot /sdcard/zImage (normal boot): boot_zImage.zip
Recovery script to boot /sdcard/zImage (recovery boot): boot_zImage_recovery.zip
Script to binary patch decompressor code: patch_decomp_cachebufram.sh
Is this different in function than rodderik's dual boot support?
I know his didn't include usb booting support, but sdcard booting appears to be the same...although this seems a little cleaner, possibly
Sent from my SPH-D700 using xda premium
squshy 7 said:
Is this different in function than rodderik's dual boot support?
I know his didn't include usb booting support, but sdcard booting appears to be the same...although this seems a little cleaner, possibly
Sent from my SPH-D700 using xda premium
Click to expand...
Click to collapse
His uses a modified init, which then choses to load which init.rc, the one names init.rc.sdcard or normal init.rc. This (kexec method) reminds me A LOT like how they ran linux/android on winmo devices...it shuts down android and then runs the kernel they want (if I read correctly).
squshy 7 said:
Is this different in function than rodderik's dual boot support?
I know his didn't include usb booting support, but sdcard booting appears to be the same...although this seems a little cleaner, possibly
Sent from my SPH-D700 using xda premium
Click to expand...
Click to collapse
Yes. The genocide implementation allows a ROM to boot from the sd card as long as the kernel on the main ROM supports the sd ROM. this means you cannot dual boot a gingerbread and a froyo ROM because the need different kernels .
With this patch that limitation is removed as the sd based ROM can use its own separate kernel. This you may run stock ec05 and keep cyanogen or a gingerbread on the sd card to test and play with.
Great work mkasick
Sent from my SPH-D700 using Tapatalk
I was never interested in the dual boot feature since that was ROM's only and itwas limited by kernel support.
But now this really interest me, can't wait till we see some developers take advantage of this.
Sent from my SPH-D700 using xda premium
All I have to say is hope you stick with the epic your amazing
Sent from my SPH-D700 using Tapatalk
Yes, this is complementary to Rodderik's dual boot. Kexec allows one to load a different kernel, but it still defaults to booting the ROM stored in flash. Which is great for kernel testing, but not of much use otherwise.
It's easy enough to modify a kernel to load a ROM only from SD, but then we'll start seeing a divide between "bml kernels" and "SD kernels", when really it'd be nice to have init scripts that support both. That's where Rodderik's work comes in.
Probably the best is to have a kernel command line parameter that specifies where the ROM is located, so it can be passed in. Something like "console=ttySAC2,115200 loglevel=4 systemfs=mmcblk0p2 datafs=mmcblk0p3 cachefs=mmcblk0p4". These would default to stl9, stl10, stl11 respectively if unspecified. The kernel command line is available to init through "/proc/cmdline", and it's easy enough to parse in a shell script.
But yes, keeping a working ROM on flash while testing/debugging CyanogenMod was my primary motivation, since I need a working phone "during the day" and can't touch CyanogenMod otherwise.
formula84 said:
All I have to say is hope you stick with the epic your amazing
Click to expand...
Click to collapse
Thanks!
I'm much of a year out on a full upgrade, and I'm not considering a new device sooner as long as my Epic still works.
Edit: An obvoius limitation is modem compatibility. I've avoided the GB leaks thus far, so I'm not sure what's the status with that. But if GB supports the EC05 modem, then you can dual boot EC05 and GB-whatever. Same if EC05 supports newer modems.
Speaking of which, anyone know what GB modem compatibilty is like?
mkasick said:
Yes, this is complementary to Rodderik's dual boot. Kexec allows one to load a different kernel, but it still defaults to booting the ROM stored in flash. Which is great for kernel testing, but not of much use otherwise.
It's easy enough to modify a kernel to load a ROM only from SD, but then we'll start seeing a divide between "bml kernels" and "SD kernels", when really it'd be nice to have init scripts that support both. That's where Rodderik's work comes in.
Probably the best is to have a kernel command line parameter that specifies where the ROM is located, so it can be passed in. Something like "console=ttySAC2,115200 loglevel=4 systemfs=mmcblk0p2 datafs=mmcblk0p3 cachefs=mmcblk0p4". These would default to stl9, stl10, stl11 respectively if unspecified. The kernel command line is available to init through "/proc/cmdline", and it's easy enough to parse in a shell script.
But yes, keeping a working ROM on flash while testing/debugging CyanogenMod was my primary motivation, since I need a working phone "during the day" and can't touch CyanogenMod otherwise.
Thanks!
I'm much of a year out on a full upgrade, and I'm not considering a new device sooner as long as my Epic still works.
Edit: An obvoius limitation is modem compatibility. I've avoided the GB leaks thus far, so I'm not sure what's the status with that. But if GB supports the EC05 modem, then you can dual boot EC05 and GB-whatever. Same if EC05 supports newer modems.
Speaking of which, anyone know what GB modem compatibilty is like?
Click to expand...
Click to collapse
As far as I know, and from experience, modems are a free for all except for bonsai. Ec05 modem works on gb, leaked modems work on ec05.
this is definitely very cool, thanks mkasick!
Sent from my SPH-D700 using XDA Premium App
mkasick you never cease to amaze me...i'll definately play with this, this week if i have the time!
Rodderik said:
mkasick you never cease to amaze me...i'll definately play with this, this week if i have the time!
Click to expand...
Click to collapse
Great!
If you run into something not particularly straight forward, or think there's something I can clarify, please ask. I've been playing around with this long enough that I fear I might've overlooked documenting a detail or two that would be helpful for others.
So to patch any kernel u just point the script to the zImage?
sent from my epic 4g. with the key skips.
ugothakd said:
So to patch any kernel u just point the script to the zImage?
Click to expand...
Click to collapse
The script only implements one patch, it allows any kernel to boot ~30 seconds faster when kexec'd.
But yes, "./patch_decomp_cachebufram.sh zImage" modifies that zImage to boot faster. It requires the xxd hexdump tool that's packaged with vim.
Kexec support itself, along with the slew of other source patches, has to be applied to a kernel source tree, from which a new kernel must be built to take advantage of them.
mkasick said:
The script only implements one patch, it allows any kernel to boot ~30 seconds faster when kexec'd.
But yes, "./patch_decomp_cachebufram.sh zImage" modifies that zImage to boot faster. It requires the xxd hexdump tool that's packaged with vim.
Kexec support itself, along with the slew of other source patches, has to be applied to a kernel source tree, from which a new kernel must be built to take advantage of them.
Click to expand...
Click to collapse
I see...so its a no-go for gb. Or at least quick gingerbread.
sent from my epic 4g. with the key skips.
ugothakd said:
I see...so its a no-go for gb. Or at least quick gingerbread.
Click to expand...
Click to collapse
You should be able to kexec a GB kernel, but you'd need an EC05-ish /system on flash to boot recovery. Unless GB recovery is compatible with Froyo kernels.
If you're going to boot a GB kernel, you'd probably want to repackage the initramfs with an init.rc that loads the rest of the GB ROM off SD. It's actually not a bad way to keep EC05 around for a stable, working phone, and to test GB leaks as they happen. Which, hopefully, shouldn't be much longer.
wow mkasick, you never cease to amaze me bro...
I wish I wasn't working so many damned hours now, with your patches, I really want the dual boot now. Like you, the need for a working phone at all times is what keeps me from flashing more ROMs, including EpicCM and the gb leaks...
I hope Rodderik figures this out pretty quickly, as most of my dev time is spent on the IRC channels, and he's usually around to help and answer questions.
Once I can get my Clean Kernel working with this, I'll be stoked... I have had a tough time dealing with patches thus far, I usually git cherry-pick and/or manually edit, so I need to figure out how to use the patches correctly.
Anyways, gotta go to work now (I'm working 50+ hour weeks now, hence the time constraints), but hopefully I can get the time to get it into my kernel.
Thanks, mkasick!
Sent from my Samsung Epic4G
DRockstar said:
I have had a tough time dealing with patches thus far, I usually git cherry-pick and/or manually edit, so I need to figure out how to use the patches correctly.
Click to expand...
Click to collapse
What environment (OS, etc.) are you using? Is the "patch" utility working for you?
The patches are split up based on functionality. In each patch directory there's a "series" file that lists the order they should be applied. There's a program, quilt that can help manage them but it's not necessary. If you're running a bourne shell (e.g., bash) in the "Kernel" directory of the kernel sources, you should be able to apply the patches with:
Code:
while read i; do patch -p 1 < "/path/to/kexec_patches/kernel-EC05/$i"; done < "/path/to/kexec_patches/kernel-EC05/series"
Whether they'll apply cleanly or not is a different story, but that's the general idea.
And yeah, time ....
Thank you mkasick, that's a great explanation, I think I can handle that, much appreciated!
For the record, I compile by ssh into dev boxes donated for dev use. They all run linux in different distros. I find this most convenient since I can do most everything from the command line using your brilliant connectbot for epic
Sent from my Samsung Epic4G
With those recovery scripts, doesn't Clockwork Mod have to have kexec set up?
ugothakd said:
With those recovery scripts, doesn't Clockwork Mod have to have kexec set up?
Click to expand...
Click to collapse
You mean for boot_zImage_recovery.zip to work?
The CWM kernel doesn't need full kexec support in order to be booted via kexec. But it does need the copy_atags patch in order to respect the "bootmode=3" kernel argument.
Actually, you can take any existing Epic kernel and somewhat-easily fix it to be bootable via kexec. Steps are:
1. Extract EC05 kernel sources. Or use the GB sources, it doesn't matter, it doesn't even have to match the version of the kernel you're fixing.
2. Apply "decomp_cachebufram" and "decomp_copy_atags" patches.
3. Build a kernel. Config options don't matter much since this kernel is going to be thrown away.
4. Find the zImage for the kernel you want to fix. Run:
Code:
skip=`grep -Fabom 1 $'\x1f\x8b\x08' zImage | head -n 1 | cut -d : -f 1`
dd if=zImage bs=1 skip="$skip" | gunzip > Image
cp Image arch/arm/boot/Image
which extracts the decompressed kernel payload from the zImage, and replaces the "Image" that was previously built with the one you've extracted.
5. Run "make" in the kernel source directory again. You might have to append a "CROSS_COMPILE=" path to match the one used in a build script. The output should be:
Code:
CHK include/linux/version.h
make[1]: `include/asm-arm/mach-types.h' is up to date.
CHK include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-arm
CALL scripts/checksyscalls.sh
CHK include/linux/compile.h
Kernel: arch/arm/boot/Image is ready
GZIP arch/arm/boot/compressed/piggy.gz
AS arch/arm/boot/compressed/piggy.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
Building modules, stage 2.
MODPOST 13 modules
which shows that the build process took the existing, extracted Image, compressed it, and attached a new kexec-compatible decompressor to it.
The resulting "arch/arm/boot/zImage" can be kexec'd, and command line arguments should be respected, e.g., if you want to boot into CWM recovery.

[Q] GT-I9000M kernel compiling

I've got this side project going where I've decided to try to modify the stock kernel for my GT-I9000M.
I'm a Gentoo linux user and have cross-compiled kernels for embedded systems with or without initramfs and modules successfully many times. Rather than just grab and flash the latest mod from the net I want to understand exactly how to create my own.
I already have access via a chroot to a working Gentoo install, however that runs in a sandbox inside android userland, which can be irritating to say the least. I'm already able to create binaries for armv7a on the phone itself, which is a time and power-consuming novelty.
I setup a development environment on my main computer and made sure I could create working binaries for the armv7a.
I backed up all the bml partitions on my phone.
Next, I made sure I could access Download Mode and experimented with Heimdall until I was satisfied I was able to recover from any bad kernel flashes.
I altered the first boot logo in param.lfs with dd, but that's a whole other story.
Next, I downloaded Samsung's source for Froyo and followed the instructions to create a zImage.
aries_eur_defconfig selects the FM radio module and the Samsung TV out driver which are broken. No problem, I figured I could check that out later so I disabled those options for now. it compiles! great! But it didn't boot. I turned to the internet for ways to solve the problem.
There was a lot of conflicting information. I ended up trying a lot of different approaches, modules, firmware, version info, kernel command lines, fbcon... well I messed around.
Some time later, I find myself happily booting with my own kernel. The bootloader displayed my custom logo in param.lfs, but fbcon didn't work and I got a stock samsung gt-i9000 logo before android booted up! The phone worked, wifi worked, bluetooth worked, it was awesome (for 2.6.32.9 that is )!
So, great! Except I got overconfident and cocky. I made a slew of changes trying to get fbcon to work and to top off the evening I overwrote my working zImage with a broken kernel (without a backup of my working custom zImage or .config). I still have backups otherwise of course and haven't lost the functionality of my phone in any way, but now I'm just irritated.
Anybody else working on compiling from source on the GT-I9000M?
I pressed ahead and tried to recreate the conditions that got me a working kernel and as of yet I've been unsuccessful Luckily I've got a kmsg from the kernel when it booted. I can see the kernel command line on the custom kernel that booted was simply "console=ttySAC2,115200" although I do recall trying different values for init= ... The default init in the sources is /linuxrc which doesn't exist in initramfs.
There are also settings for the kernel command line and version information in arch/arm/mach-s5pv210/include/mach/param.h
Is there a known good method to compile from Samsung's sources?
I unpacked a known good zImage, played with it's initramfs, repacked it and it boots just fine.
I've tried again with a fresh copy of the gt-i9000 froyo-samsung branch:
- unpack initramfs from a known good 2.6.32.9 kernel
- make clean
- make aries_eur_defconfig
- make menuconfig, add initramfs, remove Samsung TV driver and FM radio module
- make
the resulting vmlinux is: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped (I know, it's zImage not vmlinux but I'm just doing sanity checks)
I have a custom logo in param.lfs which always displays on boot. A second logo is compiled into the kernel, and I do see a change in the logo when my kernel boots (it shows GT-I9000 instead of GT-I9000M after the first logo). This leads me to believe that the kernel is booting... but the phone powers off after booting.
I've tried the recommended changes to default.prop to use adb to obtain the kmsg of the new kernel. This has not worked however, which could mean that the kernel doesn't get as far as initramfs.
the kernel command line from the kmsg I have from the one time that a custom kernel of mine booted is simply: "console=ttySAC2,115200 loglevel=4" . There's no mention of init, which I think should be init=/init although aries_eur_defconfig seems to think that init=/linuxrc is appropriate (linuxrc doesn't exist?) Regardless, it doesn't seem to matter what I specify for init.
Which leaves proprietary Samsung kernel modules. If they can't load, this could explain everything I'm experiencing. It isn't clear what specific version the proprietary modules are expecting.
Maybe this will help somebody else. I've got it working now.
Attached is my working config.

[ROM][UNOFFICIAL] LineageOS 17.1 for Unihertz Atom L (20200828)

Introduction
This thread contains the LineageOS 17.1 custom firmware images for the Unihertz Atom L, a rugged Android phone released by Unihertz in July 2020, and the accompanying LineageOS Recovery used for flashing the firmware.
Please note that this ROM is one of my side projects, for which I could provide zero warranty. By installing this ROM, you acknowledge that you take all the risks that come with installing custom firmwares on your devices, including but not limited to bricking your device, losing your data, etc. You are always suggested to keep backups and make sure you know how to flash back to official ROM before trying any custom ROMs.
Please find the download links in the Download section. The following sections are guides to installing the ROM.
WARNING: DO NOT try to install this on Atom XL. This is ONLY for the Atom L.
Working Features
- All basic features (Telephony, VoLTE, Audio, Camera, NFC, WiFi, Bluetooth, ....)
- Programmable PTT (red) button (Functionality can be set in Settings - System - Buttons, under the "Search Button" section)
- 48MP camera seems to be working (unlike on many other super resolution devices)
Known Issues
- VoLTE is working (at least for me) but sometimes quirky. If you find it somehow stopped working, usually turning it off and back on again (in Settings - Network - Mobile Network) will fix it. Putting the device to SELinux Permissive mode also fixes most of the VoLTE quirks but this is not recommended (a few quirks in Enforcing mode is better than having the whole device Permissive)
Unlocking
1. Boot your Atom L to the official OS
2. Go into Settings - About phone, tap "build number" several times to enable developer settings
3. Go to Settings - System - Developer Settings, enable OEM unlocking and ADB debugging
4. Run `adb reboot bootloader` on your PC (there is no way to enter bootloader directly, only possible through adb)
5. Run `adb flashing unlock` and comfirm unlock on device (THIS WILL WIPE ALL DATA)
6. Reboot and now you should see an unlocked warning during boot screen.
Installing LineageOS Recovery
For now the only working recovery is the LineageOS Recovery, because the device's kernel does not load the touch driver in recovery mode for whatever reason, rendering TWRP useless.
1. Download `lineage_recovery_XXX.img` and `vbmeta.zip`, unpack `vbmeta.zip` to get three .img files starting with `vbmeta`
2. Run `adb reboot bootloader` to put your device in bootloader mode
3. Run `fastboot flash --disable-verification --disable-verity vbmeta vbmeta.img`
4. Run `fastboot flash --disable-verification --disable-verity vbmeta_system vbmeta_system.img`
5. Run `fastboot flash --disable-verification --disable-verity vbmeta_vendor vbmeta_vendor.img`
6. Run `fastboot flash recovery lineage_recovery_XXX.img`
7. Run `fastboot reboot recovery` to reboot into the newly-installed LineageOS Recovery
The LineageOS Recovery is operated by volume keys as selection and power as confirmation (or entering sub-menus). To return to upper levels of menus from sub-menus, press volume up until the selection goes to the first item and then disappears, then press power (i.e. there's a hidden "Go Back" item at the very top of each sub-menu).
The recovery will show a verification failed prompt for most packages that are not signed with the AOSP keys. This is safe to ignore.
Installing LineageOS 17.1
The LineageOS image must be installed via LineageOS recovery.
1. Download `lineage-17.1-Atom_L-XXX.zip`
2. Reboot your device into recovery (`adb reboot recovery` or simply hold volume up while turning power on)
3. Wipe all data (factory reset) (THIS DELETES EVEN INTERNAL STORAGE)
4. Choose Apply Update, then Apply Update from ADB
5. Run `adb sideload lineage-17.1-Atom_L-XXX.zip` from your PC
6. Wait for the process to finish. (The recovery might prompt something about verification failure, just ignore it and continue anyway)
7. At this point, you can then sideload the LATEST Magisk and OpenGAPPS Nano at your will (note that the size of the system partition might only be enough for the `nano` variant of OpenGAPPS) (If installing Magisk / OpenGAPPS fails, you can try rebooting into recovery again in advanced menus, then try installing them again)
8. Reboot into system and enjoy (Note that Magisk might cause your device to boot loop once or two but it will eventually boot)
When updating to a newer build, you have to flash the new zip, and then re-flash whatever mod you have installed previously (Magisk / GAPPS).
Download Links
LineageOS:
lineage-17.1-Atom_L-20200828-peter-signed.zip: https://mega.nz/file/bAgh1BZA#jzMs_0e9NUR9NcALXWp51ZeWttM5rl_3K5T8Or9hAW0
- Synchronized updates from LineageOS upstream.
lineage-17.1-Atom_L-20200728-peter-signed.zip: https://mega.nz/file/vBwlmL5D#wpw8RovBHyVFCLFlhQ2H5QAIb0ECXkT4of0FRijiP6A
LineageOS Recovery:
lineage_recovery_20200728.img: https://mega.nz/file/yc4Dnbyb#yx0Ci9p3q9_lfAiXkGfgWDFnRJI-JSGrv3kyawkU3fw
vbmeta:
vbmeta.zip: https://mega.nz/file/nF51mBoY#ZNY4j92wc_6a1dXch3l5r-w4VFl9QjN7YJaRMKRoEGk
XDA:DevDB Information
LineageOS 17.1 for Unihertz Atom L, ROM for the Android General
Contributors
PeterCxy
Source Code: https://cgit.typeblog.net/android/device/unihertz/Atom_L/
ROM OS Version: Android 10
Version Information
Status: Alpha
Created 2020-07-28
Last Updated 2020-07-28
How different is the Atom XL?
PeterCxy said:
Introduction
WARNING: DO NOT try to install this on Atom XL. This is ONLY for the Atom L.
Unfortunately I've got the XL version which I thought only varied from the L by the presence of a UHF radio! Can you explain to me why its not a suitable candidate for your mods which sound very good!?
And before you ask, I only got this radio for hacking so I don't mind experimenting if that is required. Please let me know if I can help.
The Bitfarmer
Click to expand...
Click to collapse
tvroman said:
PeterCxy said:
Introduction
WARNING: DO NOT try to install this on Atom XL. This is ONLY for the Atom L.
Unfortunately I've got the XL version which I thought only varied from the L by the presence of a UHF radio! Can you explain to me why its not a suitable candidate for your mods which sound very good!?
And before you ask, I only got this radio for hacking so I don't mind experimenting if that is required. Please let me know if I can help.
The Bitfarmer
Click to expand...
Click to collapse
Because Unihertz publishes completely different firmware files for the L and XL, so the safest assumption is that there is more difference than just the UHF radio. If you want to risk it, then you CAN try using this ROM on the XL, as long as you know how to revert back to official if things go wrong. (But I cannot guarantee if the kernel image from L that this ROM uses will not cause serious issues like corrupted baseband or something on the XL)
My suggestion is that instead of trying this ROM directly on the XL, someone with XL can try to modify my device tree for L, replacing the kernel, dtbo images and other vendor blobs from the ones from XL, and then re-compile the ROM for XL. This would be the proper way to handle these two devices.
Click to expand...
Click to collapse
Going XL
Hi.
Great work. :good:
I want to built a ROM for the Atom XL myself. And because I'm no expert on this (for now) I'm in search of guides and hints on how to achieve my goal.
As far as I know the biggest problem with Unihertz is that they use a Mediatek chipset with which they are not allowed to provide the sourcecode of the kernel. Or at least you have to pay for it from Mediatek.
But there are some variants of the chipset (Helio P60; mt6771) used in other mobile phones (e.g. Nokia X5) for which I was able to find kernelsources on Github. Using these and the latest Android kernel from google I tried to compile a kernel as a starting point. I was able to extract the build.config directly from the phone which helped tremendously. This should at least get me to the point where I'm able to assemble a TWRP build. But I believe that I'm still missing some (vital?) drivers which are specific to the actual device. This includes I think the missing touchscreen driver that you mentioned is preventing the recovery to be useful.
So now I'm a little bit stuck, because most of the guides to arrange a LineageOS (or any other custom ROM) build tree I found require the sourcecode from the manufacturer which we don't have. All other guides to build from scratch were too generic for my current level of expertise.
Can you please share your approach to create this build?
If you don't want to do this in the open you could also PM me.
With kind regards
ADT
a-dead-trousers said:
Hi.
Great work. :good:
I want to built a ROM for the Atom XL myself. And because I'm no expert on this (for now) I'm in search of guides and hints on how to achieve my goal.
As far as I know the biggest problem with Unihertz is that they use a Mediatek chipset with which they are not allowed to provide the sourcecode of the kernel. Or at least you have to pay for it from Mediatek.
But there are some variants of the chipset (Helio P60; mt6771) used in other mobile phones (e.g. Nokia X5) for which I was able to find kernelsources on Github. Using these and the latest Android kernel from google I tried to compile a kernel as a starting point. I was able to extract the build.config directly from the phone which helped tremendously. This should at least get me to the point where I'm able to assemble a TWRP build. But I believe that I'm still missing some (vital?) drivers which are specific to the actual device. This includes I think the missing touchscreen driver that you mentioned is preventing the recovery to be useful.
So now I'm a little bit stuck, because most of the guides to arrange a LineageOS (or any other custom ROM) build tree I found require the sourcecode from the manufacturer which we don't have. All other guides to build from scratch were too generic for my current level of expertise.
Can you please share your approach to create this build?
If you don't want to do this in the open you could also PM me.
With kind regards
ADT
Click to expand...
Click to collapse
You don't need the kernel source code to build a working ROM -- just look at my device tree for Atom L. I think you can build a working ROM for the XL by just replacing the prebuilt kernel in my device tree with the one from Atom XL and also re-extracting the vendor blobs from XL using the script in my devcie tree, then rename everything to Atom XL instead of L. I don't know if the integrated amateur radio would still work though.
PeterCxy said:
You don't need the kernel source code to build a working ROM -- just look at my device tree for Atom L. I think you can build a working ROM for the XL by just replacing the prebuilt kernel in my device tree with the one from Atom XL and also re-extracting the vendor blobs from XL using the script in my devcie tree, then rename everything to Atom XL instead of L. I don't know if the integrated amateur radio would still work though.
Click to expand...
Click to collapse
I'm already on to that.
But I seem to have trouble extracting the prebuilt kernel. None of the tools I found gave me the exact files you have got (dtb.img, dtbo.img, Image.gz). What did you use?
The best I could get were "dtb", "kernel" and "dtborecovery" (without extensions) which roughly had the same size as yours.
Also, as far as I understand it, with your initial commit (without the modifications for Lineage itself) I should be able to at least compile a recovery image but I got an error regarding a missing dtb.img file in the "out" directory.
Something seems to be missing because, my dtb file is in the "device" directory and not being transfered into "out" during building.
I'm not sure that is because I have got a different naming scheme (renamig it didn't help) or I did something wrong with the extraction.
---------- Post added at 07:30 ---------- Previous post was at 07:14 ----------
Another question I have:
Are the vbmeta-files you used to flash the recovery the ones from the original firmeware zip from unihertz or did you get them from the lineage built?
And reguarding the rather smallish system partition:
I have an idea to bypass that by using the SPFlash Tool from Mediatek. As far as I understand the settings in the scatter-file this tool does a repartitioning of the internal storage. So we only need to "decrease" the userdata, "move" some partitions inbetween and "increase" the system. Only problem is, I couldn't find a partition designated as "system" in the scatter-file, only one big "super" and a "vbmeta-system" (which for my understaning is for verified boot) partition.
What do you think?
a-dead-trousers said:
I'm already on to that.
But I seem to have trouble extracting the prebuilt kernel. None of the tools I found gave me the exact files you have got (dtb.img, dtbo.img, Image.gz). What did you use?
The best I could get were "dtb", "kernel" and "dtborecovery" (without extensions) which roughly had the same size as yours.
Also, as far as I understand it, with your initial commit (without the modifications for Lineage itself) I should be able to at least compile a recovery image but I got an error regarding a missing dtb.img file in the "out" directory.
Something seems to be missing because, my dtb file is in the "device" directory and not being transfered into "out" during building.
I'm not sure that is because I have got a different naming scheme (renamig it didn't help) or I did something wrong with the extraction.
---------- Post added at 07:30 ---------- Previous post was at 07:14 ----------
Another question I have:
Are the vbmeta-files you used to flash the recovery the ones from the original firmeware zip from unihertz or did you get them from the lineage built?
And reguarding the rather smallish system partition:
I have an idea to bypass that by using the SPFlash Tool from Mediatek. As far as I understand the settings in the scatter-file this tool does a repartitioning of the internal storage. So we only need to "decrease" the userdata, "move" some partitions inbetween and "increase" the system. Only problem is, I couldn't find a partition designated as "system" in the scatter-file, only one big "super" and a "vbmeta-system" (which for my understaning is for verified boot) partition.
What do you think?
Click to expand...
Click to collapse
> None of the tools I found gave me the exact files you have got (dtb.img, dtbo.img, Image.gz). What did you use?
There is a tool called `unpack_bootimg` in the Android source code. Just run `make unpack_bootimg` in the root directory of the Android source tree and you will get one in the output directory. (btw I have renamed those extracted files so the names won't exactly match, but you need this tool to extract the correct images. All other tools won't work properly).
> my dtb file is in the "device" directory and not being transfered into "out" during building.
Because most tools other than `unpack_bootimg` extracts dtb incorrectly.
> Are the vbmeta-files you used to flash the recovery the ones from the original firmeware zip from unihertz or did you get them from the lineage built?
Those don't matter. Either will work as long as you flash it with the correct parameters as given in my post.
> And reguarding the rather smallish system partition
No don't do that. Android 10 does not use a separate system partition anymore, instead both system, vendor and product are sub-partitions in a huge super partition. When flashing a new ROM, the partitions are automatically resized to match the new image exactly, instead of leaving free space unused like before Android 10. That's why I need to reserve space in BoardConfig.mk for gapps to be installed correctly.
Still not able to build.
PeterCxy said:
There is a tool called `unpack_bootimg` in the Android source code. Just run `make unpack_bootimg` in the root directory of the Android source tree and you will get one in the output directory. (btw I have renamed those extracted files so the names won't exactly match, but you need this tool to extract the correct images. All other tools won't work properly).
Click to expand...
Click to collapse
I'm still getting an error:
Code:
FAILED: ninja: 'out/target/product/Atom_XL/dtb.img', needed by 'out/target/product/Atom_XL/boot.img', missing and no known rule to make it
Comparing your BoardConfig.mk with mine shows a slight difference in the offset and size values which could be associated with the different kernels of the phones.
But using "unpack_bootimg" I didn't get a value for "BOARD_KERNEL_OFFSET" like you have it in your config. Could this be the problem?
Your BoardConfig.mk
My BoardConfig.mk
Do you see anything else out of the ordinary?
(Because I'm doing everything what you did step-by-step the links point to the best matching commits)
Despite not being able to compile right now I tried to press on with integrating your changes in the hopes that it will be fixed somehow later on
So I'm currently stuck on this commit of yours:
Atom_L: import overlay from official vendor
Where did you get the "config.xml" and "power_profile.xml" from? The best thing I could find was a "power_profile.xml" inside "/vendor/overlay/FrameworkResOverlay/FrameworkResOverlay.apk" which seems to be a "compiled" version of the aforementioned xml-file.
a-dead-trousers said:
I'm still getting an error:
Code:
FAILED: ninja: 'out/target/product/Atom_XL/dtb.img', needed by 'out/target/product/Atom_XL/boot.img', missing and no known rule to make it
Comparing your BoardConfig.mk with mine shows a slight difference in the offset and size values which could be associated with the different kernels of the phones.
But using "unpack_bootimg" I didn't get a value for "BOARD_KERNEL_OFFSET" like you have it in your config. Could this be the problem?
Your BoardConfig.mk
My BoardConfig.mk
Do you see anything else out of the ordinary?
(Because I'm doing everything what you did step-by-step the links point to the best matching commits)
Despite not being able to compile right now I tried to press on with integrating your changes in the hopes that it will be fixed somehow later on
So I'm currently stuck on this commit of yours:
Atom_L: import overlay from official vendor
Where did you get the "config.xml" and "power_profile.xml" from? The best thing I could find was a "power_profile.xml" inside "/vendor/overlay/FrameworkResOverlay/FrameworkResOverlay.apk" which seems to be a "compiled" version of the aforementioned xml-file.
Click to expand...
Click to collapse
> Comparing your BoardConfig.mk with mine shows a slight difference in the offset and size values which could be associated with the different kernels of the phones.
TARGET_KERNEL_OFFSET should normally always be 0x00008000. Also, your other offset values seem to be wrong too -- those values from `unpack_bootimg` cannot be filled in directly to BoardConfig.mk. Instead, you need to subtract BOARD_KERNEL_BASE from them (e.g. BOARD_RAMDISK_OFFSET should be 0x55000000 - 0x40078000, which is 0x14f88000, the same as mine). In fact, I think those parameters should be exactly the same for XL and L. Other than that, I don't think I can see much of a problem about your makefiles.
However, note that not all of my historical commits represent a compilable state of the device tree. I'd suggest you start directly from the latest state and just replace whatever is relevant instead of starting over. And there should not be much that needs changing at all except device names, fingerprints and the proprietary vendor files.
> Where did you get the "config.xml" and "power_profile.xml" from
Exactly from those apks. Just decompile them using apktool.
PeterCxy said:
TARGET_KERNEL_OFFSET should normally always be 0x00008000. Also, your other offset values seem to be wrong too -- those values from `unpack_bootimg` cannot be filled in directly to BoardConfig.mk. Instead, you need to subtract BOARD_KERNEL_BASE from them (e.g. BOARD_RAMDISK_OFFSET should be 0x55000000 - 0x40078000, which is 0x14f88000, the same as mine). In fact, I think those parameters should be exactly the same for XL and L. Other than that, I don't think I can see much of a problem about your makefiles.
Click to expand...
Click to collapse
Still giving me errors.
So I tried a very unconventional approach: I just copied the file myself into the mentioned "out/target/product/Atom_XL" folder.
For now it's still compiling. Fingers crossed.
PeterCxy said:
However, note that not all of my historical commits represent a compilable state of the device tree. I'd suggest you start directly from the latest state and just replace whatever is relevant instead of starting over. And there should not be much that needs changing at all except device names, fingerprints and the proprietary vendor files.
Click to expand...
Click to collapse
I just reached your biggest commit yet.
Can you tell me how you got the list of needed files? I hope it's not through trial-and-error.
Except for the values in "setup-makefiles.sh" only the "proprietary-files.txt" seems to be device specific. Is there anything else I need to be aware of in this commit?
P.S.: I know it is tedious to go through your commits one by one but I want to learn something of it not just simply copying what you did. To get a feeling where the biggest pitfalls are and what you did to circumvent them.
a-dead-trousers said:
Still giving me errors.
So I tried a very unconventional approach: I just copied the file myself into the mentioned "out/target/product/Atom_XL" folder.
For now it's still compiling. Fingers crossed.
I just reached your biggest commit yet.
Can you tell me how you got the list of needed files? I hope it's not through trial-and-error.
Except for the values in "setup-makefiles.sh" only the "proprietary-files.txt" seems to be device specific. Is there anything else I need to be aware of in this commit?
P.S.: I know it is tedious to go through your commits one by one but I want to learn something of it not just simply copying what you did. To get a feeling where the biggest pitfalls are and what you did to circumvent them.
Click to expand...
Click to collapse
> Still giving me errors.
Looks like that dtb.img error was totally my fault -- it was due to my jerry-rigged solution of using prebuilt dtb image that conflicted with one of Lineage's update in August and I haven't built the ROM for a month. Now I have fixed it in the latest commit.
> Can you tell me how you got the list of needed files?
All of those files are for VoLTE support and I started with the list from a commit in Redmi Note 7 Pro's device tree that imported those VoLTE blobs, and then added what was missing one by one (when something is missing the Phone process will crash and you can see what got missing in the logs). I don't think the list will be any different on Atom XL so you can just use the one in my device tree.
Hi.
Thanks to you everything is running smoothly here. But what bugs me is that TWRP is not working on our devices.
Although for the Atom there is a possibility: https://forum.xda-developers.com/android/development/twrp-modded-to-unihertz-atom-t3885793
Before I want to go public with my build I wanted to solve this last "mystery".
So I tried to include it in my current source tree according to the (official?) guide but some errors prevented me from a successful build.
Naturally I asked for some guidance at the most reasonable places I know of but got nothing so far:
https://forum.xda-developers.com/showpost.php?p=83443611&postcount=4622
https://forum.xda-developers.com/showpost.php?p=83455271&postcount=4623
https://github.com/TeamWin/android_bootable_recovery/issues/70
I even tried different repositories (omnirom/android_bootable_recovery) and revisions (android-9.0) but these resulted in missing library "type" (static vs. shared) errors so I assume these are too old for LineageOS 17.1
What I want to know is how you managed to get TWRP to built for your device even though the touchscreen wasn't working?
Did you use your LineageOS source tree or one of the many "minimal" manifests? If so, which one would be the "best" to use?
wkr ADT
@PeterCxy and @a-dead-trousers
Thanks for all the work on this so far. I've got an Atom L and have gotten the ROM's PeterCxy posted running on them as in the OP. Do either of you have a quick step-by-step workflow of how you got all the Lineage sources set up and built into the various ROMs? I'd like to be able to build the ROMs from scratch and understand the process.
If I can get caught up to where you two are at with the builds, I can help debug, test and work through issues.
dirtylimerick said:
[MENTION=5351691] Do either of you have a quick step-by-step workflow of how you got all the Lineage sources set up and built into the various ROMs? I'd like to be able to build the ROMs from scratch and understand the process.
If I can get caught up to where you two are at with the builds, I can help debug, test and work through issues.
Click to expand...
Click to collapse
I documented my steps to setup up the build environment in the readme of my repo:
https://github.com/ADeadTrousers/android_device_Unihertz_Atom_XL
But leave out the TWRP part. It isn't working yet mostly because TeamWin/android_bootable_recovery and LineageOS/android_bootable_recovery are too similar.
To figure out all the bits and pieces needed for the device I followed the commit log of @PeterCxy build.
Hi, @PeterCxy.
Finally I was able to build a TWRP recovery and surprise, surprise the touchscreen isn't working.
But during my attempts to get a working TWRP build I came acros a guide that explains how to patch the kernel to get the touchscreen to work.
https://forum.hovatek.com/thread-27132.html
So I tried to follow it but failed to identify the "end" of the zipped Image-file (step 18) to remove the payload from the gz-file. Regardless of which of the null-bytes I use for cutting I always get a warning from 7-zip that there is still data at the end.
Do you know a better approach to achieve this whole patching? Maybe even come up with a scripting solution to easily apply this patch in later builds?
wkr ADT
a-dead-trousers said:
Hi, @PeterCxy.
Finally I was able to build a TWRP recovery and surprise, surprise the touchscreen isn't working.
But during my attempts to get a working TWRP build I came acros a guide that explains how to patch the kernel to get the touchscreen to work.
https://forum.hovatek.com/thread-27132.html
So I tried to follow it but failed to identify the "end" of the zipped Image-file (step 18) to remove the payload from the gz-file. Regardless of which of the null-bytes I use for cutting I always get a warning from 7-zip that there is still data at the end.
Do you know a better approach to achieve this whole patching? Maybe even come up with a scripting solution to easily apply this patch in later builds?
wkr ADT
Click to expand...
Click to collapse
There is no sane way to solve the problem without kernel source code. Basically the stock kernel just does not load the touch screen driver in recovery mode. That patching guide is pretty out of date and I imagine it won't work on most recent kernels. The only proper way is to pressure Unihertz to actually obey GPLv2 and release their kernel source code. Or maybe someone can try reverse-engineering the kernel, but at least I won't do it because it'll just be too much of a hassle.
PeterCxy said:
There is no sane way to solve the problem without kernel source code. Basically the stock kernel just does not load the touch screen driver in recovery mode. The only proper way is to pressure Unihertz to actually obey GPLv2 and release their kernel source code.
Click to expand...
Click to collapse
I'm with you on this one, but as long as we don't have the source code we need to resort to other means to achieve our goals.
PeterCxy said:
That patching guide is pretty out of date and I imagine it won't work on most recent kernels.
Click to expand...
Click to collapse
Yeah it's from way back in 2019
Anyway, with a little bit of tinkering I was able to modify my kernel to load the touchscreen driver in recovery mode.
Here is the device tree and the manifest i used.
I wouldn't recommend to use it in it's current state at all though because the fstab needs a little bit of tinkering. Everything seems to be either unordered or not mounted properly and I fear anything you do in there now will mess up the whole device. BUT I got the touchscreen goin for me which is nice.
PeterCxy said:
Or maybe someone can try reverse-engineering the kernel, but at least I won't do it because it'll just be too much of a hassle.
Click to expand...
Click to collapse
As soon as I have everything sorted out that needs to be fixed on my build (e.g. signing, radio, included gapps working properly, TWRP) I want to dig deeper into the kernel.
There are some devices with Helios P60 out there from other vendors which offer kernel sources.
P.S.: I also uploaded a HOW-TO in my device tree.
If you or someone else wants to try it. Also if you want to you can send me a "symbl.txt" (see to the HOW-TO) extracted from your device then I can do the patching for the Atom_L too.
a-dead-trousers said:
I'm with you on this one, but as long as we don't have the source code we need to resort to other means to achieve our goals.
Yeah it's from way back in 2019
Anyway, with a little bit of tinkering I was able to modify my kernel to load the touchscreen driver in recovery mode.
Here is the device tree and the manifest i used.
I wouldn't recommend to use it in it's current state at all though because the fstab needs a little bit of tinkering. Everything seems to be either unordered or not mounted properly and I fear anything you do in there now will mess up the whole device. BUT I got the touchscreen goin for me which is nice.
As soon as I have everything sorted out that needs to be fixed on my build (e.g. signing, radio, included gapps working properly, TWRP) I want to dig deeper into the kernel.
There are some devices with Helios P60 out there from other vendors which offer kernel sources.
P.S.: I also uploaded a HOW-TO in my device tree.
If you or someone else wants to try it. Also if you want to you can send me a "symbl.txt" (see to the HOW-TO) extracted from your device then I can do the patching for the Atom_L too.
Click to expand...
Click to collapse
Happy to hear that you were able to figure the touchscreen out. I tried to port TWRP at the very beginning when I started tinkering with the device but quickly grew frustrated and just ported Lineage Recovery instead. I guess I might try patching the kernel image too at some point later.
BTW, for TWRP to work with devices released after Android 10, I'm pretty sure you need an extra set of patches that are not yet fully merged to the main TWRP repository. I remember there's some guy providing another manifest with all the patches applied but I couldn't remember the name.
Hi.
I just officially announced my build for the Atom XL:
https://forum.xda-developers.com/android/development/rom-lineageos-17-1-unihertz-atom-xl-t4171407
Could you please put a link in your first post for those in search of the Atom XL and found your thread instead. Thanks.
wkr ADT
hi @PeterCxy.
During my daily usage of the phone I encountered a strage problem:
The audio jack isn't working. Plugging in some headphones I get this slight click in the earpieces when the circuits connect but nothing else happens. Neither a "headphone" icon in the status bar nor hearing anything coming from the headphones itself. The main speaker of the phone keeps playing the music. Using bluetooth everything is working as expected though. So I used logcat to see if something is coming up during plugging in but nothing "catchy" shows up in the logs. My guess is that some (vendor?) service is missing or not started during booting. Next I checked If something shows up on logcat during boot but I'm not sure for what to look exactly. There are quite a few errors and warnings though. In my despair I started to "fix" the "avc: denied" (SEPolicy) entries. Thats when I found a specific error reguarding VoLTE. Maybe this would fix the problems you had with VoLTE in enforcing mode:
https://github.com/ADeadTrousers/an..._Atom_XL/blob/master/sepolicy/private/init.te
(The line with "socket_device:sock_file")
My provider doesn't support VoLTE so I'm not sure if this helps or not. Maybe you could check it.
Anyway can you please tell me if your device's audio jack is working or not?
If you're (by some mysterious coincidence) not affected by this, can you at least give me some pointers for what to look for to get this fixed on my side.
The Internet Is not very helpful when searching for "android audio jack" or something similiar.
Thanks in advance.
wkr ADT

Development boot.img for SM-A127F and SM-A125F with the touch and MTP fixed

Here is a few boot.img files (tarred for Odin and zipped) intended to be used together with GSI systems (e.g. LineageOS) which suffer from the non-functional touchscreen after the wake-up and the non-functional MTP (USB file transfer). The boot.img files contain the recompiled stock kernel taken from Samsung Open Source with only a couple of the most necessary fixes. 99.9% unaltered, 100% open-source
All credits for the touchscreen fix go to manteiga25, he's done an amazing job on figuring this all out, still from his solution which includes additional performance tweaks I've taken the absolute bare minimum so that the problem is no longer present. Also huge thanks to Osvaldo Costa for the wonderful bootimgtool.
NOTE: If you did not yet flash any non-stock boot.img or recovery.img you may get the bootloop after flashing of any of these files (except for the orig's). That bootloop is caused by bootloader refusing to boot the VB-unsigned kernel together with the rest of the VB-signed components. The only solution (unfortunately) is the full factory reset, so you'll have to lose your user data; everything else, including the GSI will remain intact, but you'll have to set it up from scratch.
UPDATE 01/09/23: added the version based on A127FXXU7CVL2 (Android 13) version of the kernel.
UPDATE 01/11/23: added the fixed kernels for SM-A125F.
UPDATE 03/16/23: added the version based on A127FXXU5BVF3 (Android 12) version of the kernel.
Files for SM-A127F:
boot_sm-a127f-u4_fixed.zip: A127FXXU4AUK1-based kernel, Ilitek ili9881x fix, MTP fix
boot_sm-a127f-u5_fixed.zip: A127FXXU5BVF3-based (Android 12) kernel, Ilitek ili9881x fix, MTP fix
boot_sm-a127f-u7_fixed.zip: A127FXXU7CVL2-based (Android 13) kernel, Ilitek ili9881x fix, MTP fix
orig_boot_sm-a127-u4.zip: the original unaltered A127FXXU4AUK1 boot.img for undo
orig_boot_sm-a127-u5.zip: the original unaltered A127FXXU5BVF3 boot.img for undo
orig_boot_sm-a127-u7.zip: the original unaltered A127FXXU7CVL2 boot.img for undo
src_sm-a127f_fix.zip: all the altered source files
Files for SM-A125F:
boot_sm-a125f-u2_fixed_v1.zip: A125FXXU2BVB4-based kernel, Ilitek ili9881x fix, MTP fix
boot_sm-a125f-u2_fixed_v2.zip: A125FXXU2BVB4-based kernel, Ilitek ili9881x fix, Novatek nt36525 fix, MTP fix
orig_boot_sm-a125-u2.zip: the original unaltered A125FXXU2BVB3 boot.img for undo
src_sm-a127f-fix_v2.zip: all the altered source files
v1 should be easy on battery, but v2 will probably eat more because it basically disables the power saving features of the touchscreen chip (unfortunately that's the only solution at the kernel side).
If you don't trust me or if you're in desperate need of a more recent kernel, here are the steps how to rebuild it all yourself (for SM-A127F on Debian 11):
Download the kernel source from Samsung Open Source (A127FXXU3AUJ5)
Unpack SM-A127F_RR_Opensource.zip and Kernel.tar.gz inside
Unpack SM-A127F_RR_Opensource_A127FXXU4AUK1.zip into the same dir (overwriting the files)
Unpack the attached source.tar.gz, it contains only the changed files and build.sh facilitating compilation
From root: apt install clang-9 gcc-9-aarch64-linux-gnu
Remove any other versions of clang. Then cd /usr/bin; ln -s clang clang-9; ln -s clang++ clang++-9; ln -s clang-cpp clang-cpp-9
Back in the Kernel dir, run build.sh and wait for the kernel to compile
Download bootimgtool and compile it (just "make")
Download the stock firmware
Extract boot.img from AP_A127FXX[...].tar.md5 (unpack using tar, ignore the .md5) to the root dir of your Kernel
bootimgtool disassemble boot.img
cp Kernel/arch/arm64/boot/Image kernel
bootimgtool create -o boot.img
Flash boot.img as is using Heimdall or pack into .tar and flash using Odin
For SM-A125F you'll need to use the Google's patched Clang and GCC instead, and there is no way around that except for lots and lots of additional include paths for the Mediatek drivers (and even that does not guarentee that it will be compiled successfully).
uluruman said:
Here is the boot.img (tarred for Odin) intended to be used together with GSI systems (e.g. LineageOS). It contains the recompiled stock U4 kernel taken from Samsung Open Source with only a couple of the most necessary fixes, namely the freezing touchscreen and the non-functional MTP. 99.9% unaltered, 100% open-source.
All credits for the touchscreen fix go to manteiga25, he's done an amazing job on figuring this all out, still from his solution which includes additional performance tweaks I've taken the absolute bare minimum so that the problem is no longer present. Also huge thanks to Osvaldo Costa for the wonderful bootimgtool.
If you don't trust me here are the steps how to rebuild it all yourself (on Debian 11):
Download the kernel source from Samsung Open Source (A127FXXU3AUJ5)
Unpack SM-A127F_RR_Opensource.zip and Kernel.tar.gz inside
Unpack SM-A127F_RR_Opensource_A127FXXU4AUK1.zip into the same dir (overwriting the files)
Unpack the attached source.tar.gz, it contains only the changed files and build.sh facilitating compilation
From root: apt install clang-9 gcc-9-aarch64-linux-gnu
Remove any other versions of clang. Then cd /usr/bin; ln -s clang clang-9; ln -s clang++ clang++-9; ln -s clang-cpp clang-cpp-9
Back in the Kernel dir, run build.sh and wait for the kernel to compile
Download bootimgtool and compile it (just "make")
Download the stock firmware
Extract boot.img from AP_A127FXX[...].tar.md5 (unpack using tar, ignore the .md5) to the root dir of your Kernel
bootimgtool disassemble boot.img
cp Kernel/arch/arm64/boot/Image kernel
bootimgtool create -o boot.img
Flash boot.img as is using Heimdall or pack into .tar and flash using Odin
Click to expand...
Click to collapse
Amazing work. Love to see developers still working on this device. Does it work with SM-A125F?
Allehandro said:
Amazing work. Love to see developers still working on this device. Does it work with SM-A125F?
Click to expand...
Click to collapse
You can try, it may work, but most likely will bootloop. SM-A125F is based on a Mediatek SoC, SM-A127F is based on Exynos, which has a different kernel config.
uluruman said:
You can try, it may work, but most likely will bootloop. SM-A125F is based on a Mediatek SoC, SM-A127F is based on Exynos, which has a different kernel config.
Click to expand...
Click to collapse
I don't want to risk it as it is my main device and don't want to have to restore the device later on. Thanks though.
I've finally managed to compile the SM-A125F kernel (A125FXXU2BVB4 - SM-A125F_EUR_RR): somehow it turned out to be MUCH harder than that for SM-A127F, as nearly everything there is designed for only one specific toolchain, plus the non-Samsung s_mtp driver did not compile, so I had to take it from A127F's source. Anyway, I've ported the same fixes and here is the experimental boot.img. As I don't have SM-A125F I cannot test it, so I need someone to test it. Also attached is the original U2 boot.img: in case it does not work you just flash the original.
Amazing bro! Mad respect!!!!
I will soon put this baby to the test and see what's made of!!!
I can flash this using ODIN (PDA) directly over the current LOS GSI right?
Also, do you plan to include this kernel in your gsi building script so that the boot img of the gsi will be this one?
One other issue that I seemed to also have in my phone was the proximity sensor was not working e.g. when I was in call the screen would remain on....
axy_david said:
Amazing bro! Mad respect!!!!
I will soon put this baby to the test and see what's made of!!!
I can flash this using ODIN (PDA) directly over the current LOS GSI right?
Also, do you plan to include this kernel in your gsi building script so that the boot img of the gsi will be this one?
One other issue that I seemed to also have in my phone was the proximity sensor was not working e.g. when I was in call the screen would remain on....
Click to expand...
Click to collapse
Yes, flash using Odin. GSI should not be affected in any way. If anything does wrong I've also attached the original A127FXXU4AUK1 boot.img, so that you could revert the changes.
Currently I'm struggling to make the same fixed boot.img for my second phone, which is SM-A325F, and I cannot: even if I just unpack and repack back the same boot.img using any tool, including the Google's official mkbootimg, it causes the bootloop. So all of this is currently experimental.
uluruman said:
Currently I'm struggling to make the same fixed boot.img for my second phone, which is SM-A325F, and I cannot: even if I just unpack and repack back the same boot.img using any tool, including the Google's official mkbootimg, it causes the bootloop. So all of this is currently experimental.
Click to expand...
Click to collapse
This issue is sorted out: one cannot flash a custom boot.img over the signed stock one and don't do the full factory reset afterwards. Only after the factory reset the system boots with the unsigned boot partition. Interestingly enough, Download allows flashing such an image without any warnings (in contrast to flashing up_param.bin) but the system just refuses to boot.
uluruman said:
This issue is sorted out: one cannot flash a custom boot.img over the signed stock one and don't do the full factory reset afterwards. Only after the factory reset the system boots with the unsigned boot partition. Interestingly enough, Download allows flashing such an image without any warnings (in contrast to flashing up_param.bin) but the system just refuses to boot.
Click to expand...
Click to collapse
is it possible to fix the proximity sensor?
axy_david said:
is it possible to fix the proximity sensor?
Click to expand...
Click to collapse
There is no physical proximity sensor in this phone, but with the latest firmware you can normally use the Phone app. Now it normally reacts on touching the top part of the screen with your ear and blanks the screen. The screen does not blank on approaching the screen but only on touching it.
uluruman said:
Here is the boot.img (tarred for Odin) intended to be used together with GSI systems (e.g. LineageOS). It contains the recompiled stock U4 kernel taken from Samsung Open Source with only a couple of the most necessary fixes, namely the freezing touchscreen and the non-functional MTP. 99.9% unaltered, 100% open-source.
If the fixed boot.img does not work for you for some reason, I've also attached the original U4 boot (taken from the SM-A127F_NPB_A127FXXU4AUK1 firmware) so you could revert the changes.
All credits for the touchscreen fix go to manteiga25, he's done an amazing job on figuring this all out, still from his solution which includes additional performance tweaks I've taken the absolute bare minimum so that the problem is no longer present. Also huge thanks to Osvaldo Costa for the wonderful bootimgtool.
If you don't trust me or if you're in desperate need of a more recent kernel, here are the steps how to rebuild it all yourself (on Debian 11):
Download the kernel source from Samsung Open Source (A127FXXU3AUJ5)
Unpack SM-A127F_RR_Opensource.zip and Kernel.tar.gz inside
Unpack SM-A127F_RR_Opensource_A127FXXU4AUK1.zip into the same dir (overwriting the files)
Unpack the attached source.tar.gz, it contains only the changed files and build.sh facilitating compilation
From root: apt install clang-9 gcc-9-aarch64-linux-gnu
Remove any other versions of clang. Then cd /usr/bin; ln -s clang clang-9; ln -s clang++ clang++-9; ln -s clang-cpp clang-cpp-9
Back in the Kernel dir, run build.sh and wait for the kernel to compile
Download bootimgtool and compile it (just "make")
Download the stock firmware
Extract boot.img from AP_A127FXX[...].tar.md5 (unpack using tar, ignore the .md5) to the root dir of your Kernel
bootimgtool disassemble boot.img
cp Kernel/arch/arm64/boot/Image kernel
bootimgtool create -o boot.img
Flash boot.img as is using Heimdall or pack into .tar and flash using Odin
P.S.: the U5 kernel sources are suspicously segregated between RR (rest of the world), EUR, CIS and CIS-SER (Russia). It's quite interesting what are the differences?
Click to expand...
Click to collapse
Can you make one for A127F/DSN U7? (I don't have linux)
just tested on my phone latest U7 or s7???? nevertheless it bootloops
axy_david said:
just tested on my phone latest U7 or s7???? nevertheless it bootloops
Click to expand...
Click to collapse
it only works for u4 currently.
TheWorldYT said:
Can you make one for A127F/DSN U7? (I don't have linux)
Click to expand...
Click to collapse
I will, hold on.
just tested on my phone latest U7 or s7???? nevertheless it bootloops
TheWorldYT said:
it only works for u4 currently.
Click to expand...
Click to collapse
damn, and I can't downgrade, im using A127FXXS7BVK1 the latest update for europe really
axy_david said:
just tested on my phone latest U7 or s7???? nevertheless it bootloops
damn, and I can't downgrade, im using A127FXXS7BVK1
Click to expand...
Click to collapse
same thing.
also:
uluruman said:
I will, hold on.
Click to expand...
Click to collapse
axy_david said:
just tested on my phone latest U7 or s7???? nevertheless it bootloops
damn, and I can't downgrade, im using A127FXXS7BVK1 the latest update for europe really
Click to expand...
Click to collapse
uluruman said he will create one.
axy_david said:
just tested on my phone latest U7 or s7???? nevertheless it bootloops
damn, and I can't downgrade, im using A127FXXS7BVK1 the latest update for europe really
Click to expand...
Click to collapse
Done! ) See the update in the first post.
I've used the A127FXXU7CVL2 version source but it should work anyway because it's also U7-based (anyway there is no alternative - Samsung provides only that U7-based kernel). The only thing that theoretically can be needed is the factory reset: at least with my SM-A325F that was the case of the weird boot loop - the Verified Boot protection being voided (the warranty void bit being set) caused the bootloader to refuse loading the kernel.
uluruman said:
Done! ) See the update in the first post.
I've used the A127FXXU7CVL2 version source but it should work anyway because it's also U7-based (anyway there is no alternative - Samsung provides only that U7-based kernel). The only thing that theoretically can be needed is the factory reset: at least with my SM-A325F that was the case of the weird boot loop - the Verified Boot protection being voided (the warranty void bit being set) caused the bootloader to refuse loading the kernel.
Click to expand...
Click to collapse
Thank you!
uluruman said:
I've finally managed to compile the SM-A125F kernel (A125FXXU2BVB4 - SM-A125F_EUR_RR): somehow it turned out to be MUCH harder than that for SM-A127F, as nearly everything there is designed for only one specific toolchain, plus the non-Samsung s_mtp driver did not compile, so I had to take it from A127F's source. Anyway, I've ported the same fixes and here is the experimental boot.img. As I don't have SM-A125F I cannot test it, so I need someone to test it. Also attached is the original U2 boot.img: in case it does not work you just flash the original.
Click to expand...
Click to collapse
Can u make flashable zip for fix touch and mtp for a125f cause i think it dndt work after flashing only boot.img in twrp,still i found out that the baseband version is still bv5 instead of bv4 i hope you fix that bro because i want to install gsi
uluruman said:
Here is the boot.img (tarred for Odin) intended to be used together with GSI systems (e.g. LineageOS). It contains the recompiled stock U4 kernel taken from Samsung Open Source with only a couple of the most necessary fixes, namely the freezing touchscreen and the non-functional MTP. 99.9% unaltered, 100% open-source.
If the fixed boot.img does not work for you for some reason, I've also attached the original U4 boot (taken from the SM-A127F_NPB_A127FXXU4AUK1 firmware) so you could revert the changes.
All credits for the touchscreen fix go to manteiga25, he's done an amazing job on figuring this all out, still from his solution which includes additional performance tweaks I've taken the absolute bare minimum so that the problem is no longer present. Also huge thanks to Osvaldo Costa for the wonderful bootimgtool.
UPDATE 01/09/23: added the version based on A127FXXU7CVL2 (Android 13) version of the kernel.
If you don't trust me or if you're in desperate need of a more recent kernel, here are the steps how to rebuild it all yourself (on Debian 11):
Download the kernel source from Samsung Open Source (A127FXXU3AUJ5)
Unpack SM-A127F_RR_Opensource.zip and Kernel.tar.gz inside
Unpack SM-A127F_RR_Opensource_A127FXXU4AUK1.zip into the same dir (overwriting the files)
Unpack the attached source.tar.gz, it contains only the changed files and build.sh facilitating compilation
From root: apt install clang-9 gcc-9-aarch64-linux-gnu
Remove any other versions of clang. Then cd /usr/bin; ln -s clang clang-9; ln -s clang++ clang++-9; ln -s clang-cpp clang-cpp-9
Back in the Kernel dir, run build.sh and wait for the kernel to compile
Download bootimgtool and compile it (just "make")
Download the stock firmware
Extract boot.img from AP_A127FXX[...].tar.md5 (unpack using tar, ignore the .md5) to the root dir of your Kernel
bootimgtool disassemble boot.img
cp Kernel/arch/arm64/boot/Image kernel
bootimgtool create -o boot.img
Flash boot.img as is using Heimdall or pack into .tar and flash using Odin
P.S.: the U5 kernel sources are suspicously segregated between RR (rest of the world), EUR, CIS and CIS-SER (Russia). It's quite interesting what are the differences?
Click to expand...
Click to collapse
Please create working flashable zip file for twrp for a125f cause i dont have pc i cant use odin,thank you

Categories

Resources