OTA 패키지 내부에서 사용

시스템이 bootable/recovery/updater 에서 업데이터 바이너리를 빌드하여 OTA 패키지에서 사용합니다.

패키지 자체는 실행 바이너리 META-INF/com/google/android/update-binary 가 포함된 .zip 파일(ota_update.zip, incremental_ota_update.zip)입니다.

업데이터에는 일반적인 업데이트 관련 작업의 명령어를 지원하는 확장 가능한 스크립트 언어(edify)의 인터프리터와 여러 내장 함수가 포함되어 있습니다. 업데이터는 패키지 .zip 파일에서 META-INF/com/google/android/updater-script 파일의 스크립트를 찾습니다.

참고: edify 스크립트나 내장 함수 사용은 일반적인 활동이 아니지만 업데이트 파일을 디버그해야 하는 경우에는 유용합니다.

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

a~z, A~Z, 0~9, _, :, /, . 문자로 구성되었으나 예약어가 아닌 문자열은 문자열 리터럴로 간주됩니다. (예약어는 if else 그리고 endif임) 문자열 리터럴은 큰 따옴표로 표시될 수도 있습니다. 이는 공백과 위의 문자 집합에 없는 문자를 사용하여 값을 만드는 방법입니다. \n, \t, \", \\는 \x##과 같이 따옴표로 묶인 문자열 내에서 이스케이프 문자로 제공됩니다.

&& 및 || 연산자는 단락되어 있어 논리 결과가 왼쪽에 따라 결정되는 경우 오른쪽은 평가되지 않습니다. 다음은 동일합니다.

e1 && e2
if e1 then e2 endif

; 연산자는 시퀀스 포인트입니다. 즉, 먼저 왼쪽을 평가한 다음 오른쪽을 평가합니다. 그 값은 오른쪽 표현식의 값입니다. 세미콜론은 표현식 뒤에 나타날 수도 있고 그 효과는 C 스타일 문을 시뮬레이션하는 것입니다.

prepare();
do_other_thing("argument");
finish_up();

내장 함수

