2016年11月4日 星期五

1st step for snappy


1st step for snappy
以下是在下用有限的時間了解的淺見,有錯 .... 就算了~
snappy 是Canonical 最近全力發展的一個新品牌,其整個 ecosystem 包含了 snap, snapd, all snaps 因為一些都還在發展之中,這些名字都有可能再變 (之前 snappy 1.0 到 snappy 2.0 就發生過),也因為是新的品牌,常常 google 在找的時後會找到一些沒關係的東酉或是舊的設計架構 (snappy 1.0)
所以,最好每次都比較一下 snapd 版本或是文章的時間 (可能一星期就不太一樣)
整個品牌個人感覺是包含了兩大部份:
universal snap
由snap, snapd, snapcraft 組成,目地是要取代現行的 deb, rpm 等各家不同的 package format ,而用統一 format 可以裝在所有 linux base distribution 上。
如何作到?
snap
  • 新的 package format,為 squashfs image,裡面包了差不多所有執行程式時需的東西 ex. share libs
  • 執行程式時透過 snapd 準備一個臨時 rootfs ,並將需要的 folders bind mount 進去,最後 chroot 進去執行。
  • 以此達成 confinement 及 decouple dependency
  • 還是有一些 interface 可以讓 snap 之間分享資源
  • 但 size 會增加, 其目標 device 為單一或少功能的 IoT ,所以預期空間足夠使用。
  • non-official hardware requirement
snapcraft
  • 一個打包 snap 的工具,執行時可以 parse yaml file 抓取需要的 source code 及 build dependency 然後在獨立的 chroot 環境中編譯。
  • snapcraft.io
snapd
  • 一個 daemon 提供所有執行 snap 所需的環境,也就是說只要有 snapd 的地方都可以執行 snap.
  • 已經發行 snapd 到眾家 distribution 的 store 中,剩下的也將慢慢完成 (連 openwrt 也在計畫當中)
all-snap
由 system-boot, writable partitions, kernel snap, core snap (也叫 os snap), 及支持的 bootloader (u-boot or grub) 組成, 目的是一開機就進入精簡過的 core snap ubuntu rootfs, 然後所有的package 都以 snap 的形式存在,適用於IoT deivce.
如何作到?
kernel snap
OS snap
  • 精簡過ubuntu rootfs, 有點像 ubuntu phone 上面的 ubuntu tarball.
bootloader
  • 透過環境變snap_try_kernel, snappy_core, snappy_kernel, snap_mode 等環境變數來決定要 load 那個 kernel snap 及 os snap,以達到開機失敗就載舊 image 的功能。
  • 目前有 u-boot 及 grub ,在 android 上因為 bootload 常不opensource ,所以可能會以 android recovery 來達成類似的效果。

2016年9月29日 星期四

synaptics touchpad xorg driver issue

最近看了一個 synaptics touchpad 的 issue ,就是 single touch scrolling failed in right edge,but works in bottom edge.

xorg 在開機的時後,會將所有的 driver load 進來,可以在/var/log/Xorg.0.log 看到,而 /usr/share/X11/xorg.conf.d 下面則放著針對各個 driver 的設定檔 (也可以不放就是 default), 像這次遇到的就是 50-synaptics.conf

然後從 xinput 及 移除 psmouse kernel module 的方式可以知道它的 touch pad 是走 I2C,也就是說 kernel driver 把 x, y 丟上來, xorg driver 去判斷是 edge 還是 function button 之類的。

所以再看 xorg 的 user space Synaptics driver :
 * https://cgit.freedesktop.org/xorg/driver/xf86-input-synaptics/
 * https://launchpad.net/ubuntu/+source/xserver-xorg-input-synaptics/1.8.3-1ubuntu1

