安卓edify脚本语法内建函数 updater_script脚本分析

OTA更新包

系统从bootable/recovery/updater编译更新程序二进制文件并将其用于 OTA 更新包。

更新包本身是包含可执行二进制文件META-INF/com/google/android/update-binary的 .zip 文件(ota_update.zipincremental_ota_update.zip)。
更新程序包含多个内建函数和一个可扩展脚本语言 (Edify) 解释器,该脚本语言支持用于执行更新相关的典型任务的命令。更新程序会从 .zip 压缩包文件中查找 META-INF/com/google/android/updater-script文件中的脚本。

Edify 语法

Edify 脚本是一个单一的表达式,其中的所有值都是字符串。从布尔值角度考虑,空字符串为 False,其他所有字符串均为 True。Edify 支持以下运算符(具有常规含义):

(expr )
 expr + expr  # string concatenation, not integer addition
 expr == expr
 expr != expr
 expr && expr
 expr || expr
 ! expr
 if expr then expr endif
 if expr then expr else expr endif
 function_name(expr, expr,...)
 expr; expr
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

由 a-z、A-Z、0-9、_、:、/、. 组成的任何字符串,只要不属于非保留字,均视为字符串字面值。(保留字为 if else then endif。)字符串字面值也可以用双引号引起来;通过这种方法可以使用空格和上述集合之外的其他字符来创建值。\n、\t、\” 和 \ 充当带引号的字符串中的转义字符,\x## 亦如此。

&& 和 || 为短路运算符;如果逻辑结果由左侧确定,则不评估右侧。下面两个表达式是对等的:

e1 && e2
if e1 then e2 endif
  • 1
  • 2

分号“;”运算符是序列点;表示要先评估左侧,再评估右侧。它的值是右侧表达式的值。分号也可以出现在表达式之后,其效果与 C 风格语句相仿:

prepare();
do_other_thing("argument");
finish_up();
  • 1
  • 2
  • 3

内建函数

大部分更新功能都包含在可供脚本执行的函数中。(严格来说,这些是“宏”,而不是 Lisp 意义上的函数,因为它们不需要评估所有参数。)除非另有说明,函数在成功时返回 True,出错时返回 False。如果您希望在出错时中止脚本执行,请使用abort()和/或 assert()函数。您也可以扩展更新程序中的可用函数集,以提供设备特定的功能。

abort([msg])

使用可选的 msg 立即中止脚本执行。如果用户开启了文本显示功能,msg 将出现在恢复日志和屏幕上。

assert(expr[, expr, …])

依序评估每个 expr。如果出现 false,则立即中止执行并显示“assert failed”和失败的表达式的源文本。

apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, […])

将二进制补丁程序应用于 src_file 以生成 tgt_file。如果设定的目标文件与源文件相同,则传递“-”作为 tgt_file。tgt_sha1 和 tgt_size 分别是目标文件的预期最终 SHA1 哈希值和文件大小。其余参数必须成对出现:一个 SHA1 哈希值(40 个字符的十六进制字符串)和一个 Blob。如果源文件当前的内容具有给定的 SHA1,该 Blob 即为要应用的补丁程序。

打补丁以一种安全的方式完成,该方式可保证目标文件要么具有所需的 SHA1 哈希值和大小,要么不发生变化,而不会处于不可恢复的中间状态。如果在打补丁过程中进程中断,目标文件可能会处于中间状态;这时缓存分区中会存在一个副本,重新启动更新便可成功更新文件。

支持特殊语法将 MTD(内存技术设备)分区的内容作为文件处理,以便为引导分区这样的原始分区打补丁。由于 MTD 分区没有文件结束标记,因此要读取该分区,您必须知道您要读取的数据量。您可以使用字符串“MTD:partition:size_1:sha1_1:size_2:sha1_2”作为文件名来读取给定的分区。您必须至少指定一个(size,sha-1)对;如果您希望读取的内容有多种可能,则可以指定多个对。

apply_patch_check(filename, sha1[, sha1, …])

如果 filename 的内容或缓存分区中的临时副本(如果存在)中的内容具有与给定的 sha1 值之一相等的 SHA1 校验和,则返回 True。sha1 值指定为 40 位十六进制数字。该函数不同于 sha1_check(read_file(filename), sha1 [, ...]),因为它知道要检查缓存分区副本,因此即使文件被中断的 apply_patch()update 损坏,apply_patch_check()也将成功。

apply_patch_space(bytes)

如果至少有 bytes 个字节的暂存空间可用于打二进制补丁程序,则返回 True。

block_image_verify(partition, transfer_list, new, patch)

partition参数是将要升级的块设备,通常就是/system分区。transfer_list参数是一个文本文件,包含在目标分区上将数据从一个位置传输到另一个位置的命令。这个命令只是空运行,实际上并不执行写入操作,只是用于判断升级是否可以进行。

block_image_update(partition, transfer_list, new, patch)

这个函数和block_image_verify功能一致,唯一的区别是执行实际的升级操作。

block_image_recover(partition, range)

恢复指定范围内的分区(假如块已损坏的话)。如果执行成功则返回字符串“t”,否则返回空字符串。

check_first_block(partition)

此功能检查在增量OTA更新之前是否已重新挂载读写权限。该函数读取每个分区的第一个块并检查挂载的时间和次数。如果执行成功则返回字符串“t”,否则返回空字符串。

concat(expr[, expr, …])

