Menu

OTA - android system update in omap4460

1.    Tích hợp chức năng update hệ điều hành bằng Recovery


Mục lục
I.Phân tích code chế độ Recovery



I.                   Phân tích code chế độ Recovery

1.     File chính: recovery.cpp

/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/bootable/recovery/recovery.cpp
·       Chứa hàm main(), thay đổi các biến sau trong hàm main():
const char *update_package = "/cache/update.zip";///////////////////
int wipe_data = 0, wipe_cache = 0, show_text = 1;///////////////
·       Đoạn code thực hiện quá trình update trong lệnh if sau:
if (update_package != NULL)
·        Quá trình update trả về biến trạng thái của quá trình update là biến:  status
·       Nếu quá trình update thành công thì tất cả lệnh if sau đó được bỏ qua, hệ thống tự động khởi động lại.

2.     File chứa các hàm thực hiện quá trình update: install.cpp

/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/bootable/recovery/install.cpp
·       Trong lệnh if đã nêu ở trên là:
if (update_package != NULL)
·       Hàm install_package()  khai báo trong install.cpp được gọi để thực hiện quá trình update.
·        Hàm install-package() tiếp tục gọi hàm really_install_package()
·       Hàm really_install_package() thực hiện kiểm tra RSAPublicKey của file update.zip, đồng thời mở file này lưu nội dung vào 1 biến đệm tên là zip. Sau khi các quá trình trên thành công nó gọi hàm try_update_binary() để thực hiện đọc file update_binary và file update_script trong update.zip.
·       Hàm try_update_binary() chạy file thực thi update_binary và thực hiện update theo kịch bản trong update_script. Sau quá trình update kết thúc, nó trả về kết quả lưu trong biến status đã nói ở trên.

3.     Lưu ý

    Comment đoạn code sau, nó có chức năng chờ thao tác từ người dùng sau khi đã chạy xong kịch bản update trong file update_script

    if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {        prompt_and_wait(device, status);    }

II.               Quá trình tạo file update.zip

1.     Kiến trúc file update.zip

·       Kiến trúc sau được mô tả theo mẫu file update.zip
META-INF/
    +- com/
       +- google/
             +- android/
                   +- update-script
                   +- update-binary
                   +- updater-script
system/
   +- etc/
       +- sysctl.conf
       +- security/
             +- cacerts.bks

·       Nội dung của thư mục META-INF tuân theo thự tự trên và không nên thay đổi.
·       Các file update-script, update-binary,  updater-script cần được đặt trong folder: META-INF/com/google/android/
·       Nội dung file update-script, updater-script được trình bày ở dưới
·       File update-binary nên được lấy từ file:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/out/target/product/blaze_tablet/system/bin/updater
·       Và đổi tên thành update-binary. Nếu không có thể tải trên mạng.
·       Nội dung các file cần update đặt tại thư mục gốc của  file zip
·       Cấu trúc thư mục system có thể thay đổi như ý muốn nhưng cần phải nêu rõ đường dẫn trong file update_script (nên theo chuẩn phân vùng trên EMMC cho đỡ nhầm).

2.     Nội dung file update-script và file updater-script

Nội dung file này được mô tả theo mẫu trong file update.zip
ui_print("Android Security Enhancements.........");
ui_print("Script file is modified by AnhPX..........");

show_progress(1.000000, 0);

ui_print("  Mounting /system................");
mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.1/by-name/system", "/system");
set_progress(0.100000);

ui_print("  Extracting files to /system..............");
package_extract_dir("system", "/system");
set_progress(0.200000);

ui_print("  Setting permissions to 0644..................");
set_perm(0,0,0644,"/system/etc/sysctl.conf","/system/etc/security/cacerts.bks");
set_progress(0.300000);

ui_print("  Unmounting /system.................");
unmount("/system");
set_progress(0.900000);

ui_print("Update complete. Have a safe Android!.....................");
set_progress(1.000000);

·       Nội dung của file này thực hiện mount phân vùng /system trên EMMC, copy các file trong file trong thư mục system của file zip vào phân vùng system trên EMMC.
·       Định nghĩa các lệnh sử dụng trong file này chứa trong file:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/bootable/recovery/updater/install.c
·       Có các hàm sau:
void RegisterInstallFunctions() {
    RegisterFunction("mount", MountFn);
    RegisterFunction("is_mounted", IsMountedFn);
    RegisterFunction("unmount", UnmountFn);
    RegisterFunction("format", FormatFn);
    RegisterFunction("show_progress", ShowProgressFn);
    RegisterFunction("set_progress", SetProgressFn);
    RegisterFunction("delete", DeleteFn);
    RegisterFunction("delete_recursive", DeleteFn);
    RegisterFunction("package_extract_dir", PackageExtractDirFn);
    RegisterFunction("package_extract_file", PackageExtractFileFn);
    RegisterFunction("symlink", SymlinkFn);
    RegisterFunction("set_perm", SetPermFn);
    RegisterFunction("set_perm_recursive", SetPermFn);

    RegisterFunction("getprop", GetPropFn);
    RegisterFunction("file_getprop", FileGetPropFn);
    RegisterFunction("write_raw_image", WriteRawImageFn);

    RegisterFunction("apply_patch", ApplyPatchFn);
    RegisterFunction("apply_patch_check", ApplyPatchCheckFn);
    RegisterFunction("apply_patch_space", ApplyPatchSpaceFn);

    RegisterFunction("read_file", ReadFileFn);
    RegisterFunction("sha1_check", Sha1CheckFn);

    RegisterFunction("wipe_cache", WipeCacheFn);

    RegisterFunction("ui_print", UIPrintFn);

    RegisterFunction("run_program", RunProgramFn);
}