透過 code 及觀查 evtest 吐出來的 x, y 可以看到兩個問題 (evtest 在 driver 之上, Xorg 之下):
 1. right edge 沒有 x 坐標丟出來
  - 這應該要看 kernel driver.
 2. user space Synaptics driver 根据的 VID:PID [0002:0007] 是 psmouse 的ID,但最後抓到的是 [06cb:78f6] 看起來像是 Synaptics i2c 的 ID.
  - driver根拒這個決定 edge width,UNKNOWN ID 短於 Synaptics ,再加上 第 1. 點,所以touch 點永遠不被判定為 edge

所以解 1 or 2 就可以解掉這個問題,或者直接在 50-synaptics.conf 上面固定 edge width 當 workaround.

另外,同事有建議試用 xinput 取代Synaptics user space driver, 有空再試吧~

reference :
 * https://wiki.archlinux.org/index.php/Touchpad_Synaptics
 * https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-input-synaptics/+bug/1627674

2016年9月23日 星期五

[Ubuntu Snappy 2] tips for tracing and debugging (keep updating)

因為 snappy 不是用 apt 套件管理所以無法簡單的安裝 debian package ,這樣 debug 有點麻煩,然後其實 OS snap 就是 Ubuntu rootfs 也就是一堆 debian package 的集合,那我想知道其中幾個 package version 怎麼辨? 在 beta channel 中有一個 classic snap package,它透過 chroot 的方式再加上 apt package 讓使用者可以使用 apt commands。

class package 是將 writable partition 中的 OS snap copy 一份到
/var/snap/classic/common/classic 中,然後 bind mount host 一些 partition 進去後,chroot 進去,在裡面 就可以用 dpkg -l 取得所以 OS snap 中的 package 資訊:
https://pastebin.ubuntu.com/23220997/

[Ubuntu Snappy 2] - trace the booting process

最近新的 Ubuntu Core 16 Image release 了,這是就我知道的第一版 base on Snappy 2.x 的 Ubuntu core image (Snappy 2.x 是利用 snapd 管理套件, Snappy 1.x 沒研究), 詳情可見這封 mail :
https://lists.snapcraft.io/archives/snapcraft/2016-September/001166.html

小弟花了一點時間看一下他的 boot process 在此作一下記錄以免大腦記憶体不足被 garbage collection 清掉。

Ubuntu core image divides the storage to 2 partition: "writable" and "system-boot" 給 KVM 和給 raspberry pi 3 的 image 其 boot partition label 看起來不同,反正就是一個 boot ,一個 system.

boot partition:
  • /boot/grub/grubenv decides the kernel and core snap which will be loop mounted by grub.
  • /boot/grub/grub.cfg loop mount kernel snap to specify the position of kernel and initramfs image.

在writable partition 中的 kernel snap 中取得 kernel 及 initramfs ,在 initramfs 中 再 mount OS snap:

mount "${writable_mnt}/system-data/var/lib/snapd/snaps/${snap_core}" "$rootmnt"

這裡我覺得可以在開發時將 OS snap 轉成 ext4 image,然後 mount 成 rw ,這樣比較方便,只是 size 會從 75mb 擴增到 242mb。

然後其 initramfs 應該是來自於這裡:
最後就是進到 systemd 再把 snapd 叫起來。

2016年9月18日 星期日

Ubuntu Phone - install Ubuntu on Meizu Pro5 Android edition

最近看到 #phone-phone mailing list[1] 上面有人分享如何將 Meizu Pro5 Android Edition 刷成 Ubuntu Edition,因為手上沒有以 Android 版本出貨的 Meizu Pro5 所以無法實測其方法,但看來是可行的。

因為 Ubuntu Phone Edition 基本上是買不到了,就一定會有人想嘗試從 Android Edition 刷過去,此篇想用小弟的經驗嘗試分析在刷機的前後可能會遇到的問題,供想刷機的人作參考。

任何自行刷機的行為需自行負擔其風險,本人不保証任何保固上面的問題。

