作者归档:softsim

修改super.img

0.将Android sparse image格式转换为raw image

simg2img super.img   super.img.raw

1.提取 system分区
有两个工具,一个是Android项目中的 lpunpack, 另一个大神的imjtool

lpunpack --partition=system super.img.raw
lpunpack --partition=vendor super.img.raw
lpunpack --partition=product super.img.raw
提取所有
lpunpack super.img.raw

imgtool的命令为

./imjtool.ELF64 super.img.raw extract
MMapped: 0x7f460c400000, imgMeta 0x7f460c401000
liblp dynamic partition (super.img) - Blocksize 0x1000, 3 slots
LP MD Header @0x3000, version 10.2, with 10 logical partitions on block device of 8704 GB, at partition super, first sector: 0x800
Partitions @0x3100 in 3 groups:
	Group 0: default
	Group 1: qti_dynamic_partitions_a
		Name: odm_a (read-only, Linux Ext2/3/4/? Filesystem Image, @0x100000 spanning 1 extents of 1 MB) - extracted
		Name: product_a (read-only, Linux Ext2/3/4/? Filesystem Image, @0x300000 spanning 1 extents of 474 MB) - extracted
		Name: system_a (read-only, Linux Ext2/3/4/? Filesystem Image, @0x1de00000 spanning 1 extents of 5 GB) - extracted
		Name: system_ext_a (read-only, Linux Ext2/3/4/? Filesystem Image, @0x15f600000 spanning 1 extents of 473 MB) - extracted
		Name: vendor_a (read-only, Linux Ext2/3/4/? Filesystem Image, @0x17d000000 spanning 1 extents of 2 GB) - extracted
	Group 2: qti_dynamic_partitions_b
		Name: odm_b (read-only,  empty) - extracted
		Name: product_b (read-only,  empty) - extracted
		Name: system_b (read-only,  empty) - extracted
		Name: system_ext_b (read-only,  empty) - extracted
		Name: vendor_b (read-only,  empty) - extracted


如果遇到错误,请用sudo执行

2. 修改system.img为可写

fallocate -l 2G system.img
/sbin/resize2fs system.img 2G

看实际的system.img的大小,适当大一些
6G

3.0 移除共享块
如果报错 couldn’t mount RDWR because of unsupported optional features (4000)
4000特性就是 EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS

可以用下面的命令 去掉

e2fsck -y -E unshare_blocks  system.img

也可以检查是否有这个feature

/sbin/dumpe2fs vendor_a.img 
...
Filesystem features:      ext_attr dir_index .... extra_isize shared_blocks

3.1 挂载

mount -t ext4 -o loop system.img system
如果是EROFS 只读文件系统
mount -t erofs  -o loop system.ext4.img /mnt

4. 编辑 system目录下的文件

...

5. 卸载 system 目录

umount system

6.修改文件系统错误

e2fsck -yf system.img

7. 让system.img占用尽可能小的空间

resize2fs -M system.img
e2fsck -yf system.img

8. 查看真实分区大小

stat -c '%n %s' system.img

stat -c '%n %s' *
product.img 1596944384
system.img 1128718336
vendor.img 544976896

8.写回

lpmake --metadata-size 65536 --super-name super --metadata-slots 1 
--device super:4294967296 
--group main:3139354624 
--partition system:readonly:1128718336:main --image system=./system.img 
--partition vendor:readonly:544976896:main --image vendor=./vendor.img 
--partition product:readonly:1596944384:main --image product=./product.img 
--sparse --output ./super.new.img

group这里是所有分区的文件大小加起来的和

–metadata-slots 要跟 imjtool 工具输出的一样
实际, device-size设置为8G

lpmake --metadata-size 65536    --device-size=8589934592   --metadata-slots=3   
--group=qti_dynamic_partitions_a:8053952512   
--partition=odm_a:none:1470464:qti_dynamic_partitions_a   
--partition=product_a:none:407822336:qti_dynamic_partitions_a   
--partition=system_a:none:4835311616:qti_dynamic_partitions_a  
--partition=system_ext_a:none:496226304:qti_dynamic_partitions_a   
--partition=vendor_a:none:2313121792:qti_dynamic_partitions_a   
--image=odm_a=./odm_a.img  --image=product_a=./product_a.img  --image=system_a=./system_a.img  --image=system_ext_a=./system_ext_a.img   --image=vendor_a=./vendor_a.img   
--group=qti_dynamic_partitions_b:0  
--partition=odm_b:none:0:qti_dynamic_partitions_b  
--partition=product_b:none:0:qti_dynamic_partitions_b  
--partition=system_b:none:0:qti_dynamic_partitions_b  
--partition=system_ext_b:none:0:qti_dynamic_partitions_b  
--partition=vendor_b:none:0:qti_dynamic_partitions_b  
--image=odm_b=./odm_b.img  --image=product_b=./product_b.img  --image=system_b=./system_b.img  --image=system_ext_b=./system_ext_b.img  --image=vendor_b=./vendor_b.img  
--sparse  --output /media/3/tmp/super.new.img