评估每个表达式并将它们连接起来。在只有两个参数的特殊情况下,+ 运算符就是该函数的语法糖(但该函数形式可以包含任意数量的表达式)。表达式必须为字符串;该函数不能连接 Blob。

file_getprop(filename, key)

读取给定的 filename,将其解释为属性文件(例如:/system/build.prop),并返回给定 key 的值,如果 key 不存在,则返回空字符串。

format(fs_type, partition_type, location, fs_size, mount_point)

重新格式化给定的分区。支持的分区类型如下:
- fs_type =“yaffs2”和 partition_type =“MTD”。Location 必须为 MTD 分区的名称;将在该位置构建一个空的 yaffs2 文件系统。其余参数未使用。
- fs_type =“ext4”和 partition_type =“EMMC”。Location 必须为该分区的设备文件。将在该位置构建一个空的 ext4 文件系统。如果 fs_size 为零,则文件系统将占用整个分区。如果 fs_size 为正数,则文件系统将占用分区的前 fs_size 个字节。如果 fs_size 为负数,则文件系统将占用分区中除最后 |fs_size| 个字节以外的所有字节。
- fs_type =“f2fs” 和 partition_type =“EMMC”。Location 必须为该分区的设备文件。fs_size 必须为非负数。如果 fs_size 为零,则文件系统将占用整个分区。如果 fs_size 为正数,则文件系统将占用分区的前 fs_size 个字节。
- mount_point 应为文件系统的未来挂载点。

getprop(key)

返回系统属性 key 的值(或者,如果未定义,则返回空字符串)。由恢复分区定义的系统属性值未必与主系统属性值相同。此函数返回恢复分区中的值。

greater_than_int(a, b)

当且仅当 (iff) a(解析为整数)大于 b(解析为整数)时,才返回 True。

ifelse(cond, e1[, e2])

评估 cond,如果为 True,则评估并返回 e1 的值,否则评估并返回 e2(如果存在)。“if … else … then … endif”结构就是此函数的语法糖。

is_mounted(mount_point)

当且仅当 mount_point 挂载了文件系统时,才返回 True。

is_substring(needle, haystack)

当且仅当 needle 是 haystack 的子字符串时,才返回 True。

less_than_int(a, b)

当且仅当 a(解析为整数)小于 b(解析为整数)时,才返回 True。

mount(fs_type, partition_type, name, mount_point)

在 mount_point 挂载 fs_type 的文件系统。 partition_type 必须为以下类型之一:
- MTD。
Name 是 MTD 分区的名称(例如:system、userdata;有关完整列表,请参见设备上的 /proc/mtd)。
- EMMC。
默认情况下,恢复分区不挂载任何文件系统(如果用户正在手动从 SD 卡安装软件包,则 SD 卡除外);您的脚本必须挂载需要修改的所有分区。

package_extract_dir(package_dir, dest_dir)

从 package_dir 下的文件包中提取所有文件,并将它们写入 dest_dir 下相应的树形结构中。所有现有文件都将被覆盖。

package_extract_file(package_file[, dest_file])

从更新包中提取单个 package_file 并将其写入 dest_file,如有必要,覆盖现有文件。在没有 dest_file 参数的情况下,将更新包文件的内容作为二进制 blob 返回。

range_sha1(partition, range)

检查指定范围内分区的SHA1哈希值,返回SHA1哈希值

read_file(filename)

读取 filename 并将其内容作为二进制 blob 返回。

run_program(path[, arg, …])

在 path 上执行二进制文件并传入 arg。返回程序的退出状态。

set_progress(frac)

在最近的 show_progress() 调用所定义的块内设置进度条的位置。frac 必须在 [0.0, 1.0] 范围内。进度条从不向后移动;向后移动的尝试会被忽略。

sha1_check(blob[, sha1])

blob 参数是 read_file() 返回的 blob 类型或 package_extract_file() 的单参数形式 blob。在没有 sha1 参数的情况下,此函数返回 blob 的 SHA1 哈希值(作为 40 位十六进制字符串)。在提供了一个或多个 sha1 参数的情况下,如果 SHA1 哈希值等于其中一个参数,则该函数返回此 SHA1 哈希值;如果与任何一个参数都不相等,则返回空字符串。

show_progress(frac, secs)

在 secs 秒(必须为整数)内推动进度条向前移动下一个 frac 的长度。secs 可为 0,在这种情况下,进度条不会自动向前移动,而是通过使用上面所定义的 set_progress() 函数实现进度递增。

sleep(secs)

休眠 secs 秒(必须为整数)。

stdout(expr[, expr, …])

评估每个表达式并将其值转储到 stdout。这在调试时很有用。

tune2fs(device[, arg, …])

调整 device 上的可调参数 arg。

ui_print([text, …])

连接所有 text 参数并将结果输出到界面(如果用户已开启文本显示功能,界面上将显示该结果)。

unmount(mount_point)

将挂载在 mount_point 上的文件系统卸载。

wipe_block_device(block_dev, len)

擦除给定块设备 block_dev 的 len 个字节。

wipe_cache()

可实现在安装过程成功结束时擦除缓存分区。

write_raw_image(filename_or_blob, partition)

将 filename_or_blob 中的映像写入 MTD 分区。 filename_or_blob 可以是一个指代本地文件的字符串或一个包含要写入的数据的 blob 值参数。要将文件从 OTA 包复制到分区,请使用:write_raw_image(package_extract_file("zip_filename"), "partition_name");

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值