以下列出目前有出貨的手機:

  • BQ Krillin
    • 太舊了,不想討論
  • Meizu MX4 (Arale)
    • MTK solution
    • 刷 Factory images 需要用到MTK提供的 flash-tool
      • 本人經驗,不同的 SoC 對應的 flash-tool 版本可能不同,我之前用的是 v5.1452.00.100
  • BQ M10 (frieza)
    • MTK solution
      • 刷 Factory images 需要用到MTK提供的 flash-tool
        • 本人經驗,不同的 SoC 對應的 flash-tool 版本可能不同,我之前用的是 v5.1520.00.100
  • Meizu Pro5 (Turbo)
    • 2Samsung solution
      • 直接用 fastboot 刷 factory image 即可
factory images 就是每個 partition image file, 然後用工具刷進去,就可以出廠了。以上只有 Pro5 可以用 fastboot 直接刷每一個 partition,最方便而且他是最新的一支 Ubuntu phone 所以拿它來刷還滿合理。

上面的 Krillin, Arale and Turbo 是 device name,也就是在 image server 上面的 device 對應,ubuntu-device-flash 的 --device 要輸入的也就是它們。


目前來說,每支 Ubuntu Edition 的 partition size 都跟 Android Edition 不同,因為 Ubuntu 需要的 system partition(2.5G) 及 cache partition (700MB) 比較大。 為何? 因為在 recovery 中作 update 時,要拿 cache partition 來作 buffer。 那問題就來了~ 原本 Pro5 的 cache partition 只有 500mb,有點危險。 system partition Android Edition, AFAIK 原本就給 2.5G,所以沒有問題。

Cache partition 太小會怎樣? 你在 OTA 的時後, tarballs 會被放在 cache partition,然後 recovery mode 的時後拿來 update (請見 ubuntu-phone-recovery),cache 太小就無法 OTA ,聰明的看官應該已經想到應對的方式了..... 對,手動 update 可以解決這個問題,一樣請見 ubuntu-phone-recovery

BTW.... bootloader 就在 device tarball 裡面呀? 那是不是可以直接刷 bootloader 就好? 嗯.... 刷 bootloader 一不小心就變磚了,而且我也不知道 pro5 Android edition 的 bootloader partition 可不可以刷,所以... 科科

再來就是要把 partitions 一個一個刷進去,可以用 [1] 的方法,也可以用小弟的 repack-factory image tool [2] ,直接從 OTA server 上把 images 拉下來打包成 factory images ,然後用 fastboot 刷進去。

以上再次申明,因小弟沒有 Android Edition,所以只在 Ubuntu Edition 上測試過,如果有勇者嘗試了,再請分享結果吧 :)

[1] https://lists.launchpad.net/ubuntu-phone/msg22248.html
[2] https://github.com/alex-tu-cc/ubuntu_phone_tools

2016年7月10日 星期日

Ubuntu Phone - recovery

想要 hack 手機最快速的方式應該是從 recovery 下手,目前 Ubuntu phone 都有在官網上 release adb shell enabled 的 recovery image [1],可以用 fastboot 輕易燒入。

進入 recovery 後,可以借由 ubuntu-device-flash update 的動作了解其如何將 image 更新進去,了解之後要修改 image 內容就容易多了。

本文將簡介其運作,如想深入了解請自行 adb shell 進去 recovery 研究看看。

目前 phablet 6.x common tree 已將部份 recovery 需要的修改收錄進去,從 diff 可以看到有一個 system-image-upgrader 負責 OTA update 的動作,大致上整個 process 為:

 * u-d-f 將 ubuntu tarball, device tarball, custom tarball 從 system-image.ubuntu.com 上拉下來放到 device 裡 /cache/recovery 中並建立 ubuntu_command 檔。
 * system-image-upgrader 讀取 ubuntu_command 裡命令將 tarball 解開並將 放到 /system partition 裡。

如此一來,也可以在其他的 Android phone 上運用相同的方式,將 ubuntu tarball, custom tarball 塞進 /system 或是學 Nexus 4 將 system partition 用 loop mount 的方式放到 ubuntu.img。

接下來就只要煩腦 device tarball 就好了。 device tarball 裡包括了 kernel 及 Android 所需的各 partition 的 image 及一個減肥過的 android 放在 /var/lib/lxc/android/system.img (refer to [2])

