Posted
over 2 years
ago
by
Thomas Perl
This depends on Bounce (the N900 .deb) and SDL 1.2 being installed. Google "bounce_1.0.0_armel.deb" for the former, and use n9repomirror for the latter.This is available on OpenRepos: https://openrepos.net/content/thp/rebounce
Also on
... [More]
TMO: https://talk.maemo.org/showthread.php?t=101160
Also on Twitter: https://twitter.com/thp4/status/1359758278620758019
Source code (copy'n'paste this into a file named "rebounce.c", then run it using your shell):
#if 0
gcc -Os -shared -fPIC -lSDL -o librebounce.so rebounce.c
LD_PRELOAD=$(pwd)/librebounce.so /opt/bounce/bin/bounce
exit 0
#endif
/**
* reBounce -- softfp-to-hardfp LD_PRELOAD hack for Bounce on N9
*
* Bounce was a really nice 2009 tech demo on the N900. This
* makes this tech demo work on an N9 by translating the calls
* that use floating point arguments to the hardfp ABI. It also
* fixes input using SDL1.2 to get sensor values from sensorfw.
*
* Known issues: Audio is muted on startup until mute is toggled.
*
* 2021-02-11 Thomas Perl
**/
#define _GNU_SOURCE
#include
#include
#include
#include
#define SFP __attribute__((pcs("aapcs")))
typedef unsigned int GLuint;
static void *
sensor_thread(void *user_data)
{
SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
SDL_Joystick *accelerometer = SDL_JoystickOpen(0);
while (1) {
SDL_JoystickUpdate();
float x = 0.053888f * SDL_JoystickGetAxis(accelerometer, 0);
float y = 0.053888f * SDL_JoystickGetAxis(accelerometer, 1);
float z = 0.053888f * SDL_JoystickGetAxis(accelerometer, 2);
FILE *out = fopen("/dev/shm/bounce.sensor.tmp", "wb");
fprintf(out, "%f %f %f\n", -y, x, z);
fclose(out);
rename("/dev/shm/bounce.sensor.tmp", "/dev/shm/bounce.sensor");
SDL_Delay(10);
}
return NULL;
}
FILE *
fopen(const char *filename, const char *mode)
{
FILE *(*fopen_orig)(const char *, const char *) = dlsym(RTLD_NEXT, "fopen");
if (strcmp(filename, "/sys/class/i2c-adapter/i2c-3/3-001d/coord") == 0) {
static int sensor_inited = 0;
if (!sensor_inited) {
sensor_inited = 1;
pthread_t thread;
pthread_create(&thread, NULL, sensor_thread, NULL);
}
filename = "/dev/shm/bounce.sensor";
}
return fopen_orig(filename, mode);
}
#define f_f(name) float SFP name(float x) { return ((float (*)(float))dlsym(RTLD_NEXT, #name))(x); }
#define d_d(name) double SFP name(double x) { return ((double (*)(double))dlsym(RTLD_NEXT, #name))(x); }
#define f_ff(name) float SFP name(float x, float y) { return ((float (*)(float, float))dlsym(RTLD_NEXT, #name))(x, y); }
#define d_dd(name) double SFP name(double x, double y) { return ((double (*)(double, double))dlsym(RTLD_NEXT, #name))(x, y); }
f_f(sinhf) f_f(coshf) f_f(tanhf) f_f(asinf) f_f(acosf) f_f(atanf) f_f(sinf) f_f(cosf) f_f(tanf) f_f(expf) f_f(logf)
f_f(log10f) f_f(ceilf) f_f(floorf) d_d(log) d_d(sin) f_ff(atan2f) f_ff(fmodf) d_dd(atan2) d_dd(pow) d_dd(fmod)
double SFP
frexp(double value, int *exp)
{
return ((double (*)(double, int *))dlsym(RTLD_NEXT, "frexp"))(value, exp);
}
double SFP
ldexp(double x, int n)
{
return ((double (*)(double, int))dlsym(RTLD_NEXT, "ldexp"))(x, n);
}
double SFP
modf(double value, double *iptr)
{
return ((double (*)(double, double *))dlsym(RTLD_NEXT, "modf"))(value, iptr);
}
void SFP
glClearColor(float r, float g, float b, float a)
{
((void (*)(float, float, float, float))dlsym(RTLD_NEXT, "glClearColor"))(r, g, b, a);
}
void SFP
glUniform4f(GLuint location, float v0, float v1, float v2, float v3)
{
((void (*)(GLuint, float, float, float, float))dlsym(RTLD_NEXT, "glUniform4f"))(location, v0, v1, v2, v3);
}
void SFP
glUniform1f(GLuint location, float v0)
{
((void (*)(GLuint, float))dlsym(RTLD_NEXT, "glUniform1f"))(location, v0);
}
0 0 [Less]
|
Posted
over 2 years
ago
by
Alberto Mardegan
This is the second part of my porting odyssey; for the first part, follow this
link.
The good news is that I've done some progress; the bad news is that there are
still plenty of issues, and solving them involves deep diving into nearly all
... [More]
components and technologies that make up the core of an Android device, so
completing the porting is going to take quite some time. On the other hand, I'm
learning a lot of new stuff, and I might be able to share it by writing some
documentation. And, who knows, maybe work on some other device port.
Anyway, enough with the introduction! Let's see what progress I've been doing
so far.
The new device tree
While asking for help to debug the audio issue I was facing (more about that
later), I was also told that the lavender tree, which I was using as a
reference, was obsolete. The new one was in
gitlab,
and was build with a totally different system, described
here.
So, I picked the lavender tree and adapted it for violet: I changed the
deviceinfo file to point to my kernel tree, use my kernel configuration, and
use the same boot command line as before. By the way, here's my current "new"
device
tree. The
build failed, with errors like:
In function 'memcpy',
inlined from 'proc_ipc_auto_msgmni.part.1' at /home/mardy/projects/port/xiaomi-violet/bd/downloads/android_kernel_xiaomi_violet/ipc/ipc_sysctl.c:82:2:
/home/mardy/projects/port/xiaomi-violet/bd/downloads/android_kernel_xiaomi_violet/include/linux/string.h:340:4: error: call to '__read_overflow2' declared with attribute error: detected read beyond size of object passed as 2nd parameter
__read_overflow2();
^
I then replayed the kernel build using the old system, and noticed that it was
using clang as the compiler; so I changed the related flag in the deviceinfo
file, and the build went past that point. It failed later, though:
/home/mardy/projects/port/xiaomi-violet/bd/downloads/android_kernel_xiaomi_violet/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c:1498:26: error: cast to smaller integer type 'eSapStatus' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
bss_complete->status = (eSapStatus) context;
^~~~~~~~~~~~~~~~~~~~
I ended up editing the Kbuild file in the module source directory, and
removed
the -Werror from there (as well in another place that failed a bit later).
This made the build proceed until the end, where it failed because the device
tree file was not found:
+ cp -v /home/mardy/projects/port/xiaomi-violet/bd/downloads/KERNEL_OBJ/arch/arm64/boot/dts/qcom/sm8150-mtp-overlay.dtbo /home/mardy/projects/port/xiaomi-violet/bd/tmp/partitions/dtbo.img
cp: cannot stat '/home/mardy/projects/port/xiaomi-violet/bd/downloads/KERNEL_OBJ/arch/arm64/boot/dts/qcom/sm8150-mtp-overlay.dtbo': No such file or directory
I quickly realized that this was due to an error of mine: the Xiaomi violet
is a sm6150, not a sm8150 as mentioned in my deviceinfo file! But what
overlay file should I use then, since there isn't a sm6150-mtp-overlay.dts in
my source tree? Having a loot at other deviceinfo
files,
I saw that the deviceinfo_kernel_dtb_overlay line is not always there, so I
tried commenting it out, and it helped.
The next step was getting flashable images, of course. While the device is not
supported by the UBports system-image server, we can use use some scripts to
create a fake OTA (Over The Air update) and generate flashable images starting
from it. The steps can be read in the devel-flashable target of the
.gitlab-ci.yml file (if this step is not present, we should try to find
another device
repository which has it.
They are the following:
./build/prepare-fake-ota.sh out/device_violet.tar.xz ota
./build/system-image-from-ota.sh ota/ubuntu_command out
Once these commands have completed their execution, these commands will push
the images to the device:
fastboot flash boot out/boot.img; fastboot flash system out/system.img
There's also fastboot flash recovery out/recovery.img, but I left it out
since I was not interested in the recovery image at this stage. And unless you
are ready to submit your port for inclusion into the "supported devices" list,
I'd recommend not flashing the UT recovery image since TWRP is more powerful
and will likely help you in recover your device from a broken image.
Kernel command line
It's important that the kernel command line contains the systempart
parameter. In my case, the first boot failed because the command line was
longer than 512 bytes, and this parameter was getting truncated. So one thing
to be careful about is the length of the kernel command line.
This was fixed by removing some unnecessary kernel
parameters
from the deviceinfo file.
Missing thumbnails in the Gallery app, content-hub not working
Another issue I noticed is that photo thumbnails were all black in the Gallery
app, and the content-hub also was not working.
I noticed a relevant commit in the lavender kernel
tree
and found a launchpad bug
which mentioned the issues I was seeing. In the Telegram channel I was told
that patch is a forward port of a commit from kernel 3.4 that was present in
all of the cores devices, and that it was indeed needed to have the ContentHub
working.
The patch did not apply cleanly on top of my kernel tree, but luckily it was
just an offset issue: adjusting the
patch
was easy, and indeed after applying it thumbnails started appearing in the
Gallery and
Imaginario could import photos again via the
ContentHub.
Time and date
Time was always reset to a far away date after a reboot. This is a common issue
on Qualcomm devices, and can be fixed by disabling the time service in the
Android container.
https://github.com/Halium/android_device_halium_halium_arm64/pull/3
For some reason, at a certain point my override stopped working (or, more
likely, the override never worked, but I happened to have fixed the issue
directly modifying the vendor init file). I had to copy
/android/vendor/etc/init/hw/init.qcom.rc into /usr/share/halium-overrides/,
modify it and bind mount the modified file in order to get it working.
This actually seems to match my understanding of the Android init
documentation,
because according to the path priorities a configuration file stored under
/system/ will never be able to override one stored under /vendor.
Fixing the audio configuration
Audio was not working at all. The sound indicator icon was not shown, only the
raw (unstranslated) "indicator-sound" text was shown in the panel. pulseaudio
was not running. Trying to run it manually (as the phablet user, since
pulseaudio is run in the user session) led to this:
[email protected]:~$ pulseaudio -n -vvv -F /etc/pulse/touch-android9.pa
I: [pulseaudio] main.c: setrlimit(RLIMIT_NICE, (31, 31)) failed: Operation not permitted
I: [pulseaudio] main.c: setrlimit(RLIMIT_RTPRIO, (9, 9)) failed: Operation not permitted
...
D: [pulseaudio] cli-command.c: Parsing script '/etc/pulse/touch-android9.pa'
D: [pulseaudio] database-tdb.c: Opened TDB database '/home/phablet/.config/pulse/ubuntu-phablet-stream-volumes.tdb'
I: [pulseaudio] module-stream-restore.c: Successfully opened database file '/home/phablet/.config/pulse/ubuntu-phablet-stream-volumes'.
...
D: [pulseaudio] module.c: Checking for existence of '/usr/lib/pulse-8.0/modules/module-droid-card-28.so': success
I: [pulseaudio] module-droid-card.c: Create new droid-card
D: [pulseaudio] droid-util.c: No configuration provided for opening module with id primary
I: [pulseaudio] config-parser-xml.c: Failed to open file (/odm/etc/audio_policy_configuration.xml): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /odm/etc/audio_policy_configuration.xml
D: [pulseaudio] config-parser-xml.c: Read /vendor/etc/audio/audio_policy_configuration.xml ...
D: [pulseaudio] config-parser-xml.c: New module: "primary"
W: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio/audio_policy_configuration.xml:78] Could not find element attribute "samplingRates"
E: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio/audio_policy_configuration.xml:78] Failed to parse element
E: [pulseaudio] config-parser-xml.c: parsing aborted at line 78
D: [pulseaudio] droid-config.c: Failed to parse configuration from /vendor/etc/audio/audio_policy_configuration.xml
D: [pulseaudio] config-parser-xml.c: Read /vendor/etc/audio_policy_configuration.xml ...
D: [pulseaudio] config-parser-xml.c: New module: "primary"
W: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio_policy_configuration.xml:78] Could not find element attribute "samplingRates"
E: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio_policy_configuration.xml:78] Failed to parse element
E: [pulseaudio] config-parser-xml.c: parsing aborted at line 78
D: [pulseaudio] droid-config.c: Failed to parse configuration from /vendor/etc/audio_policy_configuration.xml
I: [pulseaudio] config-parser-legacy.c: Failed to open config file (/vendor/etc/audio_policy.conf): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /vendor/etc/audio_policy.conf
I: [pulseaudio] config-parser-xml.c: Failed to open file (/system/etc/audio_policy_configuration.xml): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /system/etc/audio_policy_configuration.xml
I: [pulseaudio] config-parser-legacy.c: Failed to open config file (/system/etc/audio_policy.conf): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /system/etc/audio_policy.conf
E: [pulseaudio] droid-config.c: Failed to parse any configuration.
...
Indeed, line 78 of /vendor/etc/audio_policy_configuration.xml had an error,
where a property was spelt like simplingRate instead of samplingRate.
However, the "vendor" partition is read-only, so I couldn't change that file
directly. Another option could have been creating a fixed copy of the file and
place it with /system/etc/audio_policy_configuration.xml, but the "system" is
also read-only (there are ways to modify these partitions, of course, but I
couldn't find a clean way to do it from the device tree scripts. So I went for
the bind-mount approach: I would ship the fixed file in some other directory of
the file-system, and then modify the /etc/init/mount-android.conf file (this
is the job that upstart executes before starting the Android LXC container) to
bind-mount the file onto /vendor/etc/audio_policy_configuration.xml.
This worked, but my joy was short-lived: audio was coming up only once every 5
boots or so. I will not list here all the things I tried, as they were plenty
of them; and more than once I went to sleep happy and convinced of having fixed
the issue for good, until the next day the device booted without audio. It was
clearly a timing issue occurring in the early boot, because one thing I clearly
noticed very early on is that in those cases when the audio was booting, the
following lines appeared in the kernel log:
[ 7.130057] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vdd-ldo-rxtx: vol=[1800000 1800000]uV, curr=[25000]uA, ond 0
[ 7.130068] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vddpx-1: vol=[1800000 1800000]uV, curr=[10000]uA, ond 0
[ 7.130076] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vdd-mic-bias: vol=[3296000 3296000]uV, curr=[25000]uA, ond 0
[ 7.130084] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vdd-buck: vol=[1800000 1800000]uV, curr=[650000]uA, ond 1
[ 7.137759] wcd937x_codec wcd937x-codec: bound wcd937x-slave.1170224 (ops cleanup_module [wcd937x_slave_dlkm])
[ 7.138065] wcd937x_codec wcd937x-codec: bound wcd937x-slave.1170223 (ops cleanup_module [wcd937x_slave_dlkm])
I started adding some printk to the kernel driver, and modified
it slightly to register itself with the module_driver() macro instead of the
simpler, but logless, module_platform_driver(). This showed that the driver
was always loaded at about 7 seconds, but the platform_driver_register()
method only called the driver's bind method (wcd937x_bind()) in those boots
where audio was working.
After more debugging into platform_driver_register(), I stumbled upon the
platform_match()
function, added some debugging message in there to print the device name and
the driver name, and observed how in those boots where audio was failing this
function was called to find a driver for the wcd937x_codec device before
the wcd937x_codec driver (provided by the wcd937x_dlmk module) was
available. So, I tried adding wcd937x_dlmk to
/etc/modules-load.d/modules.conf and this caused the driver to be loaded at
about 3 seconds, and apparently fixed the audio issue. At least, till the time
of writing this, I never had my phone boot without audio anymore.
Not all is fine with the audio, unfortunately: the mic records a background
noise along with the actual sounds, and the recording volume is quite low. This
also affects the call quality. On the other hand, the noise disappears when
recording happens via the earphones. But I've yet to investigate this; I hope
to give you some updates in part three.
0 0 [Less]
|
Posted
over 2 years
ago
by
Alberto Mardegan
This is the second part of my porting odyssey; for the first part, follow this
link.
The good news is that I've done some progress; the bad news is that there are
still plenty of issues, and solving them involves deep diving into nearly all
... [More]
components and technologies that make up the core of an Android device, so
completing the porting is going to take quite some time. On the other hand, I'm
learning a lot of new stuff, and I might be able to share it by writing some
documentation. And, who knows, maybe work on some other device port.
Anyway, enough with the introduction! Let's see what progress I've been doing
so far.
The new device tree
While asking for help to debug the audio issue I was facing (more about that
later), I was also told that the lavender tree, which I was using as a
reference, was obsolete. The new one was in
gitlab,
and was build with a totally different system, described
here.
So, I picked the lavender tree and adapted it for violet: I changed the
deviceinfo file to point to my kernel tree, use my kernel configuration, and
use the same boot command line as before. By the way, here's my current "new"
device
tree. The
build failed, with errors like:
In function 'memcpy',
inlined from 'proc_ipc_auto_msgmni.part.1' at /home/mardy/projects/port/xiaomi-violet/bd/downloads/android_kernel_xiaomi_violet/ipc/ipc_sysctl.c:82:2:
/home/mardy/projects/port/xiaomi-violet/bd/downloads/android_kernel_xiaomi_violet/include/linux/string.h:340:4: error: call to '__read_overflow2' declared with attribute error: detected read beyond size of object passed as 2nd parameter
__read_overflow2();
^
I then replayed the kernel build using the old system, and noticed that it was
using clang as the compiler; so I changed the related flag in the deviceinfo
file, and the build went past that point. It failed later, though:
/home/mardy/projects/port/xiaomi-violet/bd/downloads/android_kernel_xiaomi_violet/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c:1498:26: error: cast to smaller integer type 'eSapStatus' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
bss_complete->status = (eSapStatus) context;
^~~~~~~~~~~~~~~~~~~~
I ended up editing the Kbuild file in the module source directory, and
removed
the -Werror from there (as well in another place that failed a bit later).
This made the build proceed until the end, where it failed because the device
tree file was not found:
+ cp -v /home/mardy/projects/port/xiaomi-violet/bd/downloads/KERNEL_OBJ/arch/arm64/boot/dts/qcom/sm8150-mtp-overlay.dtbo /home/mardy/projects/port/xiaomi-violet/bd/tmp/partitions/dtbo.img
cp: cannot stat '/home/mardy/projects/port/xiaomi-violet/bd/downloads/KERNEL_OBJ/arch/arm64/boot/dts/qcom/sm8150-mtp-overlay.dtbo': No such file or directory
I quickly realized that this was due to an error of mine: the Xiaomi violet
is a sm6150, not a sm8150 as mentioned in my deviceinfo file! But what
overlay file should I use then, since there isn't a sm6150-mtp-overlay.dts in
my source tree? Having a loot at other deviceinfo
files,
I saw that the deviceinfo_kernel_dtb_overlay line is not always there, so I
tried commenting it out, and it helped.
The next step was getting flashable images, of course. While the device is not
supported by the UBports system-image server, we can use use some scripts to
create a fake OTA (Over The Air update) and generate flashable images starting
from it. The steps can be read in the devel-flashable target of the
.gitlab-ci.yml file (if this step is not present, we should try to find
another device
repository which has it.
They are the following:
./build/prepare-fake-ota.sh out/device_violet.tar.xz ota
./build/system-image-from-ota.sh ota/ubuntu_command out
Once these commands have completed their execution, these commands will push
the images to the device:
fastboot flash boot out/boot.img; fastboot flash system out/system.img
There's also fastboot flash recovery out/recovery.img, but I left it out
since I was not interested in the recovery image at this stage. And unless you
are ready to submit your port for inclusion into the "supported devices" list,
I'd recommend not flashing the UT recovery image since TWRP is more powerful
and will likely help you in recover your device from a broken image.
Kernel command line
It's important that the kernel command line contains the systempart
parameter. In my case, the first boot failed because the command line was
longer than 512 bytes, and this parameter was getting truncated. So one thing
to be careful about is the length of the kernel command line.
This was fixed by removing some unnecessary kernel
parameters
from the deviceinfo file.
Missing thumbnails in the Gallery app, content-hub not working
Another issue I noticed is that photo thumbnails were all black in the Gallery
app, and the content-hub also was not working.
I noticed a relevant commit in the lavender kernel
tree
and found a launchpad bug
which mentioned the issues I was seeing. In the Telegram channel I was told
that patch is a forward port of a commit from kernel 3.4 that was present in
all of the cores devices, and that it was indeed needed to have the ContentHub
working.
The patch did not apply cleanly on top of my kernel tree, but luckily it was
just an offset issue: adjusting the
patch
was easy, and indeed after applying it thumbnails started appearing in the
Gallery and
Imaginario could import photos again via the
ContentHub.
Time and date
Time was always reset to a far away date after a reboot. This is a common issue
on Qualcomm devices, and can be fixed by disabling the time service in the
Android container.
https://github.com/Halium/android_device_halium_halium_arm64/pull/3
For some reason, at a certain point my override stopped working (or, more
likely, the override never worked, but I happened to have fixed the issue
directly modifying the vendor init file). I had to copy
/android/vendor/etc/init/hw/init.qcom.rc into /usr/share/halium-overrides/,
modify it and bind mount the modified file in order to get it working.
This actually seems to match my understanding of the Android init
documentation,
because according to the path priorities a configuration file stored under
/system/ will never be able to override one stored under /vendor.
Fixing the audio configuration
Audio was not working at all. The sound indicator icon was not shown, only the
raw (unstranslated) "indicator-sound" text was shown in the panel. pulseaudio
was not running. Trying to run it manually (as the phablet user, since
pulseaudio is run in the user session) led to this:
[email protected]:~$ pulseaudio -n -vvv -F /etc/pulse/touch-android9.pa
I: [pulseaudio] main.c: setrlimit(RLIMIT_NICE, (31, 31)) failed: Operation not permitted
I: [pulseaudio] main.c: setrlimit(RLIMIT_RTPRIO, (9, 9)) failed: Operation not permitted
...
D: [pulseaudio] cli-command.c: Parsing script '/etc/pulse/touch-android9.pa'
D: [pulseaudio] database-tdb.c: Opened TDB database '/home/phablet/.config/pulse/ubuntu-phablet-stream-volumes.tdb'
I: [pulseaudio] module-stream-restore.c: Successfully opened database file '/home/phablet/.config/pulse/ubuntu-phablet-stream-volumes'.
...
D: [pulseaudio] module.c: Checking for existence of '/usr/lib/pulse-8.0/modules/module-droid-card-28.so': success
I: [pulseaudio] module-droid-card.c: Create new droid-card
D: [pulseaudio] droid-util.c: No configuration provided for opening module with id primary
I: [pulseaudio] config-parser-xml.c: Failed to open file (/odm/etc/audio_policy_configuration.xml): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /odm/etc/audio_policy_configuration.xml
D: [pulseaudio] config-parser-xml.c: Read /vendor/etc/audio/audio_policy_configuration.xml ...
D: [pulseaudio] config-parser-xml.c: New module: "primary"
W: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio/audio_policy_configuration.xml:78] Could not find element attribute "samplingRates"
E: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio/audio_policy_configuration.xml:78] Failed to parse element
E: [pulseaudio] config-parser-xml.c: parsing aborted at line 78
D: [pulseaudio] droid-config.c: Failed to parse configuration from /vendor/etc/audio/audio_policy_configuration.xml
D: [pulseaudio] config-parser-xml.c: Read /vendor/etc/audio_policy_configuration.xml ...
D: [pulseaudio] config-parser-xml.c: New module: "primary"
W: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio_policy_configuration.xml:78] Could not find element attribute "samplingRates"
E: [pulseaudio] config-parser-xml.c: [/vendor/etc/audio_policy_configuration.xml:78] Failed to parse element
E: [pulseaudio] config-parser-xml.c: parsing aborted at line 78
D: [pulseaudio] droid-config.c: Failed to parse configuration from /vendor/etc/audio_policy_configuration.xml
I: [pulseaudio] config-parser-legacy.c: Failed to open config file (/vendor/etc/audio_policy.conf): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /vendor/etc/audio_policy.conf
I: [pulseaudio] config-parser-xml.c: Failed to open file (/system/etc/audio_policy_configuration.xml): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /system/etc/audio_policy_configuration.xml
I: [pulseaudio] config-parser-legacy.c: Failed to open config file (/system/etc/audio_policy.conf): No such file or directory
D: [pulseaudio] droid-config.c: Failed to parse configuration from /system/etc/audio_policy.conf
E: [pulseaudio] droid-config.c: Failed to parse any configuration.
...
Indeed, line 78 of /vendor/etc/audio_policy_configuration.xml had an error,
where a property was spelt like simplingRate instead of samplingRate.
However, the "vendor" partition is read-only, so I couldn't change that file
directly. Another option could have been creating a fixed copy of the file and
place it with /system/etc/audio_policy_configuration.xml, but the "system" is
also read-only (there are ways to modify these partitions, of course, but I
couldn't find a clean way to do it from the device tree scripts. So I went for
the bind-mount approach: I would ship the fixed file in some other directory of
the file-system, and then modify the /etc/init/mount-android.conf file (this
is the job that upstart executes before starting the Android LXC container) to
bind-mount the file onto /vendor/etc/audio_policy_configuration.xml.
This worked, but my joy was short-lived: audio was coming up only once every 5
boots or so. I will not list here all the things I tried, as they were plenty
of them; and more than once I went to sleep happy and convinced of having fixed
the issue for good, until the next day the device booted without audio. It was
clearly a timing issue occurring in the early boot, because one thing I clearly
noticed very early on is that in those cases when the audio was booting, the
following lines appeared in the kernel log:
[ 7.130057] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vdd-ldo-rxtx: vol=[1800000 1800000]uV, curr=[25000]uA, ond 0
[ 7.130068] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vddpx-1: vol=[1800000 1800000]uV, curr=[10000]uA, ond 0
[ 7.130076] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vdd-mic-bias: vol=[3296000 3296000]uV, curr=[25000]uA, ond 0
[ 7.130084] wcd937x_codec wcd937x-codec: msm_cdc_dt_parse_vreg_info: cdc-vdd-buck: vol=[1800000 1800000]uV, curr=[650000]uA, ond 1
[ 7.137759] wcd937x_codec wcd937x-codec: bound wcd937x-slave.1170224 (ops cleanup_module [wcd937x_slave_dlkm])
[ 7.138065] wcd937x_codec wcd937x-codec: bound wcd937x-slave.1170223 (ops cleanup_module [wcd937x_slave_dlkm])
I started adding some printk to the kernel driver, and modified
it slightly to register itself with the module_driver() macro instead of the
simpler, but logless, module_platform_driver(). This showed that the driver
was always loaded at about 7 seconds, but the platform_driver_register()
method only called the driver's bind method (wcd937x_bind()) in those boots
where audio was working.
After more debugging into platform_driver_register(), I stumbled upon the
platform_match()
function, added some debugging message in there to print the device name and
the driver name, and observed how in those boots where audio was failing this
function was called to find a driver for the wcd937x_codec device before
the wcd937x_codec driver (provided by the wcd937x_dlmk module) was
available. So, I tried adding wcd937x_dlmk to
/etc/modules-load.d/modules.conf and this caused the driver to be loaded at
about 3 seconds, and apparently fixed the audio issue. At least, till the time
of writing this, I never had my phone boot without audio anymore.
Not all is fine with the audio, unfortunately: the mic records a background
noise along with the actual sounds, and the recording volume is quite low. This
also affects the call quality. On the other hand, the noise disappears when
recording happens via the earphones. But I've yet to investigate this; I hope
to give you some updates in part three. [Less]
|
Posted
over 2 years
ago
by
Alberto Mardegan
In case you have a sense of deja-vu when reading this post, it's because
indeed this is not the first time I try porting a device to Ubuntu Touch. The
previous
attempt,
however, was with another phone model (and manufacturer), and did not have a
... [More]
happy ending. This time it went better, although the real ending is still far
away; but at least I have something to celebrate.
The phone
I made myself a Christmas present and bought a Xiaomi Redmi Note 7 Pro, a
dual-SIM phone from 2019 with 6GB of RAM and 128GB of flash storage. To be
totally honest, I bought it by mistake: the phone I really wanted to buy is the
Redmi Note 7 (without the "Pro"), because it's a modern phone that is working
reasonable well with Ubuntu Touch. The online shop where I bought it from let
me choose some options, including the RAM size, so I chose the maximum
available (6GB) without being aware that this would mean that I would be buying
the "Pro" device — the shop did not alter the item name, so I couldn't really
know. Unfortunately, the two versions are two rather different beasts, powered
by different SoC; both are produced by Qualcomm, so they are not that
different, but it's enough to make the installation of Ubuntu Touch impossible.
But between the choice of retuning the phone to the shop and begin a new
porting adventure, I stood firm and went for the latter. Hopefully I won't
regret it (if everything goes bad, I can still use it with LineageOS, which
runs perfectly on it).
Moreover, there already exist a port of Ubuntu Touch for this phone, which
actually works reasonably well (I tried it briefly, and many things were
working), but the author claims to be a novice and indeed did not follow the
best git practices when working on the source code, so it's hard to understand
what was changed and why. But if you are looking for a quick way to get Ubuntu
Touch working on this phone, you are welcome to have a look at this Telegram
channel.
What follows are the raw notes of my attempts. They are here so that search
engines can index the error messages and the various logs, and hopefully help
someone hitting similar errors on other devices to find his way out.
Getting Halium and the device source code
Installed the dependencies like in the first step. repo was not found in the
Ubuntu 20.04 archives, but I had it installed anyway due to my work on a Yocto
device.
Since my device has Android 9 on it, I went for Halium 9:
repo init -u git://github.com/Halium/android.git -b halium-9.0 --depth=1
repo sync -c -j 16
The official LineageOS repository for the Xiaomi Redmi Note 7 Pro is
android_device_xiaomi_violet,
but the page with the official build
has been taken down (some DMCA violation, if you believe the
forums)
and no development has been happening since last year. A more active forum
thread
uses another repository which seems to be receiving more frequent updates, so I
chose to base my port on that.
I actually tested that LineageOS image on my phone, and verified that all the
hardware was working properly.
Initially, I created forks of the relevant repository under my own gitlab
account, but then I though (especially looking at the Note 7 port)
that creating a group just for this port would make people's life easier,
because they wouldn't need to navigate through my 1000 personal projects
to find what is relevant for this port. So, I created these forks:
gitlab.com/ubuntu-touch-xiaomi-violet/android_device_xiaomi_violet
gitlab.com/ubuntu-touch-xiaomi-violet/android_kernel_xiaomi_violet
gitlab.com/ubuntu-touch-xiaomi-violet/android_vendor_xiaomi_violet
Next, created the halium/devices/manifests/xiaomi_violet.xml file with this content:
name="ubuntu-touch-xiaomi-violet"
fetch="https://gitlab.com/ubuntu-touch-xiaomi-violet"
revision="halium-9.0"/>
path="device/xiaomi/violet"
name="android_device_xiaomi_violet"
remote="ubuntu-touch-xiaomi-violet" />
path="kernel/xiaomi/violet"
name="android_kernel_xiaomi_violet"
remote="ubuntu-touch-xiaomi-violet" />
path="vendor/xiaomi/violet"
name="android_vendor_xiaomi_violet"
remote="ubuntu-touch-xiaomi-violet" />
Fetching all the sources mentioned in the manifest:
./halium/devices/setup violet
Full output:
*****************************************
I: Configuring for device xiaomi_violet
*****************************************
Fetching projects: 100% (393/393), done.
hardware/qcom/audio-caf/apq8084: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8916: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8952: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8960: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8974: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8994: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8996: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8998: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/sdm845: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/sm8150: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio/default: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/display: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/apq8084: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8916: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8952: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8960: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8974: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8994: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8996: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8998: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/sdm845: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/sm8150: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/media: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/apq8084: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8916: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8952: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8960: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8974: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8994: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8996: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8998: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/sdm845: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/sm8150: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/ril: Shared project LineageOS/android_hardware_ril found, disabling pruning.
hardware/ril-caf: Shared project LineageOS/android_hardware_ril found, disabling pruning.
hardware/qcom/wlan: Shared project LineageOS/android_hardware_qcom_wlan found, disabling pruning.
hardware/qcom/wlan-caf: Shared project LineageOS/android_hardware_qcom_wlan found, disabling pruning.
hardware/qcom/bt: Shared project LineageOS/android_hardware_qcom_bt found, disabling pruning.
hardware/qcom/bt-caf: Shared project LineageOS/android_hardware_qcom_bt found, disabling pruning.
Updating files: 100% (67031/67031), done.nel/testsUpdating files: 36% (24663/67031)
lineage/scripts/: discarding 1 commits
Updating files: 100% (1406/1406), done.ineageOS/android_vendor_qcom_opensource_thermal-engineUpdating files: 47% (666/1406)
Checking out projects: 100% (392/392), done.
*******************************************
I: Refreshing device vendor repository: device/xiaomi/violet
I: Processing proprietary blob file: device/xiaomi/violet/./proprietary-files.txt
I: Processing fstab file: device/xiaomi/violet/./rootdir/etc/fstab.qcom
I: Removing components relying on SettingsLib from: device/xiaomi/violet
*******************************************
Starting the build
Setting up the environment:
$ source build/envsetup.sh
including device/xiaomi/violet/vendorsetup.sh
including vendor/lineage/vendorsetup.sh
$
Running the breakfast command:
$ breakfast violet
including vendor/lineage/vendorsetup.sh
Trying dependencies-only mode on a non-existing device tree?
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
LINEAGE_VERSION=16.0-20210109-UNOFFICIAL-violet
TARGET_PRODUCT=lineage_violet
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo300
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv8-a
TARGET_2ND_CPU_VARIANT=cortex-a75
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.4.0-58-generic-x86_64-Ubuntu-20.04.1-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=PQ3A.190801.002
OUT_DIR=/home/mardy/projects/port/halium/out
PRODUCT_SOONG_NAMESPACES= hardware/qcom/audio-caf/sm8150 hardware/qcom/display-caf/sm8150 hardware/qcom/media-caf/sm8150
============================================
Building the kernel
The configuration needs to be adapted for Halium. Locating the kernel config:
$ grep "TARGET_KERNEL_CONFIG" device/xiaomi/violet/BoardConfig.mk
TARGET_KERNEL_CONFIG := vendor/violet-perf_defconfig
$
Getting the Mer checker tool and running it:
git clone https://github.com/mer-hybris/mer-kernel-check
cd mer-kernel-check
./mer_verify_kernel_config ../kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig
Prints lots of warnings, starting with:
WARNING: kernel version missing, some reports maybe misleading
To help the tool, we need to let him know the kernel version. It can be seen at
the beginning of the kernel Makefile, located in
../kernel/xiaomi/violet/Makefile; in my case it was
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 83
EXTRAVERSION =
So I edited the configuration file
../kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig and
added this line at the beginning:
# Version 4.14.83
then ran the checker tool again. This time the output was a long list of kernel
options that needed to be fixed, but as I went asking for some explanation in
the Telegram channel for Ubuntu Touch porters, I was told that I could/should
skip this test and instead use the check-kernel-config tool from
Halium.
I downloaded it, made it executable (chmod +x check-kernel-config) and ran
it:
./check-kernel-config kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig
[...lots of red and green lines...]
Config file checked, found 288 errors that I did not fix.
I ran it again with the -w option, and it reportedly fixed 287 errors. Weird,
does that mean that an error was still left? I ran the tool again (without
-w), and it reported 2 errors. Ran it once more in write mode, and if fixed
them. So, one might need to run it twice.
Next, added the line
BOARD_KERNEL_CMDLINE += console=tty0
in device/xiaomi/violet/BoardConfig.mk. One more thing that needs to be done
before starting the build is fixing the mount
points,
so I opened device/xiaomi/violet/rootdir/etc/fstab.qcom and changed the type
of the userdata partition from f2fs to ext4. There were no lines with the
context option, so that was the only change I needed to do.
At this point, while browsing throught the documentation, I found a link to
this page which
contains some notes on Halium 9 porting, which are substantially different from
the official porting guide in halium.org (which I was already told in Telegram
to be obsolete in several points).
So, following the instructions from this new link I ran
hybris-patches/apply-patches.sh --mb
which completed successfully.
Then, continuing following the points from this page, I edited device/xiaomi/violet/lineage_violet.mk, commented out the lines
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base_telephony.mk)
# ...
$(call inherit-product, vendor/lineage/config/common_full_phone.mk)
and replaced the first one with a similar line pointing to halium.mk. For the
record, a find revealed that the SRC_TARGET_DIR variable in my case was
build/make/target/. It contained also the halium.mk file, which was created
by the hybris patches before. As for removing the Java dependencies, I cound't
find any modules similar to those listed in this
commit
in any of the makefiles in my source tree, so I just started the build:
source build/envsetup.sh && breakfast violet
make halium-boot
This failed the first time with the compiler being killed (out of memory, most
likely), but it succeeded on the second run. There was a suspicious warning,
though:
drivers/input/touchscreen/Kconfig:1290:warning: multi-line strings not supported
And indeed my kernel/xiaomi/violet/drivers/input/touchscreen/Kconfig had this line:
source "drivers/input/touchscreen/ft8719_touch_f7b/Kconfig
(notice the unterminated string quote). I don't know if this had any impact on
the build, but just to be on the safe side I added the missing quote and
rebuilt.
Building the system image
Running
make systemimage
failed pretty soon:
ninja: error: '/home/mardy/projects/port/halium/out/soong/host/linux-x86/framework/turbine.jar', needed by '/home/mardy/projects/port/halium/out/soong/.intermediates/libcore/core-oj/android_common/turbine/core-oj.jar', missing and no known rule to make it
The error is due to all the Java-related stuff that I should have disabled but
couldn't find. So, I tried to have a look at the changes made on another
xiaomi
device
(lavender, the Redmi note 7, which might not be that different, I thought)
and started editing device/xiaomi/violet/device.mk and removing a couple of
Android packages. Eventually the build proceeded, just to stop at a python
error:
File "build/make/tools/check_radio_versions.py", line 56
print "*** Error opening \"%s.sha1\"; can't verify %s" % (fn, key)
^
SyntaxError: invalid syntax
Yes, it's the python3 vs python2 issue, since in my system python is python
version 3. In order to fix it, I created a virtual environment:
virtualenv --python 2.7 ../python27 # adjust the path to your prefs
source ../python27/bin/activate
Remember that the second line must be run every time you'll need to setup the
Halium build environment (that is, every time you run breakfast).
The build then proceeded for several minutes, until it failed due to some unresolved symbols:
prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/aarch64-linux-android/bin/ld.gold: error: /home/mardy/projects/port/halium/out/target/product/violet/obj/STATIC_LIBRARIES/lib_driver_cmd_qcwcn_intermediates/lib_driver_cmd_qcwcn.a: member at 7694 is not an ELF object
external/wpa_supplicant_8/hostapd/src/drivers/driver_nl80211.c:7936: error: undefined reference to 'wpa_driver_set_p2p_ps'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_set_ap_wps_p2p_ie'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_get_p2p_noa'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_set_p2p_noa'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_nl80211_driver_cmd'
As people told me in the Telegram channel, this driver is not used since "our
wpa_supplicant talks to kernel directly". OK, so I simply disabled the
driver, copying again from the lavender Halium
changes:
commented out the BOARD_WLAN_DEVICE := qcwcn line (and all lines referring
this variable) from device/xiaomi/violet/BoardConfig.mk and ran make
systemimage again. This time, surprisingly, it all worked.
Try it out
I first tried to flash the kernel only. I rebooted into fastboot, and on my PC ran this:
cout
fastboot flash boot halium-boot.img
I then rebooted my phone, but after showing the boot logo for a few seconds it
would jump to the fastboot screen. Indeed, flashing the previous kernel would
restore the normal boot, so there had to be something wrong with my own kernel.
While looking at what the problem could be, I noticed that in the lavender
port the author did not modify the lineageos kernel config file in place, but
instead created a new one and changed the BoardConfig.mk file to point to his
new copy. Since it sounded like a good idea, I did the same and created
kernel/xiaomi/violet/arch/arm64/configs/vendor/violet_halium_defconfig for
the Halium changes. And then the line in the board config file became
TARGET_KERNEL_CONFIG := vendor/violet_halium_defconfig
I then continued investigating the boot issue, and I was told that it might
have been due to an Android option, skip_initramfs, which is set by the
bootloader and causes our Halium boot to fail. The fix is to just disable this
option in the kernel, by editing init/initramfs.c and change the
skip_initramfs_param function to always set the do_skip_initramfs variable
to 0, rather than to 1. After doing this, the boot proceeded to show the
Ubuntu splash screen with the five dots being lit, but it didn't proceed from
there.
Setting up the udev rules
Even in this state, the device was detected by my host PC and these lines
appeared in the system log:
kernel: usb 1-3: new high-speed USB device number 26 using xhci_hcd
kernel: usb 1-3: New USB device found, idVendor=0fce, idProduct=7169, bcdDevice= 4.14
kernel: usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
kernel: usb 1-3: Product: Unknown
kernel: usb 1-3: Manufacturer: GNU/Linux Device
kernel: usb 1-3: SerialNumber: GNU/Linux Device on usb0 10.15.19.82
Indeed, I guess the reason I could do this without even flashing my systemimage
is because I had first flashed another UT system image from another porter. I'm
not sure if I'd had the same results with my own image. Anyway, the USB
networking was there, so I connected and ran the following commands to generate
the udev rules:
ssh [email protected]
# used 0000 as password
sudo -i
# same password again
cd /home/phablet
DEVICE=violet
cat /var/lib/lxc/android/rootfs/ueventd*.rc /vendor/ueventd*.rc \
| grep ^/dev \
| sed -e 's/^\/dev\///' \
| awk '{printf "ACTION==\"add\", KERNEL==\"%s\", OWNER=\"%s\", GROUP=\"%s\", MODE=\"%s\"\n",$1,$3,$4,$2}' \
| sed -e 's/\r//' \
>70-$DEVICE.rules
I then copied (with scp) this file to my host PC, and I moved it to
device/xiaomi/violet/ubuntu/70-violet.rules (I had to create the ubuntu
directory first). Then I edited the device/xiaomi/violet/device.mk file and
added these lines at the end:
### Ubuntu Touch ###
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/ubuntu/70-violet.rules:system/halium/lib/udev/rules.d/70-android.rules
### End Ubuntu Touch ###
It was now time to try my own system image. I rebooted my device into TWRP, I
cloned the halium-install
repository into my halium build
dir, downloaded a rootfs for
Halium9,
and ran
./halium-install/halium-install -p ut \
~/Downloads/ubuntu-touch-android9-arm64.tar.gz \
out/target/product/violet/system.img
The first time this failed because the simg2img tool was not installed. The
second time it proceeded to create the image, asked me for a password for the
phablet user (gave "0000") and pushed the image onto the device, into the
/data/ partition. I then rebooted.
My first Ubuntu Touch image
Upon reboot, the usual splash screen appeared, followed by several seconds of
black screen. It definitely didn't look right, but at least it proved that
something had been flashed. After some more seconds, to my big surprise, the
Ubuntu boot screen appeared, just with a smaller logo than how it used to be
before, which also confimed that my system image was being used — in fact, I
did not adjust the GRID_UNIT_PX variable before. Since this was an easy fix,
I chose to focus on that, rather than fix the boot issues (indeed, my device
did not move on from the Ubuntu boot screen). SSH was working.
I took the scaling.conf file from the lavender
changes,
put it in device/xiaomi/violet/ubuntu/ and added this line in the
PRODUCT_COPY_FILES in device.mk:
$(LOCAL_PATH)/ubuntu/scaling.conf:system/halium/etc/ubuntu-touch-session.d/android.conf
I initially used system/ubuntu/etc/... as the target destination for the
config file, like in the lavender commit, but this didn't work out for me. Then
I changed the path to start with system/halium/, like it's mentioned in the
ubports documentation, but it apparently had no effect either.
After a couple of days spent trying to understand why my files were not
appearing under /etc, it turned out that the device was not using my system
image at all: with halium-install I had my image installed in
/userdata/system.img, while the correct path for Halium 9 devices is
/userdata/android-rootfs.img. I was told that the option -s of
halium-install would do the trick. Instead of re-running the script, I took
the shortcut of renaming /userdata/system.img to
/userdata/android-rootfs.img and after rebooting I could see that the Ubuntu
logo was displayed at the correct size. And indeed my system image was being
used.
So I started to debug why unity8 didn't start. The logs terminated with this line:
terminate called after throwing an instance of 'std::runtime_error'
what(): org.freedesktop.DBus.Error.NoReply: Message recipient disconnected from message bus without replying
initctl: Event failed
It means, that unity8 did not handle correctly the situation where another
D-Bus service crashed while handing a call from unity8. The problem now was how
to figure out which service it was. I ran dbus-monitor and restarted unity8
(initctl start unity8), then examined the dbus logs; I saw the point where
unity8 got disconnected from the bus, but before that point I didn't find any
failed D-Bus calls. So it had to be the system bus. I did exactly the same
steps, just this time after running dbus-monitor --system as root, I found
the place where unity8 got disconnected, and found this D-bus error shortly
before that:
method call time=1605676421.968667 sender=:1.306 -> destination=com.ubuntu.biometryd.Service serial=3 path=/default_device; interface=com.ubuntu.biometryd.Device; member=Identifier
method return time=1605676421.970222 sender=:1.283 -> destination=:1.306 serial=4 reply_serial=3
object path "/default_device/identifier"
...
method call time=1605676421.974218 sender=:1.283 -> destination=org.freedesktop.DBus serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionAppArmorSecurityContext
string ":1.306"
error time=1605676421.974278 sender=org.freedesktop.DBus -> destination=:1.283 error_name=org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown reply_serial=6
string "Could not determine security context for ':1.306'"
...
signal time=1605676421.989074 sender=org.freedesktop.DBus -> destination=:1.283 serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
string "com.ubuntu.biometryd.Service"
...
error time=1605676421.989302 sender=org.freedesktop.DBus -> destination=:1.306 error_name=org.freedesktop.DBus.Error.NoReply reply_serial=4
string "Message recipient disconnected from message bus without replying"
So, it looks like unity8 (:1.306) made a request to biometryd, who asked the
D-Bus daemon what was the AppArmor label of the caller, but since I didn't
backport the D-Bus mediation patches for AppArmor, the label could not be
resolved. biometryd decided to crash instead of properly handling the error,
and so did unity8.
So I backported the AppArmor patches. I took them from the Canonical kernel
repo,
but they did not apply cleanly because they are meant to be applied on top of a
pristine 4.14 branch, whereas the Android kernel had already some AppArmor
security fixes backported from later releases. So I set and quickly inspected
the contents of each patch, and found out that a couple of them had already
been applied, and the last patch had to be applied as the first (yeah, it's
hard to explain, but it all depends on other patches that Android has
backported from newer kernels). Anyway, after rebuilding the kernel and
reflashing it, my phone could finally boot to unity8!
Conclusion (of the first episode)
The actual porting, as I've been told, starts here. What has been documented
here are only the very first steps of the bring-up; what awaits me now is to
make all the hardware subsystems work properly, and this, according to people
more experienced in porting, is the harder part.
So far, very few things work, to the point that it's faster to me to list the
things that do work; it's safe to assume that all what is not listed here is
not working:
Mir, with graphics and input: Unity8 starts and is usable
Camera: can take photos; video recording start but an error appears when the
stop button is pressed
Flashlight
Fingerprint reader: surprisingly, this worked out of the box
Screen brightness (though it can be changed only manually)
For all the rest, please keep an eye on this blog: I'll write, when I make some
progress! [Less]
|
Posted
over 2 years
ago
by
Alberto Mardegan
In case you have a sense of deja-vu when reading this post, it's because
indeed this is not the first time I try porting a device to Ubuntu Touch. The
previous
attempt,
however, was with another phone model (and manufacturer), and did not have a
... [More]
happy ending. This time it went better, although the real ending is still far
away; but at least I have something to celebrate.
The phone
I made myself a Christmas present and bought a Xiaomi Redmi Note 7 Pro, a
dual-SIM phone from 2019 with 6GB of RAM and 128GB of flash storage. To be
totally honest, I bought it by mistake: the phone I really wanted to buy is the
Redmi Note 7 (without the "Pro"), because it's a modern phone that is working
reasonable well with Ubuntu Touch. The online shop where I bought it from let
me choose some options, including the RAM size, so I chose the maximum
available (6GB) without being aware that this would mean that I would be buying
the "Pro" device — the shop did not alter the item name, so I couldn't really
know. Unfortunately, the two versions are two rather different beasts, powered
by different SoC; both are produced by Qualcomm, so they are not that
different, but it's enough to make the installation of Ubuntu Touch impossible.
But between the choice of retuning the phone to the shop and begin a new
porting adventure, I stood firm and went for the latter. Hopefully I won't
regret it (if everything goes bad, I can still use it with LineageOS, which
runs perfectly on it).
Moreover, there already exist a port of Ubuntu Touch for this phone, which
actually works reasonably well (I tried it briefly, and many things were
working), but the author claims to be a novice and indeed did not follow the
best git practices when working on the source code, so it's hard to understand
what was changed and why. But if you are looking for a quick way to get Ubuntu
Touch working on this phone, you are welcome to have a look at this Telegram
channel.
What follows are the raw notes of my attempts. They are here so that search
engines can index the error messages and the various logs, and hopefully help
someone hitting similar errors on other devices to find his way out.
Getting Halium and the device source code
Installed the dependencies like in the first step. repo was not found in the
Ubuntu 20.04 archives, but I had it installed anyway due to my work on a Yocto
device.
Since my device has Android 9 on it, I went for Halium 9:
repo init -u git://github.com/Halium/android.git -b halium-9.0 --depth=1
repo sync -c -j 16
The official LineageOS repository for the Xiaomi Redmi Note 7 Pro is
android_device_xiaomi_violet,
but the page with the official build
has been taken down (some DMCA violation, if you believe the
forums)
and no development has been happening since last year. A more active forum
thread
uses another repository which seems to be receiving more frequent updates, so I
chose to base my port on that.
I actually tested that LineageOS image on my phone, and verified that all the
hardware was working properly.
Initially, I created forks of the relevant repository under my own gitlab
account, but then I though (especially looking at the Note 7 port)
that creating a group just for this port would make people's life easier,
because they wouldn't need to navigate through my 1000 personal projects
to find what is relevant for this port. So, I created these forks:
gitlab.com/ubuntu-touch-xiaomi-violet/android_device_xiaomi_violet
gitlab.com/ubuntu-touch-xiaomi-violet/android_kernel_xiaomi_violet
gitlab.com/ubuntu-touch-xiaomi-violet/android_vendor_xiaomi_violet
Next, created the halium/devices/manifests/xiaomi_violet.xml file with this content:
name="ubuntu-touch-xiaomi-violet"
fetch="https://gitlab.com/ubuntu-touch-xiaomi-violet"
revision="halium-9.0"/>
path="device/xiaomi/violet"
name="android_device_xiaomi_violet"
remote="ubuntu-touch-xiaomi-violet" />
path="kernel/xiaomi/violet"
name="android_kernel_xiaomi_violet"
remote="ubuntu-touch-xiaomi-violet" />
path="vendor/xiaomi/violet"
name="android_vendor_xiaomi_violet"
remote="ubuntu-touch-xiaomi-violet" />
Fetching all the sources mentioned in the manifest:
./halium/devices/setup violet
Full output:
*****************************************
I: Configuring for device xiaomi_violet
*****************************************
Fetching projects: 100% (393/393), done.
hardware/qcom/audio-caf/apq8084: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8916: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8952: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8960: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8974: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8994: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8996: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8998: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/sdm845: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/sm8150: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio/default: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/display: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/apq8084: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8916: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8952: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8960: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8974: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8994: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8996: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8998: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/sdm845: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/sm8150: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/media: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/apq8084: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8916: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8952: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8960: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8974: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8994: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8996: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8998: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/sdm845: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/sm8150: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/ril: Shared project LineageOS/android_hardware_ril found, disabling pruning.
hardware/ril-caf: Shared project LineageOS/android_hardware_ril found, disabling pruning.
hardware/qcom/wlan: Shared project LineageOS/android_hardware_qcom_wlan found, disabling pruning.
hardware/qcom/wlan-caf: Shared project LineageOS/android_hardware_qcom_wlan found, disabling pruning.
hardware/qcom/bt: Shared project LineageOS/android_hardware_qcom_bt found, disabling pruning.
hardware/qcom/bt-caf: Shared project LineageOS/android_hardware_qcom_bt found, disabling pruning.
Updating files: 100% (67031/67031), done.nel/testsUpdating files: 36% (24663/67031)
lineage/scripts/: discarding 1 commits
Updating files: 100% (1406/1406), done.ineageOS/android_vendor_qcom_opensource_thermal-engineUpdating files: 47% (666/1406)
Checking out projects: 100% (392/392), done.
*******************************************
I: Refreshing device vendor repository: device/xiaomi/violet
I: Processing proprietary blob file: device/xiaomi/violet/./proprietary-files.txt
I: Processing fstab file: device/xiaomi/violet/./rootdir/etc/fstab.qcom
I: Removing components relying on SettingsLib from: device/xiaomi/violet
*******************************************
Starting the build
Setting up the environment:
$ source build/envsetup.sh
including device/xiaomi/violet/vendorsetup.sh
including vendor/lineage/vendorsetup.sh
$
Running the breakfast command:
$ breakfast violet
including vendor/lineage/vendorsetup.sh
Trying dependencies-only mode on a non-existing device tree?
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
LINEAGE_VERSION=16.0-20210109-UNOFFICIAL-violet
TARGET_PRODUCT=lineage_violet
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo300
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv8-a
TARGET_2ND_CPU_VARIANT=cortex-a75
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.4.0-58-generic-x86_64-Ubuntu-20.04.1-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=PQ3A.190801.002
OUT_DIR=/home/mardy/projects/port/halium/out
PRODUCT_SOONG_NAMESPACES= hardware/qcom/audio-caf/sm8150 hardware/qcom/display-caf/sm8150 hardware/qcom/media-caf/sm8150
============================================
Building the kernel
The configuration needs to be adapted for Halium. Locating the kernel config:
$ grep "TARGET_KERNEL_CONFIG" device/xiaomi/violet/BoardConfig.mk
TARGET_KERNEL_CONFIG := vendor/violet-perf_defconfig
$
Getting the Mer checker tool and running it:
git clone https://github.com/mer-hybris/mer-kernel-check
cd mer-kernel-check
./mer_verify_kernel_config ../kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig
Prints lots of warnings, starting with:
WARNING: kernel version missing, some reports maybe misleading
To help the tool, we need to let him know the kernel version. It can be seen at
the beginning of the kernel Makefile, located in
../kernel/xiaomi/violet/Makefile; in my case it was
VERSION = 4
PATCHLEVEL = 14
SUBLEVEL = 83
EXTRAVERSION =
So I edited the configuration file
../kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig and
added this line at the beginning:
# Version 4.14.83
then ran the checker tool again. This time the output was a long list of kernel
options that needed to be fixed, but as I went asking for some explanation in
the Telegram channel for Ubuntu Touch porters, I was told that I could/should
skip this test and instead use the check-kernel-config tool from
Halium.
I downloaded it, made it executable (chmod +x check-kernel-config) and ran
it:
./check-kernel-config kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig
[...lots of red and green lines...]
Config file checked, found 288 errors that I did not fix.
I ran it again with the -w option, and it reportedly fixed 287 errors. Weird,
does that mean that an error was still left? I ran the tool again (without
-w), and it reported 2 errors. Ran it once more in write mode, and if fixed
them. So, one might need to run it twice.
Next, added the line
BOARD_KERNEL_CMDLINE += console=tty0
in device/xiaomi/violet/BoardConfig.mk. One more thing that needs to be done
before starting the build is fixing the mount
points,
so I opened device/xiaomi/violet/rootdir/etc/fstab.qcom and changed the type
of the userdata partition from f2fs to ext4. There were no lines with the
context option, so that was the only change I needed to do.
At this point, while browsing throught the documentation, I found a link to
this page which
contains some notes on Halium 9 porting, which are substantially different from
the official porting guide in halium.org (which I was already told in Telegram
to be obsolete in several points).
So, following the instructions from this new link I ran
hybris-patches/apply-patches.sh --mb
which completed successfully.
Then, continuing following the points from this page, I edited device/xiaomi/violet/lineage_violet.mk, commented out the lines
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base_telephony.mk)
# ...
$(call inherit-product, vendor/lineage/config/common_full_phone.mk)
and replaced the first one with a similar line pointing to halium.mk. For the
record, a find revealed that the SRC_TARGET_DIR variable in my case was
build/make/target/. It contained also the halium.mk file, which was created
by the hybris patches before. As for removing the Java dependencies, I cound't
find any modules similar to those listed in this
commit
in any of the makefiles in my source tree, so I just started the build:
source build/envsetup.sh && breakfast violet
make halium-boot
This failed the first time with the compiler being killed (out of memory, most
likely), but it succeeded on the second run. There was a suspicious warning,
though:
drivers/input/touchscreen/Kconfig:1290:warning: multi-line strings not supported
And indeed my kernel/xiaomi/violet/drivers/input/touchscreen/Kconfig had this line:
source "drivers/input/touchscreen/ft8719_touch_f7b/Kconfig
(notice the unterminated string quote). I don't know if this had any impact on
the build, but just to be on the safe side I added the missing quote and
rebuilt.
Building the system image
Running
make systemimage
failed pretty soon:
ninja: error: '/home/mardy/projects/port/halium/out/soong/host/linux-x86/framework/turbine.jar', needed by '/home/mardy/projects/port/halium/out/soong/.intermediates/libcore/core-oj/android_common/turbine/core-oj.jar', missing and no known rule to make it
The error is due to all the Java-related stuff that I should have disabled but
couldn't find. So, I tried to have a look at the changes made on another
xiaomi
device
(lavender, the Redmi note 7, which might not be that different, I thought)
and started editing device/xiaomi/violet/device.mk and removing a couple of
Android packages. Eventually the build proceeded, just to stop at a python
error:
File "build/make/tools/check_radio_versions.py", line 56
print "*** Error opening \"%s.sha1\"; can't verify %s" % (fn, key)
^
SyntaxError: invalid syntax
Yes, it's the python3 vs python2 issue, since in my system python is python
version 3. In order to fix it, I created a virtual environment:
virtualenv --python 2.7 ../python27 # adjust the path to your prefs
source ../python27/bin/activate
Remember that the second line must be run every time you'll need to setup the
Halium build environment (that is, every time you run breakfast).
The build then proceeded for several minutes, until it failed due to some unresolved symbols:
prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/aarch64-linux-android/bin/ld.gold: error: /home/mardy/projects/port/halium/out/target/product/violet/obj/STATIC_LIBRARIES/lib_driver_cmd_qcwcn_intermediates/lib_driver_cmd_qcwcn.a: member at 7694 is not an ELF object
external/wpa_supplicant_8/hostapd/src/drivers/driver_nl80211.c:7936: error: undefined reference to 'wpa_driver_set_p2p_ps'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_set_ap_wps_p2p_ie'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_get_p2p_noa'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_set_p2p_noa'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_nl80211_driver_cmd'
As people told me in the Telegram channel, this driver is not used since "our
wpa_supplicant talks to kernel directly". OK, so I simply disabled the
driver, copying again from the lavender Halium
changes:
commented out the BOARD_WLAN_DEVICE := qcwcn line (and all lines referring
this variable) from device/xiaomi/violet/BoardConfig.mk and ran make
systemimage again. This time, surprisingly, it all worked.
Try it out
I first tried to flash the kernel only. I rebooted into fastboot, and on my PC ran this:
cout
fastboot flash boot halium-boot.img
I then rebooted my phone, but after showing the boot logo for a few seconds it
would jump to the fastboot screen. Indeed, flashing the previous kernel would
restore the normal boot, so there had to be something wrong with my own kernel.
While looking at what the problem could be, I noticed that in the lavender
port the author did not modify the lineageos kernel config file in place, but
instead created a new one and changed the BoardConfig.mk file to point to his
new copy. Since it sounded like a good idea, I did the same and created
kernel/xiaomi/violet/arch/arm64/configs/vendor/violet_halium_defconfig for
the Halium changes. And then the line in the board config file became
TARGET_KERNEL_CONFIG := vendor/violet_halium_defconfig
I then continued investigating the boot issue, and I was told that it might
have been due to an Android option, skip_initramfs, which is set by the
bootloader and causes our Halium boot to fail. The fix is to just disable this
option in the kernel, by editing init/initramfs.c and change the
skip_initramfs_param function to always set the do_skip_initramfs variable
to 0, rather than to 1. After doing this, the boot proceeded to show the
Ubuntu splash screen with the five dots being lit, but it didn't proceed from
there.
Setting up the udev rules
Even in this state, the device was detected by my host PC and these lines
appeared in the system log:
kernel: usb 1-3: new high-speed USB device number 26 using xhci_hcd
kernel: usb 1-3: New USB device found, idVendor=0fce, idProduct=7169, bcdDevice= 4.14
kernel: usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
kernel: usb 1-3: Product: Unknown
kernel: usb 1-3: Manufacturer: GNU/Linux Device
kernel: usb 1-3: SerialNumber: GNU/Linux Device on usb0 10.15.19.82
Indeed, I guess the reason I could do this without even flashing my systemimage
is because I had first flashed another UT system image from another porter. I'm
not sure if I'd had the same results with my own image. Anyway, the USB
networking was there, so I connected and ran the following commands to generate
the udev rules:
ssh [email protected]
# used 0000 as password
sudo -i
# same password again
cd /home/phablet
DEVICE=violet
cat /var/lib/lxc/android/rootfs/ueventd*.rc /vendor/ueventd*.rc \
| grep ^/dev \
| sed -e 's/^\/dev\///' \
| awk '{printf "ACTION==\"add\", KERNEL==\"%s\", OWNER=\"%s\", GROUP=\"%s\", MODE=\"%s\"\n",$1,$3,$4,$2}' \
| sed -e 's/\r//' \
>70-$DEVICE.rules
I then copied (with scp) this file to my host PC, and I moved it to
device/xiaomi/violet/ubuntu/70-violet.rules (I had to create the ubuntu
directory first). Then I edited the device/xiaomi/violet/device.mk file and
added these lines at the end:
### Ubuntu Touch ###
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/ubuntu/70-violet.rules:system/halium/lib/udev/rules.d/70-android.rules
### End Ubuntu Touch ###
It was now time to try my own system image. I rebooted my device into TWRP, I
cloned the halium-install
repository into my halium build
dir, downloaded a rootfs for
Halium9,
and ran
./halium-install/halium-install -p ut \
~/Downloads/ubuntu-touch-android9-arm64.tar.gz \
out/target/product/violet/system.img
The first time this failed because the simg2img tool was not installed. The
second time it proceeded to create the image, asked me for a password for the
phablet user (gave "0000") and pushed the image onto the device, into the
/data/ partition. I then rebooted.
My first Ubuntu Touch image
Upon reboot, the usual splash screen appeared, followed by several seconds of
black screen. It definitely didn't look right, but at least it proved that
something had been flashed. After some more seconds, to my big surprise, the
Ubuntu boot screen appeared, just with a smaller logo than how it used to be
before, which also confimed that my system image was being used — in fact, I
did not adjust the GRID_UNIT_PX variable before. Since this was an easy fix,
I chose to focus on that, rather than fix the boot issues (indeed, my device
did not move on from the Ubuntu boot screen). SSH was working.
I took the scaling.conf file from the lavender
changes,
put it in device/xiaomi/violet/ubuntu/ and added this line in the
PRODUCT_COPY_FILES in device.mk:
$(LOCAL_PATH)/ubuntu/scaling.conf:system/halium/etc/ubuntu-touch-session.d/android.conf
I initially used system/ubuntu/etc/... as the target destination for the
config file, like in the lavender commit, but this didn't work out for me. Then
I changed the path to start with system/halium/, like it's mentioned in the
ubports documentation, but it apparently had no effect either.
After a couple of days spent trying to understand why my files were not
appearing under /etc, it turned out that the device was not using my system
image at all: with halium-install I had my image installed in
/userdata/system.img, while the correct path for Halium 9 devices is
/userdata/android-rootfs.img. I was told that the option -s of
halium-install would do the trick. Instead of re-running the script, I took
the shortcut of renaming /userdata/system.img to
/userdata/android-rootfs.img and after rebooting I could see that the Ubuntu
logo was displayed at the correct size. And indeed my system image was being
used.
So I started to debug why unity8 didn't start. The logs terminated with this line:
terminate called after throwing an instance of 'std::runtime_error'
what(): org.freedesktop.DBus.Error.NoReply: Message recipient disconnected from message bus without replying
initctl: Event failed
It means, that unity8 did not handle correctly the situation where another
D-Bus service crashed while handing a call from unity8. The problem now was how
to figure out which service it was. I ran dbus-monitor and restarted unity8
(initctl start unity8), then examined the dbus logs; I saw the point where
unity8 got disconnected from the bus, but before that point I didn't find any
failed D-Bus calls. So it had to be the system bus. I did exactly the same
steps, just this time after running dbus-monitor --system as root, I found
the place where unity8 got disconnected, and found this D-bus error shortly
before that:
method call time=1605676421.968667 sender=:1.306 -> destination=com.ubuntu.biometryd.Service serial=3 path=/default_device; interface=com.ubuntu.biometryd.Device; member=Identifier
method return time=1605676421.970222 sender=:1.283 -> destination=:1.306 serial=4 reply_serial=3
object path "/default_device/identifier"
...
method call time=1605676421.974218 sender=:1.283 -> destination=org.freedesktop.DBus serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionAppArmorSecurityContext
string ":1.306"
error time=1605676421.974278 sender=org.freedesktop.DBus -> destination=:1.283 error_name=org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown reply_serial=6
string "Could not determine security context for ':1.306'"
...
signal time=1605676421.989074 sender=org.freedesktop.DBus -> destination=:1.283 serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
string "com.ubuntu.biometryd.Service"
...
error time=1605676421.989302 sender=org.freedesktop.DBus -> destination=:1.306 error_name=org.freedesktop.DBus.Error.NoReply reply_serial=4
string "Message recipient disconnected from message bus without replying"
So, it looks like unity8 (:1.306) made a request to biometryd, who asked the
D-Bus daemon what was the AppArmor label of the caller, but since I didn't
backport the D-Bus mediation patches for AppArmor, the label could not be
resolved. biometryd decided to crash instead of properly handling the error,
and so did unity8.
So I backported the AppArmor patches. I took them from the Canonical kernel
repo,
but they did not apply cleanly because they are meant to be applied on top of a
pristine 4.14 branch, whereas the Android kernel had already some AppArmor
security fixes backported from later releases. So I set and quickly inspected
the contents of each patch, and found out that a couple of them had already
been applied, and the last patch had to be applied as the first (yeah, it's
hard to explain, but it all depends on other patches that Android has
backported from newer kernels). Anyway, after rebuilding the kernel and
reflashing it, my phone could finally boot to unity8!
Conclusion (of the first episode)
The actual porting, as I've been told, starts here. What has been documented
here are only the very first steps of the bring-up; what awaits me now is to
make all the hardware subsystems work properly, and this, according to people
more experienced in porting, is the harder part.
So far, very few things work, to the point that it's faster to me to list the
things that do work; it's safe to assume that all what is not listed here is
not working:
Mir, with graphics and input: Unity8 starts and is usable
Camera: can take photos; video recording start but an error appears when the
stop button is pressed
Flashlight
Fingerprint reader: surprisingly, this worked out of the box
Screen brightness (though it can be changed only manually)
For all the rest, please keep an eye on this blog: I'll write, when I make some
progress!
0 0 [Less]
|
Posted
over 2 years
ago
by
Philip Van Hoof
Qt published its New_Features in Qt 6.0.
Some noteworthy items in their list:
QPromise allows setting values, progress and exceptions to QFuture
QFuture supports attaching continuations
I like to think I had my pirate-hook in it at least a
... [More]
little bit with QTBUG-61928.
I need to print this out and put it above my bed:
Thiago Macieira added a comment – 13 Jul ’17 03:51
You’re right
Philip Van Hoof added a comment – 13 Jul ’17 07:32
Damn, and I was worried the entire morning that I had been ranting again.
Thiago Macieira added a comment – 13 Jul ’17 16:06
oh, you were ranting. Doesn’t mean you’re wrong.
Thanks for prioritizing this Thiago.
0 0 [Less]
|
Posted
over 2 years
ago
by
Philip Van Hoof
Qt published its New_Features in Qt 6.0.
Some noteworthy items in their list:
QPromise allows setting values, progress and exceptions to QFuture
QFuture supports attaching continuations
I like to think I had a my pirate-hook in it at least a
... [More]
little bit with QTBUG-61928.
I need to print this out and put it above my bed:
Thiago Macieira added a comment – 13 Jul ’17 03:51
You’re right
Philip Van Hoof added a comment – 13 Jul ’17 07:32
Damn, and I was worried the entire morning that I had been ranting again.
Thiago Macieira added a comment – 13 Jul ’17 16:06
oh, you were ranting. Doesn’t mean you’re wrong.
Thanks for prioritizing this Thiago.
0 0 [Less]
|
Posted
over 2 years
ago
by
Pavel Rojtberg
This question often pops up, when you need a random direction vector to place things in 3D or you want to do a particle simulation.
We recall that a 3D unit-sphere (and hence a direction) is parametrized only by two variables; elevation \theta
... [More]
\in [0; \pi] and azimuth \varphi \in [0; 2\,\pi] which can be converted to Cartesian coordinates as
\begin{aligned} x &= \sin\theta \, \cos\varphi \\ y &= \sin\theta \, \sin\varphi \\ z &= \cos\theta \end{aligned}
If one takes the easy way and uniformly samples this parametrization in numpy like
phi = np.random.rand() * 2 * np.pi
theta = np.random.rand() * np.pi
One (i.e. you as you are reading this) ends with something like this:
uniform: spherical coordinates
biased: 3D projection to Cartesian coordinates
While the 2D surface of polar coordinates uniformly sampled (left), we observe a bias of sampling density towards the poles when projecting to the Cartesian coordinates (right).The issue is that the cos mapping of the elevation has an uneven step size in Cartesian space, as you can easily verify: cos^{'}(x) = sin(x).
The solution is to simply sample the elevation in the Cartesian space instead of the spherical space – i.e. sampling z \in [-1; 1]. From that we can get back to our elevation as \theta = \arccos z:
z = 1 - np.random.rand() * 2 # convert rand() range 0..1 to -1..1
theta = np.arccos(z)
As desired, this compensates the spherical coordinates such that we end up with uniform sampling in the Cartesian space:
compensated spherical coordinates
uniform: 3D Cartesian coordinates
Custom opening angle
If you want to further restrict the opening angle instead of sampling the full sphere you can also easily extend the above. Here, you must re-map the cos values from [1; -1] to [0; 2] as
cart_range = -np.cos(angle) + 1 # maximal range in cartesian coords
z = 1 - np.random.rand() * cart_range
theta = np.arccos(z)
Optimized computation
If you do not actually need the parameters \theta, \varphi, you can spare some trigonometric functions by using \sin \theta = \sqrt { 1 - z^2} as
\begin{aligned} x &= \sqrt { 1 - z^2} \, \cos\varphi \\ y &= \sqrt { 1 - z^2} \, \sin\varphi \end{aligned}
0 0 [Less]
|
Posted
over 2 years
ago
by
Pavel Rojtberg
This question often pops up, when you need a random direction vector to place things in 3D or you want to do a particle simulation.
We recall that a 3D unit-sphere (and hence a direction) is parametrized only by two variables; elevation \theta
... [More]
\in [0; \pi] and azimuth \varphi \in [0; 2\,\pi] which can be converted to Cartesian coordinates as
\begin{aligned} x &= \sin\theta \, \cos\varphi \\ y &= \sin\theta \, \sin\varphi \\ z &= \cos\theta \end{aligned}
If one takes the easy way and uniformly samples this parametrization in numpy like
phi = np.random.rand() * 2 * np.pi
theta = np.random.rand() * np.pi
One (i.e. you as you are reading this) ends with something like this:
uniform: spherical coordinates
biased: 3D projection to Cartesian coordinates
While the 2D surface of polar coordinates uniformly sampled (left), we observe a bias of sampling density towards the poles when projecting to the Cartesian coordinates (right).The issue is that the cos mapping of the elevation has an uneven step size in Cartesian space, as you can easily verify: cos^{'}(x) = sin(x).
The solution is to simply sample the elevation in the Cartesian space instead of the spherical space – i.e. sampling z \in [-1; 1]. From that we can get back to our elevation as \theta = \arccos z:
z = 1 - np.random.rand() * 2 # convert rand() range 0..1 to -1..1
theta = np.arccos(z)
As desired, this compensates the spherical coordinates such that we end up with uniform sampling in the Cartesian space:
compensated spherical coordinates
uniform: 3D Cartesian coordinates
Custom opening angle
If you want to further restrict the opening angle instead of sampling the full sphere you can also easily extend the above. Here, you must re-map the cos values from [1; -1] to [0; 2] as
cart_range = -np.cos(angle) + 1 # maximal range in cartesian coords
z = 1 - np.random.rand() * cart_range
theta = np.arccos(z)
Optimized computation
If you do not actually need the parameters \theta, \varphi, you can spare some trigonometric functions by using \sin \theta = \sqrt { 1 - z^2} as
\begin{aligned} x &= \sqrt { 1 - z^2} \, \cos\varphi \\ y &= \sqrt { 1 - z^2} \, \sin\varphi \end{aligned}
0 0 [Less]
|
Posted
over 2 years
ago
by
Pavel Rojtberg
This question often pops up, when you need a random direction vector to place things in 3D or you want to do a particle simulation.
We recall that a 3D unit-sphere (and hence a direction) is parametrized only by two variables; elevation \theta
... [More]
\in [0; \pi] and azimuth \varphi \in [0; 2\,\pi] which can be converted to Cartesian coordinates as
\begin{aligned} x &= \sin\theta \, \cos\varphi \\ y &= \sin\theta \, \sin\varphi \\ z &= \cos\theta \end{aligned}
If one takes the easy way and uniformly samples this parametrization like
phi = np.random.rand() * 2 * np.pi
theta = np.random.rand() * np.pi
One (i.e. you as you are reading this) ends with something like this:
uniform: spherical coordinates
biased: 3D projection to Cartesian coordinates
While the 2D surface of polar coordinates uniformly sampled (left), we observe a bias of sampling density towards the poles when projecting to the Cartesian coordinates (right).The issue is that the cos mapping of the elevation has an uneven step size in Cartesian space, as you can easily verify: cos^{'}(x) = sin(x).
The solution is to simply sample the elevation in the Cartesian space instead of the spherical space – i.e. sampling z \in [-1; 1]. From that we can get back to our elevation as \theta = \arccos z:
theta = np.arccos(1 - np.random.rand() * 2) # convert rand() range 0..1 to -1..1
As desired, this compensates the spherical coordinates such that we end up with uniform sampling in the Cartesian space:
compensated spherical coordinates
uniform: 3D Cartesian coordinates
If you want to further restrict the opening angle instead of sampling the full sphere you can also easily extend the above. Here, you must re-map the cos values from [1; -1] to [0; 2] as
cart_range = -np.cos(angle) + 1 # maximal range in cartesian coords
theta = np.arccos(1 - np.random.rand() * cart_range)
0 0 [Less]
|