대부분의 업데이트 기능은 스크립트로 실행에 사용할 수 있는 함수에 포함되어 있습니다. (엄밀히 말하면, 이러한 함수는 인수를 전부 평가할 필요가 없기 때문에 Lisp에서는 함수라기 보다는 매크로입니다. 달리 명시되지 않는 한 함수는 성공 시 true를, 오류 발생 시 false를 반환합니다. 오류 발생 시 스크립트 실행을 취소하려면 abort() 또는 assert() 함수를 사용합니다. 업데이터에서 사용할 수 있는 함수 세트를 확장하여 기기별 기능을 제공할 수도 있습니다.

abort([msg])
선택적인 msg를 사용하여 즉시 스크립트 실행을 취소합니다. 사용자가 텍스트 표시를 켜면 msg가 복구 로그 및 화면에 표시됩니다.
assert(expr[, expr, ...])
expr을 차례로 평가합니다. 이 중 하나라도 false이면 실행이 즉시 취소되고 '어설션 실패' 메시지와 실패한 표현식의 소스 텍스트가 표시됩니다.
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
src_file에 바이너리 패치를 적용하여 tgt_file을 생성합니다. 원하는 타겟이 소스와 동일하다면 tgt_file에 '-'를 전달합니다. tgt_sha1tgt_size는 예상된 최종 SHA1 해시와 타겟 파일의 크기입니다. 나머지 인수는 SHA1 해시(40자의 16진수 문자열)와 blob으로 구성된 쌍이어야 합니다. blob은 소스 파일의 현재 콘텐츠에 지정된 SHA1이 있을 때 적용되는 패치입니다.

패치는 타겟 파일이 원하는 SHA1 해시 및 크기를 갖거나 수정되지 않도록(복구할 수 없는 중간 상태로 남지 않음) 보장하는 안전한 방식으로 실행됩니다. 패치가 진행되는 동안 프로세스가 중단되면 타겟 파일이 중간 상태일 수 있습니다. 캐시 파티션에 사본이 있으므로 업데이트를 다시 시작하면 파일이 성공적으로 업데이트될 수 있습니다.

특수 구문은 MTD(Memory Technology Device) 파티션의 콘텐츠를 파일로 처리하도록 지원되어 부팅과 같은 원시 파티션 패치를 허용합니다. MTD 파티션에는 파일 끝이라는 개념이 없으므로 이 파티션을 읽으려면 읽으려는 데이터의 양을 알아야 합니다. 'MTD:partition:size_1:sha1_1:size_2: sha1_2' 문자열을 파일 이름으로 사용하여 지정된 파티션을 읽을 수 있습니다. 하나 이상의 size, sha-1 쌍을 지정해야 합니다. 읽을 것으로 기대되는 내용에 관한 가능성이 여러 가지일 경우 두 개 이상을 지정할 수 있습니다.

apply_patch_check(filename, sha1[, sha1, ...])
파일 이름의 내용 또는 캐시 파티션(있는 경우)의 임시 사본에 지정된 sha1 값 중 하나와 같은 SHA1 체크섬이 있는 경우 true를 반환합니다. sha1 값은 40자리 16진수로 지정됩니다. 이 함수는 캐시 파티션 사본을 확인하는 것을 안다는 점에서 sha1_check(read_file(filename), sha1 [, ...])와 다르므로 파일이 중단된 apply_patch() update로 인해 손상된 경우에도 apply_patch_check()는 성공합니다.
apply_patch_space(bytes)
바이너리 패치를 적용하는 데 스크래치 공간의 최소 바이트를 사용할 수 있는 경우 true를 반환합니다.
concat(expr[, expr, ...])
각 표현식을 평가하고 연결합니다. + 연산자는 인수가 2개인 특수한 경우 이 함수의 슈가입니다(그러나 함수 양식에서는 개수에 제한 없이 표현식을 사용할 수 있음). 표현식은 문자열이어야 하고 blob을 연결할 수 없습니다.
file_getprop(filename, key)
지정된 파일 이름을 읽고, 속성 파일(예: /system/build.prop)로 해석하고, 지정된 의 값 또는 (가 없는 경우에는) 빈 문자열을 반환합니다.
format(fs_type, partition_type, location, fs_size, mount_point)
지정된 파티션을 다시 포맷합니다. 지원되는 파티션 유형:
  • fs_type="yaffs2" 및 partition_type="MTD". 위치는 MTD 파티션의 이름이어야 하며, 여기서 빈 yaffs2 파일 시스템이 구성됩니다. 나머지 인수는 사용되지 않습니다.
  • fs_type="ext4" 및 partition_type="EMMC". 위치는 파티션의 기기 파일이어야 합니다. 여기서 빈 ext4 파일 시스템이 구성됩니다. fs_size가 0이면 파일 시스템이 전체 파티션을 차지합니다. fs_size가 양수이면 파일 시스템이 파티션의 처음 fs_size 바이트를 차지합니다. fs_size가 음수이면 파일 시스템이 파티션의 마지막 |fs_size| 바이트를 제외한 모든 부분을 차지합니다.
  • fs_type="f2fs" 및 partition_type="EMMC". 위치는 파티션의 기기 파일이어야 하고, fs_size는 음수가 아닌 숫자여야 합니다. fs_size가 0이면 파일 시스템이 전체 파티션을 차지합니다. fs_size가 양수이면 파일 시스템이 파티션의 처음 fs_size 바이트를 차지합니다.
  • mount_point는 파일 시스템의 향후 마운트 지점이어야 합니다.
getprop(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)
needlehaystack의 하위 문자열인 경우 true를 반환합니다.
less_than_int(a, b)
a(정수로 해석됨)가 b(정수로 해석됨)보다 작은 경우 true를 반환합니다.
mount(fs_type, partition_type, name, mount_point)
mount_point에서 fs_type의 파일 시스템을 마운트합니다. partition_type은 다음 중 하나여야 합니다.
  • MTD. 이름은 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으로 반환합니다.
read_file(filename)
파일 이름을 읽고 그 내용을 바이너리 blob으로 반환합니다.
run_program(path[, arg, ...])
path에서 바이너리를 실행하여 args를 전달합니다. 프로그램의 종료 상태를 반환합니다.
set_progress(frac)
최근 show_progress() 호출로 정의된 청크 내에서 진행 미터의 위치를 설정합니다. frac는 [0.0, 1.0] 범위 내에 있어야 합니다. 진행 미터는 뒤로 이동하지 않고 뒤로 이동하려는 시도는 무시됩니다.
sha1_check(blob[, sha1])
blob 인수는 read_file()에서 반환하는 유형 또는 package_extract_file() 의 단일 인수 형식입니다. sha1 인수가 없으면 이 함수는 blob의 SHA1 해시를 (40자리 16진수 문자열로) 반환합니다. 하나 이상의 sha1 인수를 사용하는 경우 이 함수는 SHA1 해시가 인수 중 하나와 같으면 SHA1 해시를 반환하고 그렇지 않은 경우 빈 문자열을 반환합니다.
show_progress(frac, secs)
secs초(정수여야 함)를 넘는 길이의 다음 frac에 걸쳐 진행 미터를 진행합니다. secs는 0일 수 있습니다. 이 경우 미터는 자동으로 진행하지 않고 위에서 정의한 set_progress() 함수를 사용하여 진행합니다.
sleep(secs)
secs 동안 절전 모드입니다(정수여야 함).
stdout(expr[, expr, ...])
각 표현식을 평가하고 값을 stdout에 덤프합니다. 디버깅에 유용합니다.
tune2fs(device[, arg, …])
기기의 조정 가능한 매개변수 args를 조정합니다.
ui_print([text, ...])
모든 text 인수를 연결하고 결과를 UI에 인쇄합니다. 사용자가 텍스트 표시를 설정한 경우 표시됩니다.
unmount(mount_point)
mount_point에 마운트된 파일 시스템을 마운트 해제합니다.
wipe_block_device(block_dev, len)
지정된 블록 기기 block_devlen 바이트를 삭제합니다.
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");

참고: Android 4.1 이전에는 파일 이름만 허용되었으므로 이를 위해서는 데이터를 먼저 임시 로컬 파일로 압축 해제해야 했습니다.