3.     Sử dụng các hàm trong file update_script

·       Đọc file install.cpp để biết thêm chi tiết
·       Chú ý với hàm mount(), định nghĩa của nó như sau:
//mount(fs_type, partition_type, location, mount_point)
//
//    fs_type="yaffs2" partition_type="MTD"     location=partition
//    fs_type="ext4"   partition_type="EMMC"    location=device

location là phân vùng trong EMMC được mount trong qua trình khời động chế độ Recovery. Nó được định nghĩa trong file:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/out/target/product/blaze_tablet/recovery/root/fstab.omap44xxtabletboard
·       Chú ý set permission cho các ứng dụng hoặc thư viện mới cập nhật thì nó mới chạy được. Trong vd trên sử dụng hàm set_perm()

4.     Đăng ký chữ ký số

·       Android yêu cầu ta đăng ký gói cập nhật với 1 chữ ký số.
·       Để đăng ký chứ ký số ta sử dụng file testsign.jar hoặc signapk.jar
(nên sử dụng signapk.jar, cơ hội xác minh giấy phép ký số cao hơn)

4.1   Sử dụng signapk.jar

·       File signapk.jar được build cùng system.img recovery.img, nó trong thư mục:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/out/host/linux-x86/framework/signapk.jar

·       Files testkey.pk8 testkey.x509.pem có trong mã nguồn android. Hai file này được chứa trong thư mục:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/build/target/product/security

·       Đặt các file testkey.pk8  testkey.x509.pem  signapk.jar update.zip cùng 1 thư mục.
·       Chạy lệnh sau:
java -jar signapk.jar -w testkey.x509.pem testkey.pk8 update.zip update_signed.zip

4.2      Sử dụng testsign.apk

·       Đặt file update.zip và file testsign.jar cùng 1 thư mục.
·       Chạy lệnh sau:
java -classpath testsign.jar testsign update.zip update-signed.zip

4.3      Cấu trúc file zip đã được đăng ký.

·       File zip đã đăng ký sẽ có thêm 3 file, kiến trúc của file zip sẽ như sau (mô tả theo mẫu vd trên):
META-INF/
    +- MANIFEST.MF
    +- CERT.SF
    +- CERT.RSA
    +- com/
       +- google/
             +- android/
                   +- update-script
                   +- update-binary
                   +- updater-script
system/
   +- etc/
       +- sysctl.conf
       +- security/
             +- cacerts.bks

·       2 file đầu MANIFEST.MF và CERT.SF chứa hash của tất cả các file trong file zip, còn file CERT.RSA là 1 chứ ký số.

III.            Thực hiện update

·       Bây giờ ta đã có file update.zip của mình, sử dụng lệnh adb push đặt nó vào phân cùng /cache/ trên EMMC
·       Khởi động lại board ở chế độ recovery bằng lệnh:
adb reboot recovery
·       Quá trình update thành công thì board sẽ tự khởi động lại, nếu không thì update thất bại, cần kiểm tra lại file zip.

IV.             Phụ lục

4.1 Giải mã file testkey.x509.pem

·       Chuyển từ testkey.x509.pem sang file code C hoặc file có thể mở đọc được.
·       Sử dụng file dumpkey.jar được chứa trong thư mục:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/out/host/linux-x86/framework/dumpkey.jar
·       File này được build từ file mã nguồn java trong thư mục:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/system/core/libmincrypt/tools/DumpPublicKey.java
·       Đặt file dumpkey.jar và testkey.x509.pem cùng 1 thư mục.
·       Chạy lệnh:
java -jar dumpkey.jar testkey.x509.pem > testkey.x509.c

hoặc:
java -jar dumpkey.jar testkey.x509.pem > testkey.x509.c

·       Nó sẽ xuất ra file testkey.x509.c. So sánh nội dung của file này với file:
/home/anhpx/WORK/tvbox-v2.0-bsp-30/jorjin_bsp/mydroid/out/target/product/blaze_tablet/recovery/root/res/keys

để xác minh ký số.

4.2 Tăng dung lượng phân vùng cache trên EMMC

·       Để lưu trữ được file system.img có dung lượng lớn ta cần ta cần tăng dung lượng phân vùng cache
·       Kích thước ban đầu: 256M
·       Kích thước chỉnh sửa: 512M
·       File chỉnh sửa:
/home/anhpx/WORK/tvbox-v2.0-bsp-50/jorjin_bsp/u-boot/board/omap4430sdp/mmc.c
static struct partition partitions[] = {
                { "-", 128 },
                { "xloader", 128 },
                { "bootloader", 256 },
                /* "misc" partition is required for recovery */
                { "misc", 128 },
                { "-", 384 },
                { "efs", 16384 },
                { "crypto", 16 },
                { "recovery", 8*1024 },
                { "boot", 8*1024 },
                { "system", 512*1024 },
                { "cache", 256*1024 },
                { "userdata", 0},
                { 0, 0 },
};

·       Tham khảo:
/home/anhpx/WORK/tvbox-v2.0-bsp-50/jorjin_bsp/u-boot/board/omap4430panda/mmc.c

static struct partition partitions[] = {

                { "-", 128 },
                { "xloader", 128 },
                { "bootloader", 256 },
                { "-", 512 },
                { "recovery", 8*1024 },
                { "boot", 8*1024 },
                { "system", 512*1024 },
                { "cache", 256*1024 },
                { "userdata", 0},
                { 0, 0 },
};

·       Chưa test




Không có nhận xét nào :

Đăng nhận xét