lpmake I 10-14 19:06:49 11155 11155 builder.cpp:1031] [liblp]Partition odm_a will resize from 0 bytes to 1470464 bytes
lpmake I 10-14 19:06:49 11155 11155 builder.cpp:1031] [liblp]Partition product_a will resize from 0 bytes to 407822336 bytes
lpmake I 10-14 19:06:49 11155 11155 builder.cpp:1031] [liblp]Partition system_a will resize from 0 bytes to 4835311616 bytes
lpmake I 10-14 19:06:49 11155 11155 builder.cpp:1031] [liblp]Partition system_ext_a will resize from 0 bytes to 496226304 bytes
lpmake I 10-14 19:06:49 11155 11155 builder.cpp:1031] [liblp]Partition vendor_a will resize from 0 bytes to 2313121792 bytes
Invalid sparse file format at header magic
Invalid sparse file format at header magic
Invalid sparse file format at header magic
Invalid sparse file format at header magic
Invalid sparse file format at header magic
Invalid sparse file format at header
Invalid sparse file format at header
Invalid sparse file format at header
Invalid sparse file format at header
Invalid sparse file format at header
lpmake --metadata-size 65536\
 --device-size=4294967296\
 --metadata-slots=3\
 --group=google_system_dynamic_partitions_a:2222931968\
 --partition=odm_a:none:700416:google_system_dynamic_partitions_a\
 --partition=product_a:none:266579968:google_system_dynamic_partitions_a\
 --partition=system_a:none:1363767296:google_system_dynamic_partitions_a\
 --partition=system_ext_a:none:359391232:google_system_dynamic_partitions_a\
 --partition=vendor_a:none:232493056:google_system_dynamic_partitions_a\
 --image=odm_a=./odm_a.img\
 --image=product_a=./product_a.img\
 --image=system_a=./system_a.img\
 --image=system_ext_a=./system_ext_a.img\
 --image=vendor_a=./vendor_a.img\
 --group=google_system_dynamic_partitions_b:24563712\
 --partition=odm_b:none:0:google_system_dynamic_partitions_b\
 --partition=product_b:none:0:google_system_dynamic_partitions_b\
 --partition=system_b:none:24563712:google_system_dynamic_partitions_b\
 --partition=system_ext_b:none:0:google_system_dynamic_partitions_b\
 --partition=vendor_b:none:0:google_system_dynamic_partitions_b\
 --image=odm_b=./odm_b.img\
 --image=product_b=./product_b.img\
 --image=system_b=./system_b.img\
 --image=system_ext_b=./system_ext_b.img\
 --image=vendor_b=./vendor_b.img\
 --sparse \
 --output ./super.new.img

参考资料:
https://forum.xda-developers.com/t/editing-system-img-inside-super-img-and-flashing-our-modifications.4196625/
https://blog.senyuuri.info/posts/2022-04-27-patching-android-super-images/

用superunpack和superrepack直接编辑修改Android 11的super分区

参考资料:

https://forum.xda-developers.com/t/tool-win-lin-and-darw-super-image-tools-extract-or-make-partitions-rw-in-super-partition.4120963/

https://github.com/munjeni/super_image_dumper

https://gist.github.com/Systemad/0dd94142e73c7338b3b369ba1a628f5a

步骤:
从super分区 提取 可些的system.img

cd /data/local/tmp
chmod 755 superunpack.arm64_pie
./superunpack.arm64_pie /dev/block/bootdevice/by-name/super  1

挂载 system_a.img

mount -t ext4   system_a.img  system
如果上面,unpack不加1选项,system分区是只读的, mount是需要加 ro选项
mount -t ext4 -o ro  system_a.img  system

修改

