ينشئ النظام ملف ثنائي المُحدِّث من bootable/recovery/updater
ويستخدمه
في حزمة OTA.
ota_update.zip
incremental_ota_update.zip
) يحتوي على الملف الثنائي القابل للتنفيذ
META-INF/com/google/android/update-binary
.
يحتوي Updater على العديد من الدوالّ المضمّنة ومُفسّر لغة برمجة قابلة للتوسيع (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
أي سلسلة من الأحرف a-z, A-Z, 0-9, _, :, /, . التي ليست كلمة محجوزة تُعتبر سلسلة حرفية. (الكلمات المحجوزة هي if else ثم endif.) قد تظهر أيضًا سلاسل ملفتة في علامتَي اقتباس مزدوجتَين، وهذه هي الطريقة لإنشاء قيم تحتوي على مسافات بيضاء وأحرف أخرى غير مضمّنة في المجموعة أعلاه. تُستخدَم الأحرف \n و\t و\" و\\ كأحرف تخطّي داخل سلاسل quotes ، كما هو الحال مع \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 بدوره. إذا كانت أيّ منها غير صحيحة، يتم إيقاف التنفيذ على الفور مع عرض الرسالة "تعذّر التأكيد" ونص المصدر للتعبير الذي تعذّر تنفيذه.
-
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 المحدّد.
يتم إجراء التصحيح بطريقة آمنة تضمن أنّ الملف المستهدف يحتوي على تجزئة 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 المحدّدة.
يتم تحديد قيم sha1 على أنّها 40 رقمًا سداسيًا عشريًا. تختلف هذه الدالة عن دالة
sha1_check(read_file(filename), sha1 [, ...])
من حيث أنّها تعرف أنّه يجب التحقّق من نسخة قسم ذاكرة التخزين المؤقت، لذا ستنجح دالةapply_patch_check()
حتى إذا كان الملف تالفًا بسبب انقطاع عمليةapply_patch() update
. apply_patch_space(bytes)
- تعرض هذه الدالة القيمة "صحيح" إذا كانت هناك مساحة تخزين مؤقتة بايت على الأقل متاحة لتطبيق التعديلات الثنائية.
-
concat(expr[, expr, ...])
- يُحدِّد قيمة كل تعبير ويجمِّعها. عامل التشغيل + هو تنسيق نحوي لهذه الدالة في الحالة الخاصة التي تتضمّن وسيطتَين (ولكن يمكن أن يتضمّن نموذج الدالة أي عدد من التعبيرات). يجب أن تكون التعبيرات سلاسل، ولا يمكن تسلسل ملفات نصية.
-
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 تساوي صفرًا، يشغل نظام الملفات القسم بأكمله. إذا كان fs_size عددًا موجبًا، يأخذ نظام الملفات أول fs_size بايت من القسم. إذا كان fs_size هو عدد سلبي، سيأخذ نظام الملفات كل وحدات البايت في القسم باستثناء |fs_size| وحدات البايت الأخيرة.
- fs_type="f2fs" وpartition_type="EMMC". يجب أن يكون الموقع هو ملف الجهاز للقسيمة fs_size يجب أن يكون رقمًا غير سالب. إذا كانت قيمة fs_size تساوي صفرًا، يشغل نظام الملفات القسم بأكمله. إذا كان fs_size عددًا موجبًا، يأخذ نظام الملفات أول fs_size بايت من القسم.
- يجب أن تكون mount_point هي نقطة الربط المستقبلية لنظام الملفات.
getprop(key)
- تعرض قيمة خاصية النظام key (أو السلسلة الفارغة، إذا لم يتم تحديدها). لا تكون قيم سمات النظام التي يحدّدها قسم الاسترداد مماثلة بالضرورة لقيم النظام الرئيسي. تعرض هذه الدالة القيمة في وضع الاسترداد.
-
greater_than_int(a, b)
- تعرض القيمة "صحيح" إذا كان أ (الذي يتم تفسيره كعدد صحيح) أكبر من ب (الذي يتم تفسيره كعدد صحيح) فقط.
-
ifelse(cond, e1[, e2])
- يتم تقييم cond، وإذا كان صحيحًا، يتم تقييم قيمة e1 وعرضها، بخلاف ذلك، يتم تقييم e2 وعرضها (إذا كانت متوفّرة). إنّ بنية "if ... else ... then ... endif" هي مجرد تنسيق بسيط لهذه الدالة.
is_mounted(mount_point)
- تعرض القيمة true إذا كان هناك نظام ملفات تم تثبيته في نقطة_التثبيت.
-
is_substring(needle, haystack)
- تعرِض True إذا كانت needle سلسلة فرعية من haystack.
-
less_than_int(a, b)
- تعرض القيمة صحيحة إذا كان أ (المُفترَض أنّه عدد صحيح) أقل من ب (المُفترَض أنّه عدد صحيح).
-
mount(fs_type, partition_type, name, mount_point)
-
تثبيت نظام ملفات من النوع fs_type في mount_point. يجب أن يكون partition_type
أحد الخيارَين التاليَين:
-
MTD: الاسم هو اسم قسم MTD (مثل system وuserdata، اطّلِع على
/proc/mtd
على الجهاز للحصول على قائمة كاملة). - وحدة تحكُّم في الذاكرة (EMMC)
لا تُثبِّت ميزة "الاسترداد" أيّ أنظمة ملفات تلقائيًا (باستثناء بطاقة SD إذا كان المستخدم يُجري عملية تثبيت يدوي لحزمة من بطاقة SD)، ويجب أن يُثبِّت النص البرمجي أيّ أقسام يحتاج إلى تعديلها.
-
MTD: الاسم هو اسم قسم MTD (مثل system وuserdata، اطّلِع على
-
package_extract_dir(package_dir, dest_dir)
- تستخرج هذه الوظيفة جميع الملفات من الحزمة ضمن package_dir وتكتبها في الشجرة المقابلة ضمن dest_dir. يتم استبدال أي ملفات حالية.
-
package_extract_file(package_file[, dest_file])
- تستخرج هذه الوظيفة ملفًا واحدًا package_file من حزمة التحديث وتكتبه في dest_file، مع استبدال الملفات الحالية إذا لزم الأمر. بدون الوسيطة dest_file، يتم عرض محتوى ملف الحزمة كمجموعة بيانات ثنائية.
read_file(filename)
- تقرأ filename وتُرجع محتوياتها كمجموعة بيانات ثنائية.
-
run_program(path[, arg, ...])
- تنفيذ الملف الثنائي في المسار، مع تمرير المَعلمات عرض حالة الخروج من البرنامج
set_progress(frac)
-
يُستخدَم لضبط موضع مقياس التقدّم ضمن الجزء المحدّد من خلال أحدث
show_progress()
مكالمة. يجب أن تكون قيمة frac ضمن النطاق [0.0, 1.0]. لا يتراجع مقياس التقدّم أبدًا، ويتم تجاهل محاولات إجراء ذلك. -
sha1_check(blob[, sha1])
-
الوسيطة blob هي عنصر blob من النوع الذي تعرضه دالة
read_file()
أو صيغةpackage_extract_file()
التي تحتوي على وسيطة واحدة. في حال عدم توفّر وسيطات sha1، تعرض هذه الدالة تجزئة SHA1 للملفّ الثنائي (بصفتها سلسلة سداسية عشرية تتألّف من 40 رقمًا). مع وسيطة واحدة أو أكثر من وسيطات sha1، تعرض هذه الدالة تجزئة SHA1 إذا كانت مساوية لواحدة من وسيطات أو السلسلة الفارغة إذا لم تكن مساوية لأي منها. -
show_progress(frac, secs)
-
تُحرِّك هذه الدالة مقياس التقدّم إلى الجزء التالي من طوله على مدار secs ثانية (يجب أن يكون عددًا صحيحًا). ويمكن أن تكون secs 0، وفي هذه الحالة لا يتم تحرُّك المقياس
تلقائيًا ولكن باستخدام الدالة
set_progress()
المحدَّدة أعلاه. sleep(secs)
- توقّف مؤقتًا لمدة secs ثانية (يجب أن يكون عددًا صحيحًا).
-
stdout(expr[, expr, ...])
- تُقيّم كل تعبير وتُفرِغ قيمته إلى stdout. مفيدة لتصحيح الأخطاء
-
tune2fs(device[, arg, …])
- يضبط المَعلمات القابلة للضبط args على device.
ui_print([text, ...])
- تُدمج جميع وسيطات النص وتطبع النتيجة في واجهة المستخدم (حيث سيكون مرئيًا إذا فعّل المستخدم عرض النص).
unmount(mount_point)
- تؤدي هذه الوظيفة إلى إلغاء تثبيت نظام الملفات المثبَّت في نقطة_التثبيت.
-
wipe_block_device(block_dev, len)
- تؤدي هذه الوظيفة إلى محو len بايت من جهاز الكتلة المحدَّد block_dev.
wipe_cache()
- يؤدي ذلك إلى محو قسم ذاكرة التخزين المؤقت في نهاية عملية تثبيت ناجحة.
-
write_raw_image(filename_or_blob, partition)
-
يُسجِّل الإجراء الصورة في filename_or_blob في قسم MTD.
يمكن أن يكون filename_or_blob سلسلة تُحدِّد اسم ملف على الجهاز أو مَعلمة ذات قيمة ملف ثنائي
تحتوي على البيانات المطلوب كتابتها. لنسخ ملف من حزمة OTA إلى قسم، استخدِم:
write_raw_image(package_extract_file("zip_filename"), "partition_name");
ملاحظة: قبل الإصدار 4.1 من Android، كان يتم قبول أسماء الملفات فقط، لذا لتنفيذ ذلك، كان يجب أولاً فك ضغط البيانات في ملف مؤقت على الجهاز.