Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Readers > Amazon Kindle > Kindle Developer's Corner

Notices

Reply
 
Thread Tools Search this Thread
Old 04-11-2024, 09:37 AM   #1
WuYung
Junior Member
WuYung began at the beginning.
 
Posts: 5
Karma: 10
Join Date: Apr 2024
Device: Kindle paperwhite 5
Can I use Waydroid to run Android apps on my Kindle?

Sorry, I don't speak English, so this article was translated using ChatGPT.

I own a Kindle Paperwhite 5, running version 5.16.2.1.1 with 474MB of RAM (as seen on htop). The reason behind this exploration was my desire to use a manga app from Android on my Kindle device.

I'm not very familiar with Linux, but I noticed that many people run Android on Linux using Waydroid, which utilizes Linux containers to minimize performance loss. So, I decided to give it a try. First, I used alpine_kindle to run lxc-checkconfig and obtained results similar to the following (this result was captured when I wrote this post; it seems slightly different from my initial run, possibly due to my mistake or misremembering).
Code:
LXC version 6.0.0

--- Namespaces ---
Namespaces: required
Utsname namespace: missing
Ipc namespace: required
Pid namespace: required
User namespace: missing
Network namespace: missing
Namespace limits:
  cgroup: 3767
  ipc: 3767
  mnt: 3767
  net: 3767
  pid: 3767
  user: 3767
  uts: 3767

--- Control groups ---
Cgroups: enabled
Cgroup namespace: enabled
Cgroup v1 mount points:
Cgroup v2 mount points:
Cgroup v1 systemd controller: missing
Cgroup v1 freezer controller: missing
Cgroup device: missing
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: missing
Macvlan: missing
Vlan: enabled, not loaded
Bridges: enabled, not loaded
Advanced netfilter: enabled, not loaded
CONFIG_NF_NAT_IPV4: enabled, not loaded
CONFIG_NF_NAT_IPV6: missing
CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_IP6_NF_TARGET_MASQUERADE: missing
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: missing
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
FUSE (for use with lxcfs): enabled, not loaded

--- Checkpoint/Restore ---
checkpoint restore: missing
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: missing
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: missing
CONFIG_NETLINK_DIAG: missing
File capabilities: enabled

Note: Before booting a new kernel, you can check its configuration with:

  CONFIG=/path/to/config /usr/bin/lxc-checkconfig
It seems there's limited explanation online regarding the results of lxc-checkconfig. From the numerous missing results, I inferred that the current Linux kernel might not support LXC. Therefore, I embarked on recompiling the Linux kernel. Following the method 2 outlined in Step by Step instructions for kindle development environment, I compiled using the compiler downloaded from Linaro (gcc4.9.4), and my compilation environment was WSL Ubuntu 22.04 with GCC version 11.4.0.