删除,替换文件

写回

cd /data/local/tmp
mv superrepack.arm64_pie superrepack
chmod 755 superrepack
stop
./superrepack /dev/block/bootdevice/by-name/super system_a
sync
--------------------
stop
dd if=/dev/block/bootdevice/by-name/super of=/data/local/tmp/super.bin conv=notrunc
/data/local/tmp/superrepack /data/local/tmp/super.bin system_a rw
sync
dd if=/data/local/tmp/super.img of=/dev/block/bootdevice/by-name/super conv=notrunc
sync


在Linux系统也可修改 super.img 镜像

e2fsck -fy -E unshare_blocks system.ext4

-f                   Force checking even if filesystem is marked clean
-y                   Assume "yes" to all questions
-v                   Be verbose
-E extended-options

superunpack 不加 1选项,或者 lpunpack 或者 imgtool都提取的read only的image

/usr/sbin/e2fsck -f  system_a.ext4
/sbin/resize2fs system_a.ext4 4G
/usr/sbin/e2fsck -fyv  -E unshare_blocks  system_a.ext4

挂载

# mount -t ext4 -o loop,rw system_a.ext4

修改

修改后重新检查

e2fsck -f 

改成可写的分区

mount -o remount,rw  /
mount -o remount,rw  /system_ext
mount -o remount,rw  /product
mount -o remount,rw  /vendor
mount | grep dm-

使用方法

adb push superrepack.arm64_pie /data/local/tmp
adb shell
su
cd /data/local/tmp
mv superrepack.arm64_pie superrepack
chmod 755 superrepack
stop
./superrepack /dev/block/bootdevice/by-name/super system_a
sync
reboot

rust编译android命令行程序

参考资料:
https://kaisery.github.io/trpl-zh-cn/ch01-01-installation.html
https://blog.rust-lang.org/2016/05/13/rustup.html
https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html
https://ghotiphud.github.io/rust/android/cross-compiling/2016/01/06/compiling-rust-to-android.html
https://logankeenan.com/posts/cross-platform-rust-database-access-android/
https://github.com/rust-windowing/android-ndk-rs

0.安装rust

curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

1.安装Android NDK

/home/softsim/Android/Sdk/ndk/22.0.7026061

2. 添加target

rustup target add aarch64-linux-android 
rustup target add armv7-linux-androideabi 

rustup target list

3. 配置toolchain
编辑 ~/.cargo/config

[build]
target = "armv7-linux-androideabi"

[target.armv7-linux-androideabi]
linker = "/home/softsim/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi27-clang"

[target.aarch64-linux-android]
linker = "/home/softsim/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android27-clang"

NDK 23以上,去掉了 libgcc, 编译不通过,需要手动加上 libgcc

4.创建工程

cargo new --bin hello && cd hello
cargo build 


cargo build --target aarch64-linux-android --release --verbose
   Compiling hello v0.1.0 (/home/softsim/workspace/hello)
     Running `rustc --crate-name hello --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no -C metadata=fca5cedcba8d4943 -C extra-filename=-fca5cedcba8d4943 --out-dir /home/softsim/workspace/hello/target/aarch64-linux-android/release/deps --target aarch64-linux-android -C linker=/home/softsim/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android27-clang -L dependency=/home/softsim/workspace/hello/target/aarch64-linux-android/release/deps -L dependency=/home/softsim/workspace/hello/target/release/deps`
    Finished release [optimized] target(s) in 0.26s

自制usb强制9008 edl下载线

Type A 公头 引脚定义

 

 

EDL 9008短接线

 

 

将设备关机,连接此短接线缆, 但不连接电脑USB口。

用 金属导线(比如 取卡针) 连接  绿色(D+) 与 黑色线 (GND)

再连接电脑USB口

3秒后, 断开 D+ 与 GND

设备就会进入 9008模式

ble的写/确认/通知/指示

默认情形,characteristic write是需要确认的。对端设备将发送确认消息过来,其他GATT流量才会继续。
为提升吞吐,可以用 write without response, 对端设备发出 notifications ,结合起来提升吞吐率


外围设备可以发出notification或者indication来通知中央设备,来进行读写。
indication从外围设备发出后,中央设备需要对其进行确认。虽然这个确认是蓝牙协议栈做出的,跟应用层没有关系,但这也会降低速度。
当Android系统对 indication确认后, 会回调应用层的 onCharacteristicChanged 方法。

