OTA (1) - edify

1. edify and flex/bison

a mini OTA script language, implemenation under bootable/recovery/edify/, the README is a good start to study edify.

flex/bison: They are aging unix utils that help to write fast parsers. They are written in C and ouput C code.

Reference: A good turotial on flex/bision

Flex can do the parsing work indepently:

in

sNaZZle 1.3
type foo
type bar
type bas
0 0 10 5        foo
20 10 30 20     foo
7 8 12 13       bas
78 124 100 256  bar
end

snail.l

%{
#include <iostream>
using namespace std;
#define YY_DECL extern "C" int yylex()
%}
%%
[ \t\n]         ;
[0-9]+\.[0-9]+  { cout << "Found a float:" << yytext << endl; }
[0-9]+          { cout << "Found an integer:" << yytext << endl; }
[a-zA-Z0-9]+    { cout << "Found a string: " << yytext << endl; }
%%
int main(int argc, char** argv) {
    yylex();
}

commands to compile and run:

Makefile

t:
    bison -d -v snail.y
    flex -o snail.cpp snail.l
    gcc -x c++ snail.tab.c snail.cpp -lstdc++ -lfl

Run:

$ ./a.out < in

2. sample edify script

2.1 typical flow

(!less_than_int(1470971253, getprop("ro.build.date.utc"))) || abort("Can't install this package (Fri Aug 12 11:07:33 CST 2016) over newer build (" + getprop("ro.build.date") + ").");
getprop("ro.product.device") == "anonymous" || abort("This package is for \"anonymous\" devices; this is a \"" + getprop("ro.product.device") + "\".");
ui_print("Target: google/anonymous/anonymous:6.0.1/MASTER/yzyu08121102:userdebug/test-keys");
show_progress(0.750000, 0);
ui_print("Patching system image unconditionally...");
block_image_update("/dev/block/by-name/system", package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat");
ui_print("Verifying the updated system image...");
if range_sha1("/dev/block/by-name/system", "30,0,32770,32825,32827,33281,65535,65536,65538,65992,94567,98304,98306,98361,98363,98817,131071,131072,131074,163840,163842,163897,163899,164353,196607,196608,196610,197064,203177,203178,204788") == "12732a59d40cf97b0374109bdd1971fadfa79124" then
if range_sha1("/dev/block/by-name/system", "32,32770,32825,32827,33281,65535,65536,65538,65992,94567,95079,97792,98304,98306,98361,98363,98817,131071,131072,131074,131586,163328,163840,163842,163897,163899,164353,196607,196608,196610,197064,203177,203178") == "b8c32272d54165b46ba4c727ab8cd062930fab7e" then
ui_print("Verified the updated system image.");
else
  abort("system partition has unexpected non-zero contents after OTA update");
endif;
else
  abort("system partition has unexpected contents after OTA update");
endif;
show_progress(0.050000, 5);
package_extract_file("boot.img", "/dev/block/by-name/boot");
show_progress(0.200000, 10);
sync();
ui_print("Writing fastlogo...");
package_extract_file("fastlogo.img", "/dev/block/by-name/fastlogo");
sync();
ui_print("Writing tzk_normal...");
package_extract_file("tzk_normal.img", "/dev/block/by-name/tzk_normal");
sync();
ui_print("Writing bl_normal...");
package_extract_file("bl_normal.img", "/dev/block/by-name/bl_normal");
sync();
ui_print("Writing bootloader...");
package_extract_file("bootloader.img", "/tmp/bootloader.img");
update_bootloader("/tmp/bootloader.img");
sync();
set_progress(1.000000);

2.2 OTA stages

2.2.1 edify:

ui_print("stage is " + get_stage("/dev/block/mmcblk0p15"));

if (get_stage("/dev/block/mmcblk0p15") == "") then (
    show_progress(0.300000, 5);
    sleep(5);
    set_stage("/dev/block/mmcblk0p15", "2/3");
    reboot_now("/dev/block/mmcblk0p15", "recovery");
) endif;

if (get_stage("/dev/block/mmcblk0p15") == "2/3") then (
    show_progress(0.700000, 5);
    sleep(5);
    set_stage("/dev/block/mmcblk0p15", "3/3");
    reboot_now("/dev/block/mmcblk0p15", "recovery");
) endif;

if (get_stage("/dev/block/mmcblk0p15") == "3/3") then (
    show_progress(0.900000, 3);
    sleep(5);
) endif;

2.2.2 command need to add:

--stages=3