After comparing the contents of '/proc/config.gz' in the Kindle, I speculated that the kernel configuration file was mt8110-bellatrix_defconfig. So, I used the following commands to install remaining tools, configure, and compile:
Code:
sudo apt update
sudo apt upgrade
sudo apt install gcc
sudo apt install bc
sudo apt install lzop
make ARCH=arm CROSS_COMPILE=~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi- mt8110-bellatrix_defconfig
make ARCH=arm CROSS_COMPILE=~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-
There might encounter the following error:
Code:
/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x10): multiple definition of `yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [scripts/Makefile.host:116: scripts/dtc/dtc] Error 1
only need to delete 'YYLTYPE yylloc;' from line 42 in 'scripts/dtc/dtc-lexer.l' and line 640 in 'scripts/dtc/dtc-lexer.lex.c_shipped'. This error seems to be caused by the GCC version exceeding 9 in the compilation environment. Subsequently, might encounter the following two errors:
Code:
drivers/devfreq/helio-dvfsrc-opp.c:6:26: fatal error: helio-dvfsrc.h: No such file or directory
./drivers/misc/mediatek/hwtcon_v2/hal/hwtcon_pipeline_config.h:4:24: fatal error: hwtcon_def.h: No such file or directory
These two errors can be resolved by adding the following lines respectively to 'drivers/devfreq/Makefile' and 'drivers/misc/mediatek/hwtcon_v2/Makefile':

In 'drivers/devfreq/Makefile':
Code:
ccflags-y += -I$(srctree)/drivers/devfreq/
In 'drivers/misc/mediatek/hwtcon_v2/Makefile':
Code:
ccflags-y += -I$(srctree)/drivers/misc/mediatek/hwtcon_v2
However, since I'm not familiar with Linux Kernel compilation and MediaTek device compilation, I'm unsure if this method is correct. After applying these changes, should have successfully compiled. My Linux directory structure is as follows:
Code:
.config
.missing-syscalls.d
.tmp_versions
.version
.vmlinux.cmd
Android.mk
COPYING
CREDITS
CleanSpec.mk
Documentation
Kbuild
Kconfig
MAINTAINERS
Makefile
Module.symvers
README
REPORTING-BUGS
System.map
arch
block
build.config.goldfish.arm
build.config.goldfish.arm64
build.config.goldfish.mips
build.config.goldfish.
build.config.goldfish.x86
build.config.goldfish.
certs
crypto
drivers
firmware
fs
include
init
ipc
kenv.mk
kernel
lib
linux-4.9.tar.gz
mm
modules.builtin
modules.order
net
samples
scripts
security
singletask.lock
sound
tools
usr
virt
vmlinux
vmlinux.o
I came across some articles mentioning the need for a uImage file, so I tried executing 'make ARCH=arm CROSS_COMPILE=~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi- uImage', but encountered additional errors:
Code:
drivers/misc/mediatek/pmic/fiti/Makefile:1: harry build hwtcon
  Kernel: arch/arm/boot/Image is ready
  Kernel: arch/arm/boot/zImage is ready
multiple (or no) load addresses:
This is incompatible with uImages
Specify LOADADDR on the commandline to build an uImage
make[1]: *** [arch/arm/boot/Makefile:92: arch/arm/boot/uImage] Error 1
make: *** [arch/arm/Makefile:342: uImage] Error 2
Because I'm unsure about the value of LOADADDR, and I'm hesitant to flash the new kernel onto my Kindle, fearing it might become bricked, I've halted my kernel compilation process for now.

While researching, I discovered another method called kexec that allows executing a new kernel. However, upon checking the /proc/config.gz file in my Kindle, I found that the Kindle's kernel didn't have this feature enabled. So, I referred to the article Kernel development / no kexec syscall and attempted to use kexec-module. However, I faced compilation errors and encountered many unknown symbols during insmod. Thus, I made numerous modifications based on kexec-mod and anbox-modules.

First, I adjusted the Makefile to:
Code:
KDIR ?= /lib/modules/`uname -r`/build
ARCH ?= arm
PWD := $(shell pwd)

default: orig
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD)

orig:
	mkdir $@
	ln -s $(KDIR)/arch/$(ARCH)/kernel/relocate_kernel.S
	cp $(KDIR)/arch/$(ARCH)/kernel/machine_kexec.c $@/
	cp $(KDIR)/kernel/kexec.c $@/
	cp $(KDIR)/kernel/kexec_core.c $@/
	cp $(KDIR)/kernel/kexec_internal.h $@/

clean:
	rm -f -r *.o *.ko .*cmd .tmp* core *.i
Kbuild altered to:
Code:
obj-m := kexec-mod.o
kexec-mod-y := kexec-drv.o deps.o kexec.o
kexec-mod-y += machine_kexec.o relocate_kernel.o
ccflags-y := -include $(PWD)/kexec-mod.h
add 'deps.c' file:
Code:
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/kallsyms.h>

static void (*set_kernel_text_rw_ptr)(void) = NULL;
static int (*platform_can_secondary_boot_ptr)(void) = NULL;
static void (*migrate_to_reboot_cpu_ptr)(void) = NULL;
static int (*platform_can_cpu_hotplug_ptr)(void) = NULL;
static void (*printk_nmi_flush_on_panic_ptr)(void) = NULL;

void set_kernel_text_rw(void){
	if (!set_kernel_text_rw_ptr)
		set_kernel_text_rw_ptr = (void (*)(void))kallsyms_lookup_name("set_kernel_text_rw");	
	return set_kernel_text_rw_ptr();
}

int platform_can_secondary_boot(void){
	if (!platform_can_secondary_boot_ptr)
		platform_can_secondary_boot_ptr = (int (*)(void))kallsyms_lookup_name("platform_can_secondary_boot");	
	return platform_can_secondary_boot_ptr();
}
void migrate_to_reboot_cpu(void){
	if(!migrate_to_reboot_cpu_ptr)
		migrate_to_reboot_cpu_ptr = (void (*)(void))kallsyms_lookup_name("migrate_to_reboot_cpu");
	return migrate_to_reboot_cpu_ptr();
}
int platform_can_cpu_hotplug(void){
	if(!platform_can_cpu_hotplug_ptr)
		platform_can_cpu_hotplug_ptr = (int (*)(void))kallsyms_lookup_name("platform_can_cpu_hotplug");
	return platform_can_cpu_hotplug_ptr();
}
void printk_nmi_flush_on_panic(void){
	if(!printk_nmi_flush_on_panic_ptr)
		printk_nmi_flush_on_panic_ptr = (void (*)(void))kallsyms_lookup_name("printk_nmi_flush_on_panic");
	return printk_nmi_flush_on_panic_ptr();
}
During the first 'make' operation, may encounter numerous 'WARNING: "xxx" [xxx.ko] undefined!' messages.
Code:
make KDIR=~/kindle/gplrelease/linux-4.9 ARCH=arm CROSS_COMPILE=~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-
...
WARNING: "arch_phys_to_idmap_offset" [/xxx/kexec-module/kernel/kexec-mod.ko] undefined!
WARNING: "crash_kexec_post_notifiers" [/xxx/kexec-module/kernel/kexec-mod.ko] undefined!
WARNING: "panic_cpu" [/xxx/kexec-module/kernel/kexec-mod.ko] undefined!
...
Modify line 87 of the 'orig/kexec_core.c' file copied over to the makefile to read: 'if (crash_kexec_post_notifiers)'
Code:
	bool *crash_kexec_post_notifiers_ptr = (bool*)kallsyms_lookup_name("crash_kexec_post_notifiers");
	if (*crash_kexec_post_notifiers_ptr)
And modify the function on line 904 to read: 'void crash_kexec(struct pt_regs *regs)'
Code:
void crash_kexec(struct pt_regs *regs)
{
	int old_cpu, this_cpu;

	/*
	 * Only one CPU is allowed to execute the crash_kexec() code as with
	 * panic().  Otherwise parallel calls of panic() and crash_kexec()
	 * may stop each other.  To exclude them, we use panic_cpu here too.
	 */
	atomic_t *panic_cpu_ptr = (atomic_t*)kallsyms_lookup_name("panic_cpu");
	this_cpu = raw_smp_processor_id();
	old_cpu = atomic_cmpxchg(panic_cpu_ptr, PANIC_CPU_INVALID, this_cpu);
	if (old_cpu == PANIC_CPU_INVALID) {
		/* This is the 1st CPU which comes here, so go ahead. */
		printk_nmi_flush_on_panic();
		__crash_kexec(regs);

		/*
		 * Reset panic_cpu to allow another panic()/crash_kexec()
		 * call.
		 */
		atomic_set(panic_cpu_ptr, PANIC_CPU_INVALID);
	}
}
And add the following to line 67 of 'arch/arm/include/asm/kexec.h' in the Linux source code:
Code:
#define arch_phys_to_idmap_offset (*(long long*)kallsyms_lookup_name("arch_phys_to_idmap_offset"))
And add the following to line 79 of 'arch/arm/include/asm/kexec.h':
Code:
#undef arch_phys_to_idmap_offset
And add the following to line 20 of 'arch/arm/include/asm/memory.h' in the Linux source code:
Code:
#include <linux/kallsyms.h>
And add the following to line 79 of 'arch/arm/include/asm/memory.h':
Code:
#define arch_phys_to_idmap_offset (*(long long*)kallsyms_lookup_name("arch_phys_to_idmap_offset"))
And add the following to line 315 of'arch/arm/include/asm/memory.h':
Code:
#undef arch_phys_to_idmap_offset
At this point, recompiling should no longer show 'WARNING: "xxx" [xxx.ko] undefined!'
Code:
make KDIR=~/kindle/gplrelease/linux-4.9 ARCH=arm CROSS_COMPILE=~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-
However, even after copying it to the Kindle and executing insmod kexec-mod.ko, may still receive
Code:
insmod: error inserting 'kexec-mod.ko': -1 Unknown symbol in module
After searching online for a while, I couldn't find a solution to this issue. Eventually, I realized that 'static int __init kexecmod_init(void)' didn't seem to execute successfully, as it returned '-ENOENT'. This caused the error message during insmod. Later, I discovered that the Kindle's kernel hadn't enabled kallsyms and the alternative solution for accessing non-exported functions, kprobes. At this point, I'm completely stuck. Can anyone help me?

I tried compiling the tools that might be needed afterward, such as kexec-tools, and after using the following command, I was able to compile successfully.
Code:
sudo apt install automake
./bootstrap
export PATH=${PATH}:~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin
LDFLAGS=-static ./configure --host=~/kindle/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi --without-zlib --without-lzma
make
For compiling lxc, first, create a file named 'cross.txt' in the lxc source code directory and fill it with:
Code:
[binaries]
c = 'arm-linux-gnueabi-gcc'
cpp = 'arm-linux-gnueabi-g++'
ar = 'arm-linux-gnueabi-ar'
strip = 'arm-linux-gnueabi-strip'
ld = 'arm-linux-gnueabi-ld'
objcopy = 'arm-linux-gnueabi-objcopy'


[host_machine]
system = 'linux'
cpu_family = 'arm'
cpu = 'arm'
endian = 'little'
Modify the compilation settings by changing the true to false for the following three items in 'meson_options.txt'. Note that 'dbus' and 'install-init-files' may be required, but since I'm not sure how to handle the compilation errors they may cause, I've disabled them for now.
Code:
option('dbus', type: 'boolean', value: 'false',
       description: 'use dbus')
option('specfile', type : 'boolean', value: false,
       description: 'whether to prepare RPM spec')
option('install-init-files', type : 'boolean', value: false,
       description: 'whether to install init files for local init (e.g. systemd units)')
After that, execute the following command to compile successfully. The resulting executable files will be located in the 'out' directory.
Code:
meson setup --cross-file cross.txt --default-library=static -Db_lto=false build
meson compile -C build
DESTDIR=~/kindle/gplrelease/lxc/out/ meson install -C build
Since lxc-checkconfig requires zgrep, I also compiled a gzip
Code:
./configure --host=arm-linux --prefix=~/kindle/gplrelease/gzip-1.2.4/out CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ --enable-shared --enable-static --disable-test
make LDFLAGS="--static"
make install DESTDIR=~/kindle/gplrelease/gzip-1.2.4/out/
I'm not sure whether to set the 'prefix' or 'DESTDIR' for gzip. I didn't see anything related to 'DESTDIR' in the Makefile, so I set both.

Finally, I directly executed lxc-checkconfig on the Kindle and obtained results similar to those of an Alpine chroot.
Code:
[root@kindle bin]# pwd
/mnt/us/lxc/usr/local/bin
[root@kindle bin]# ls
check.log          lxc-checkpoint     lxc-destroy        lxc-ls             lxc-top            lxc-wait
lxc-attach         lxc-config         lxc-device         lxc-monitor        lxc-unfreeze       zgrep
lxc-autostart      lxc-console        lxc-execute        lxc-snapshot       lxc-unshare
lxc-cgroup         lxc-copy           lxc-freeze         lxc-start          lxc-update-config
lxc-checkconfig    lxc-create         lxc-info           lxc-stop           lxc-usernsexec
[root@kindle bin]# export PATH=${PATH}:/mnt/us/lxc/usr/local/bin
[root@kindle bin]# lxc-checkconfig
lxc-start: error while loading shared libraries: liblxc.so.1: cannot open shared object file: No such file or director                                                           y
LXC version

--- Namespaces ---
Namespaces: required
Utsname namespace: missing
Ipc namespace: required
Pid namespace: required
User namespace: missing
Network namespace: missing
Namespace limits:
  cgroup: 3767
  ipc: 3767
  mnt: 3767
  net: 3767
  pid: 3767
  user: 3767
  uts: 3767

--- Control groups ---
Cgroups: enabled
Cgroup namespace: enabled
Cgroup v1 mount points:
 - /sys/fs/cgroup/memory
Cgroup v2 mount points:
Cgroup v1 systemd controller: missing
Cgroup v1 freezer controller: missing
Cgroup v1 clone_children flag: enabled
Cgroup device: missing
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: missing
Macvlan: missing
Vlan: enabled, not loaded
Bridges: enabled, not loaded
Advanced netfilter: enabled, not loaded
CONFIG_NF_NAT_IPV4: enabled, not loaded
CONFIG_NF_NAT_IPV6: missing
CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_IP6_NF_TARGET_MASQUERADE: missing
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: missing
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
FUSE (for use with lxcfs): enabled, not loaded

--- Checkpoint/Restore ---
checkpoint restore: missing
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: missing
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: missing
CONFIG_NETLINK_DIAG: missing
File capabilities: enabled

Note: Before booting a new kernel, you can check its configuration with:

  CONFIG=/path/to/config /mnt/us/lxc/usr/local/bin/lxc-checkconfig
Due to my limited understanding of Linux and Android, and uncertainty about whether my actions are correct, I've detailed all my steps in the article. Currently, I only know that this method allows running Android with lower risk and performance loss. It seems challenging to run Android on a device with only 512MB of RAM, but some people have successfully run it on the Kindle Paperwhite 3 by flashing the original Kindle system, which is fundamentally different from what I'm doing now. However, I still want to give it a try. Lastly, I apologize for using translation to post my message.
WuYung is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Can android apps run on Kindle? stankovic Amazon Kindle 4 02-02-2015 02:57 AM
Run Android Apps on your Windows PC Dave_S Android Devices 4 04-13-2012 06:52 PM


All times are GMT -4. The time now is 03:42 PM.


MobileRead.com is a privately owned, operated and funded community.