如果是notification, 那么 Client 应该去 设置 Server 上的 Client Characteristic Configuration descriptor为 ENABLE_NOTIFICATION_VALUE。
如果是indication, 则应该设置为 ENABLE_INDICATION_VALUE

在Android SDK中,调用 BluetoothGatt#setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enable) 将enable 设置为 true, 就可以了, 对于 notifications 和 indication都这样处理。

gatt.setCharacteristicNotification(characteristic, true);
...
UUID uuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(uuid);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);

Indications and Notifications are a way for a GATT Client to subscribe to data provided by a GATT Server.
A Notification is an unacknowledged message or update while an Indication is an acknowledged message or update.
These Notifications and Indications are sent any time the relevant data in the GATT table on the GATT Server is updated. (You must “subscribe” to the data that you would like to be Notified or Indicated of) In a way Indications and Notifications are much like TCP and UDP packets. TCP requires that when data is sent, the receiver acknowledges that the data has been received by sending back an ACKnowledgement packet. UDP just sends off data without any concern whether it is actually confirmed to be received or not. In this sense Indications are akin to TCP and Notifications are akin to UDP.

Android用intent开关蓝牙

开启

            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

关闭

 
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); 
mBTAdapter.disable(); 

获取已经配对的设备

mPairedDevices = mBTAdapter.getBondedDevices();
for (BluetoothDevice device : mPairedDevices)
               device.getName() + "\n" + device.getAddress();

Android系统电话相关的几个权限

android.permission.MODIFY_PHONE_STATE
修改电话状态:开机,MMI等。 不包括打电话
此权限, 只能为系统应用 所获取。 第3方开发应用不能获得此权限

iccOpenLogicalChannel 需要此权限 或者 有运营商权限 (hasCarrierPrivileges)

android.permission.READ_PHONE_STATE
读取电话状态:包括移动网络信息,电话当前的状态

getSubscriberId 需要
1) READ_PRIVILEGED_PHONE_STATE
2) READ_PHONE_STATE
3) hasCarrierPrivileges()
4) 默认的短信应用
5) android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER

getSimSerialNumber
1) READ_PRIVILEGED_PHONE_STATE
2) READ_PHONE_STATE
3) hasCarrierPrivileges

从 Android 10 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 特许权限才能访问设备的不可重置标识符(包含 IMEI 和序列号)。

Android系统仅会向使用平台密钥进行签名的应用以及特权系统应用授予 READ_PRIVILEGED_PHONE_STATE 权限。

两点要求:

1)app使用平台签名

2) app是特权系统应用(放在 /system/priv-app目录?)

特许权限白名单,以向特权应用授予 READ_PRIVILEGED_PHONE_STATE 权限

如果应用是预加载(预装到系统)的特权应用,则需要获得在 AndroidManifest.xml 中声明的 READ_PRIVILEGED_PHONE_STATE 权限。此外,该应用还需要将此特许权限列入白名单。

特权应用是位于系统映像某个分区上 priv-app 目录下的系统应用。各 Android 版本中,该分区为:

  • Android 8.1 及更低版本 – /system
  • Android 9 及更高版本 – /system, /product, /vendor

/etc/permissions/priv-app 应该实际解析为 partition/etc/permissions/priv-app

早期版本中,设备制造商几乎无法控制可对特权应用授予哪些签名|特许权限。从 Android 8.0 开始,制造商必须在 /etc/permissions 目录下的系统配置 XML 文件中明确授予特许权限。从 Android 9 开始,实现人员必须明确授予或拒绝授予所有特许权限,否则设备将无法启动。

privapp-permissions.xml 文件只有在与特权应用位于同一分区时才能授予或拒绝授予该应用权限。例如,如果 /vendor 分区上的应用请求特许权限,则只能由同样位于 /vendor 上的 privapp-permissions.xml 文件来同意或拒绝该请求。

应用的权限白名单可列在位于 frameworks/base/etc/permissions 目录下的单个或多个 XML 文件中,如下所示:

  • /etc/permissions/privapp-permissions-OEM_NAME.xml
  • /etc/permissions/privapp-permissions-DEVICE_NAME.xml