Android code tree 的 Ubuntu phone patch 可以在 phablet 6.x common tree [3] 找到,另外 phablet_6.0.0_r1 是一個 fake device 用來假裝一個 Android 6.x device,這樣其他 Android 6.x device code tree 如果其 Merge base 是 AOSP 6.0.0_r1 就可以直接 merge 它取得 Ubuntu 為 Android 6.x 所作的修改。

這樣一來應該就可以 build 出 system.img 了,但是不是可以開機,還要看其廠商給的 Android code tree (BSP AOSP code tree) 是不是改了原本 AOSP 的 HAL,甚致有可能需要改到 hybris[4] 來迎合廠商的修改。

好像寫超過 recovery 的範圍了,反正 recovery 就只用來 OTA update,基本上只要recovery 的動作正常,就算其他 partition 都是空的,也可以透過 recovery 將其全都填上需要的內容。

另外官方的 ubuntu-device-flash 目前只支持三個 tarball 同时更新,但在開發階段可能只需要更新 custom tarball 或是 device tarball,覺得每次都要刷三個 tarball 有點浪費時間的話,可以手動修改 ubuntu_command 或是使用 這個小 tool [5] 去 update 單一個 tarball.

題外話:
如果想要刷回 Android edition ,通常先刷 Android 的 recovery ,再用其 recovery update 就可以了,但要小心的部份是 Android 的更新包中有時後會有 bootloader或preloader 的更新,最好把它拿掉,因為會導致 Ubuntu repartition 的設定不見。 說白了,就是把 system 及 boot partition 換掉,就可以回到 Android 了 (其他 partition 都共用)。

[1] https://wiki.ubuntu.com/Touch/Devices
[2] https://developer.ubuntu.com/en/phone/devices/porting-new-device/
[3] https://code-review.phablet.ubuntu.com/#/admin/projects/aosp/platform/manifest
[4] https://launchpad.net/~libhybris-maintainers/libhybris/+git/libhybris
[5] https://github.com/alex-tu-cc/ubuntu_phone_tools/blob/master/update_tarball.sh

Other refs:
https://wiki.ubuntu.com/Touch/MaintainingCodePhablet

2016年6月14日 星期二

Ubuntu Phone - porting - emulator

其實對 emulator 之前沒什麼研究,依official wiki 中步驟[1]抓來的 android code tree 是phablet-4.4.2_r1 [2],看來 wiki 中的 "Building from scratch" 就是抓 phablet 4.4.2_r1 來 build emulator。
如果是直接裝 ubuntu-emulator 其 dependency ubuntu-emulator-runtime.deb 就會把prebuild 的 emulator 放在下面
/usr/share/android/emulator/out/host/linux-x86/bin/emulator-x86
/usr/share/android/emulator/out/host/linux-x86/bin/emulator-arm
然後執行 "ubuntu-emulator run" 時 [2] 時再去執行相對位置的 emulator-*.

如此看來如果要把 Ubuntu emulator 升級當作一個 reference device 的話,可以拉新的 AOSP code,build 出其 emulator binary,還可以升級goldfish kernel [3] 到3.18 or 4.4.  最新的 emulator kernel 已改為 ranchu [6].

目前新的 AOSP tree 不再包含 qemu [4], 而是直接放一個 prebuilt emulator [5]所以可能需要再另外把它拉回來build。

keep updating .....
(
emulator 還不能動:
https://hackpad.com/Phablet-Ubuntu-Touch-z2FB0yq24Eq
)

[1] https://wiki.ubuntu.com/Touch/Emulator
[2] http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/wily/goget-ubuntu-touch/wily/files/head:/ubuntu-emulator/
[3] https://android.googlesource.com/kernel/goldfish.git
[4] https://android.googlesource.com/platform/external/qemu
[5] https://android.googlesource.com/platform/prebuilts/android-emulator
[6] https://groups.google.com/forum/#!topic/android-emulator-dev/dltBnUW_HzU