对于如何组织内容,没有严格的规则。设备实现人员可以决定内容结构,只要 /system/priv-app 下的所有应用均列入白名单即可。例如,Google 针对由 Google 开发的所有特权应用提供了一个白名单,并建议使用以下组织方式:

  • 对于已包含在 Android 开源项目 (AOSP) 树中的应用,请将其权限列在 /etc/permissions/privapp-permissions-platform.xml 中。
  • 对于 Google 应用,请将其权限列在 /etc/permissions/privapp-permissions-google.xml 中。
  • 对于其他应用,请使用以下格式的文件:/etc/permissions/privapp-permissions-DEVICE_NAME.xml

https://source.android.com/devices/tech/config/perms-whitelist?hl=zh-cn

PermissionManagerService.java

PhoneSubInfoController.java

ContextImpl.java

public int checkPermission(String permission, int pid, int uid) {
….
am.checkPermission(permission, pid, uid);

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/permission/PermissionManager.java

am.checkPermission(permission, pid, uid);

ActivityManagerService.checkPermission

com.android.server.am.ActivityManagerService

public static int checkComponentPermission(String permission, int uid,
int owningUid, boolean exported) {
….

https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/pm/permission/PermissionManagerService.java

public int checkPermission(String permName, String pkgName, int userId) {

https://gowa.club/Android/Android%E7%9A%84%E6%9D%83%E9%99%90%E6%A3%80%E6%9F%A5%E8%BF%87%E7%A8%8B.html

https://lishuaiqi.top/2017/07/06/Permission3-checkPermissions/#1-3-checkPermission

高通可穿戴芯片

Snapdragon Wear 1100: Cortex-A7 1.2G LTE Cat1 Modem 发布于2016年,没人用

Snapdragon Wear 1200: Cortex-A7 1.3G LTE M1/NB1 Modem 发布于2017年,也没人用

Snapdragon Wear 2100: 4核Cortex A7 (就是Qualcomm Technologies, Inc MSM8909W) 1.2G X5 Modem(Cat 4) 发布于2016年

Snapdragon Wear 2500: 4x ARM Cortex A7 , 其实也是8909w

Snapdragon Wear 3100: MSM8909w (Cortex A7*4 1.2G) X5 Modem(Cat4) 协处理器QCC 1100 发布于2018年

其中 MSM890w 来源于 发布于2014年9月9日的 Snapdragon 210(MSM8909),CPU和基带规格一致

Snapdragon Wear 3100: 来源于 SDM425 (Cortext A53) X5 Modem

华米智能手表2(Nexo) 参数:https://www.amazfit.com/cn/nexo.html

1.39 英寸 AMOLED 454*454分辨率

高通 Snapdragon Wear 2500 4核A7 1.1GHz

512MB LPDDR3

4G eMMC (用户可用空间约 1GB)

Bluetooth 4.2 + BLE

出门问问 TicWatch Pro 4G/LTE 参数

https://www.chumenwenwen.com/product/ticwatchpro-parameter.html

https://www.mobvoi.com/us/pages/ticwatchpro4g

Qualcomm® Snapdragon Wear™ 2100,在 /proc/cpuinfo里显示Qualcomm Technologies, Inc MSM8909W

显示屏1:AMOLED屏 400*400像素/287ppi
显示屏2:单色液晶屏

Ticwatch Pro 4G 2020版  型号:WF20066

Ticwatch Pro 2021 4G版   型号:

Ticwatch Pro 4G 2019   型号: WF11016

TicWatch Pro 4G (catshark)安装Magisk

1. 手机上安装Wear OS By Google, 蓝牙配对激活手表

2. 手表上在待机界面下滑,调出设置界面,  设置→系统→关于→版本号(注意是下面的版本号,不是上面的版本),狂点,即可打开开发者模式

3. 设置→开发者选项,打开 ADB调试

4. PC上运行

adb reboot bootloader
fastboot oem unlock

然后在手表上,用 音量键 (下面那个按钮) 选择 unlock, 然后用 电源键 (上面那个按钮) 选择确定。

5. 手表会重启,并恢复出厂设置,按照步骤1,重新激活手表

6. 下载 twrp
https://dl.twrp.me/catshark/twrp-3.5.0_9-0-catshark.img.html

7. 启动到recovery

adb reboot bootloader
fastboot boot  twrp-3.5.0_9-0-catshark.img

8. 下载Magisk v21.4
https://github.com/topjohnwu/Magisk/releases/download/v21.4/Magisk-v21.4.zip

9.

adb sideload Magisk-v21.4.zip