[TUTORIAL] Making Flashable ZIPs, EDIFY Script, ZIP Signing & Key Creation [19.01.13]

Search This thread
Apr 4, 2017
286
150
Hey, @wilskywalker, i realize i might be late to the party, but in the op you mention updater binary as being chipset-specific, but what about universal flashable zips? anybody know about this?

Sent from my GT-I9082 using XDA Labs
 

osm0sis

Senior Recognized Developer / Contributor
Mar 14, 2012
16,773
40,451
Halifax
GT-i9250
Google Nexus 4
Hey, @wilskywalker, i realize i might be late to the party, but in the op you mention updater binary as being chipset-specific, but what about universal flashable zips? anybody know about this?

I've talked about it throughout this thread, but that's a bit of hunting now, so, in short, to make a universal zip you need to replace the update-binary with a shell script. Full documentation for replacing EDIFY with shell like this is available in my thread here:

[DEV][TEMPLATE] Complete Shell Script Flashable Zip Replacement + Signing [SCRIPT]

:)
 
Apr 4, 2017
286
150
I've talked about it throughout this thread, but that's a bit of hunting now, so, in short, to make a universal zip you need to replace the update-binary with a shell script. Full documentation for replacing EDIFY with shell like this is available in my thread here:

[DEV][TEMPLATE] Complete Shell Script Flashable Zip Replacement + Signing [SCRIPT]

:)
Really don't recognise me or was that for posterity? LOL... But Thanks again:)
 

Ticklefish

Inactive Recognized Themer
Oct 27, 2011
6,773
8,633
Hampshire, UK
Hiya folks, I hope you can help.

I'm trying to make a generic ZIP for flashing deodexed files. What I want to be able to do is have a chunk of code that will delete a folder on the phone only if the same folder exists in the ZIP. That way the ZIP can have any combination of folders in it but will only act on the ones that it actually has.

It seems that I'm going to need the "ifelse" command and I was thinking of doing something like this:

Code:
ifelse(package_extract_dir("system/app", "/system/app") == "t",
(
    delete ("system/app");
    package_extract_dir("system/app","/system/app");
),
(
    ui_print(" ");
)
);

The idea is that the phone tries to copy the contents of "system/app" from the ZIP onto the phone. If it fails, nothing happens. If it succeeds, it deletes the entire system/app folder and does it again.
Doing the package extract twice seems a little redundant to me but I can't see a better way of doing it.

I'm quite new to using conditions in my updater scripts - up until a few minutes ago, I didn't know you could! So my question is, would this work and is there a better more efficient way of doing it?
 

lebigmac

Account currently disabled
Jan 31, 2017
1,342
995
How can I ui_print in a different color? For example in red? Thanks!
I tried ui_error but no such command!
 

vp1117

Senior Member
Jan 30, 2019
85
12
Hi, does anybody know what these functions do:

Code:
msm.boot_update("main")
msm.boot_update("backup")
msm.boot_update("finalize")

??
 

Top Liked Posts

  • There are no posts matching your filters.
  • 123
    [TUTORIAL] Making Flashable ZIPs, EDIFY Script, ZIP Signing & Key Creation [19.01.13]

    Recent Updates: Command Line Edify Script Tester, Further 'update-binary' info clarification, helpful links, additional credits. post#1

    Hi all,

    In the process of creating my [BOOTANIMATIONS - LINKS & INFO] thread I realised I needed to know more about how boot animations worked, as by default people tend to ask questions in that type of thread, so I wanted to be able to help.

    This meant I came across the problem of creating flash-able ZIP files and Edify scripting and in the interests of sharing and helping this great community I would like to share what I have found and hopefully learn more through discussion, I certainly am no expert and am always willing to learn.

    I have checked xda and various other websites whilst reseraching for this post and there is nothing that really explains all the basic concepts to just get up and running, also a lot of threads are quite old and focus on the old Amend scripting syntax or are a confusing mixture of the two.

    I hope this helps people get started and that we can all collaborate to make this a thread a source of valuable information.

    Contents:

    Post #1: Tutorials
    Post #2: Edify Commands


    ***Please, if there are any mistakes on this thread then let me know what I have done incorrectly in reply to this post and I will update the thread to correct it***

    ***As always, I accept no responsibiltiy for your handset, you modify it at your own risk, nobody is forcing you...be aware you can seriously bork your phone by flashing its internal partitions! Always make a nandroid back-up and think before you flash!***

    ***Have you made a nandroid back-up...no? Then make one!!***

    You will need the following:

    Android SDK, ADB & Fastboot set up for your handset.
    Notepad++ [LINK]
    7zip [LINK]

    Setting up your zip directories:

    you will need to create the following folder structure (these are case sensitive):

    Code:
    /META-INF/com/google/android

    All flash-able zips include this file structure, the final folder 'android' will contain two files:

    Code:
    update-binary
    updater-script

    update-binary: I have been unable to find much information on the update-binary file other than they seem to be chip set specific (if anyone can shed further light on these I will include it here). For the sake of compatibility I have attached the update binary from the latest CyanogenMod Nightlies for the maguro at the bottom of this thread - You can of course download the latest nightly and extract the update-binary file yourself as the attached one will obviously begin to date (all credit to the great devs at CyanogenMod for this, many thanks).

    Update: For more detailed info on the update binary you can find the sources in the bootable/recovery/updater directory at AndroidXRef here: [ xref: /bootable/recovery/updater/ ]. There is also an edify directory which looks like it handles the parsing of the script. Obviously with the sources there's nothing to stop you extending syntax/functionality should you wish given the fact the each zip comes with its own version. It will also help you understand how signature checking is handled.

    Update II: For anybody having problems flashing it is worth ensuring you have an up to date version of the update-binary (obviously the one attached to this thread will gradually become out of date).

    It is advisable to use the update-binary from the latest OTA image for your device, these images can be found in the following link:

    Official Google OTA update URLs - efrant


    updater-script: This we can create ourselves, to ensure it works properly we will use Notepad++.

    Open Notepad++ and start a new file, with the following settings:

    Format: Unix
    Encoding: ANSI
    Default Language: Normal Text

    Save this file as:

    File name: updater-script
    File type: All types (*.*)

    You can now edit this file, add the following text:

    Code:
    [COLOR="Red"]assert(getprop("ro.product.device") == "maguro" || getprop("ro.build.product") == "maguro");[/COLOR]
    [COLOR="Green"]ui_print(" ");[/COLOR]
    [COLOR="green"]ui_print("confirming device maguro");[/COLOR]
    [COLOR="green"]ui_print(" ");[/COLOR]
    [COLOR="green"]ui_print("success");[/COLOR]
    [COLOR="green"]ui_print(" ");[/COLOR]
    [COLOR="DarkOrange"]show_progress(0.200000, 5);[/COLOR]
    [COLOR="green"]ui_print("mounting system");[/COLOR]
    [COLOR="red"]mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system");[/COLOR]
    [COLOR="green"]ui_print(" ");[/COLOR]
    [COLOR="DarkOrange"]show_progress(0.200000, 5);[/COLOR]
    [COLOR="green"]ui_print("updating system files");[/COLOR]
    [COLOR="red"]package_extract_dir("system", "/system");[/COLOR]
    [COLOR="green"]ui_print(" ");[/COLOR]
    [COLOR="DarkOrange"]show_progress(0.200000, 5);[/COLOR]
    [COLOR="green"]ui_print("unmounting system");[/COLOR]
    [COLOR="red"]unmount("/system");[/COLOR]
    [COLOR="green"]ui_print(" ");[/COLOR]
    [COLOR="DarkOrange"]show_progress(0.200000, 5);[/COLOR]
    [COLOR="green"]ui_print("by yourusername");[/COLOR]
    [COLOR="DarkOrange"]show_progress(0.200000, 5);[/COLOR]
    [COLOR="green"]ui_print(" ");[/COLOR]
    ***EMPTY LINE***

    Ok, I've colour coded this so we can break it down, the lines of code in RED are the actual commands, everything else is cosmetic.

    assert(getprop("ro.product.device") == "maguro" || getprop("ro.build.product") == "maguro"); This is checking you are flashing the correct handset, this is not a requirement, but is best practice. Just insert another device name in the place of "maguro" if you so wish, or remove the command all together.

    mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system"); This is the specific mount point for the maguro system partition, if you wish to flash a different partition, data for instance you can get the mount points for your device by entering the following code over ADB:

    Code:
    adb shell "mount > /sdcard/PHONENAME_mountinfo.txt"
    This will place a text file on your sdcard with the mount points for your specific device (remember to swap 'PHONENAME' with your device name e.g. 'maguro')

    package_extract_dir("system", "/system"); This command extracts the files you wish to flash from the zip and flashes them to the phone, it is formatted as follows ("package-path", "/destination-path"). So for this example you are telling it to flash everything from the 'system' folder in your zip to the /system partition of your handset. You can obviously change these values for different partitions.

    unmount("/system"); This simply unmounts whatever partition you previously mounted.

    ui_print(" "); Shows text in the recovery whilst the flash is ongoing, you can put whatever you please between the speech marks, you must leave a space if you wish to have a blank line.

    show_progress(0.200000, 5); Controls what the progress bar in the background is displaying, it is formatted as follows (fragment, seconds).

    ***EMPTY LINE*** This is not actually text, you simply need to leave a blank line at the end of your script before you save it for it to work.

    FYI, this means in fact your script could look like this and still work:

    Code:
    [COLOR="Green"]ui_print(" ");[/COLOR]
    [COLOR="DarkOrange"]show_progress(1.000000, 30);[/COLOR]
    [COLOR="red"]mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system");[/COLOR]
    [COLOR="red"]package_extract_dir("system", "/system");[/COLOR]
    [COLOR="red"]unmount("/system");[/COLOR]
    [COLOR="Green"]ui_print(" ");[/COLOR]
    ***EMPTY LINE***

    But that just isn't that pretty, or as deceptively complicated lol! :D

    Make sure you save your edify script.

    Files to flash:

    You now need to create a further folder, this needs to be named based on where within the system you are flashing, for the sake of this example we are flashing to the system partition, so:

    Code:
    /META-INF/com/google/android
    /system/app

    Place whatever files you wish to flash within this file e.g:

    Code:
    /META-INF/com/google/android
    /system/app/nameofapp.apk

    Creating your .zip file:

    Select both of your top directories and their contents 'META-INF' and 'system' and package them into a .zip file with 7zip using the following settings:

    Archive: name_of_your_file
    Archive Format: zip
    Compression level: Store
    Update mode: Add and replace files

    And there you have it, your very own flash-able .zip file.

    I have attached an example flashable .zip file that includes this updater-script and the above mentioned CM update-binary.

    How to sign your update.zip:

    You don't actually need to sign your zip file for it to work as most custom recoveries now support unsigned zips, for aspiring developers and the more cautious among us though, here is how.

    You will need to download the following files:

    SignApk [LINK]
    Java JDK (Java Development Kit) & JRE (Java Runtime Environment) [LINK]

    Install Java JRE and JDK and restart your PC.

    You then need to create a folder in the root of your c:\ drive named 'signapk' and extract the contents of the SignApk download (signapk.jar, key.pk8, certificate.pem) to this folder.

    Place your .zip file into the same folder and then open cmd line. Input the following commands (remeber to change the name of 'myupdate.zip' to the name of your file and 'myupdate-signed.zip' to whatever you want your resulting .zip to be named):

    Code:
    cd\signapk\
    java -jar signapk.jar certificate.pem key.pk8 c:\signapk\myupdate.zip myupdate-signed.zip

    You should find that you now have the the following files in your 'META-INF' folder: CERT.RSA, CERT.SF, MANIFEST.MF

    This can also to be used to sign .apk files using the below command (same stipulations for file name changing applies as above):

    Code:
    java -jar signapk.jar certificate.pem key.pk8 c:\signapk\myapplication.apk myapplication-signed.apk

    How to create your own private signing key & certificate:

    You will need the following download:

    OpenSSL [LINK]

    The above signapk file includes test keys, if you want to create your own private keys for signing, here's what you need to do.

    As before extract the OpenSSL files to a folder in the root of your c:\ drive, preferably named 'openssl' for ease of cmd line navigation. Then input the following:

    Code:
    cd\openssl\
    openssl genrsa -out key.pem 1024
    openssl req -new -key key.pem -out request.pem
    openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem
    openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocrypt

    You can then replace 'key.pk8' & 'certificate.pem' with your own files.

    I really hope this has helped folks out, if so please consider hitting the 'Thanks' button!

    Happy flashing!

    :D

    Testing your script before you flash:

    If you would like to test if your script commands are valid and will run properly on your PC first before you use them on your handset, therefore removing the fear of borking your current install/handset in the process then head to this post:

    Command Line Edify Script Tester by: trevd

    This great tool developed by trevd currently has the following features:

    Validates function name.
    Validates function parameter count.

    It is available for Linux and Windows, so head over and check it out. Be sure to click trevd's thanks button if you find this useful.

    Other helpful links & threads:

    xda-developers: Edify script language wiki
    Edify scripts in CWM recovery by: NFHimself
    Phandroid - Edify Script Language Reference by: Koumajutsu
    Introduction to edify updater script by: kurotsugi
    Intelligent EDIFY updater-script - (Decides things during flash) by: lotherius

    Credits:

    CyanogenMod for (update-binary)
    Lorenz's Blog for (SignAPK & Info)
    JoeSyr for (Help with File Permissions)
    efrant for (Help with various commands)
    trevd for (further update-binary clarification and source links)
    osm0sis for (Helpful info & forum links & help with update-binary info)
    73
    Edify Scripting Commands

    I would like to try and put together a guide to Edify scripting commands and what their function is to compliment my above tutorial, I hope again we can all collaborate to make this a helpful source of information to all budding devs...we all have to start somewhere right!?

    ***Please, if there are any mistakes in this post or if you can help by adding further info please post below, thanks***

    Ok...

    Check you are flashing the correct device:

    Code:
    assert(getprop("ro.product.device") == "maguro" || getprop("ro.build.product") == "maguro" || getprop("ro.product.board") == "maguro");

    This will check your device is showing the correct name in the build.prop, in this case "maguro", you can obviously replace this with your device name.

    To explain this a little further, you have told the script to check certain properties within your 'build.prop' file located in your /system folder. The above command ensures the following categories have the correct definitions before proceeding with the flash:
    Code:
    ro.product.device=
    ro.build.product=
    ro.product.board=

    Here are the main build properties within your build.prop:

    Code:
    ro.build.id=
    ro.build.display.id=
    ro.build.version.incremental=
    ro.build.version.sdk=
    ro.build.version.codename=
    ro.build.version.release=
    ro.build.date=
    ro.build.date.utc=
    ro.build.type=
    ro.build.user=
    ro.build.host=
    ro.build.tags=
    ro.product.model=
    ro.product.brand=
    ro.product.name=
    ro.product.device=
    ro.product.board=
    ro.product.cpu.abi=
    ro.product.cpu.abi2=
    ro.product.manufacturer=
    ro.product.locale.language=
    ro.product.locale.region=
    ro.wifi.channels=
    ro.board.platform=
    ro.build.description=
    ro.build.fingerprint=
    ro.build.characteristics=
    ro.cm.device=


    Print text in the recovery during flashing process:

    Code:
    ui_print("Your text here");
    Code:
    ui_print(" ");

    This simply prints a line of text in the recovery, it has no actual effect on the flashing process, if you want a blank line just leave a blank space as the second example.

    Controlling the progress bar:

    I believe I understand this correctly, if not please do post below with further clarification.

    Code:
    show_progress(0.000000, 0);
    or
    Code:
    set_progress(0.000000);

    You have two choices when controlling the progress bar, the first example allows you to define fractions of the progress bar and how long they will take to fill. The second example just allows you to specify that the bar fills to a certain fraction at whatever point during the flashing process.

    The command is defined as: (progress bar fraction, duration in seconds to fill defined fraction);

    For example the following code lines interspersed with your other commands would fill a fifth of the progress bar every five seconds:

    Code:
    show_progress(0.200000, 5);
    ui_print(" ");
    show_progress(0.200000, 5);
    ui_print(" ");
    show_progress(0.200000, 5);
    ui_print(" ");
    show_progress(0.200000, 5);
    ui_print(" ");
    show_progress(0.200000, 5);

    This process will only complete if the script takes long enough to flash, therefore you need to be aware of what you are actually flashing and how long it will take when defining these values.

    If you wish to just define a fraction without fill without a time scale you can use the following command:

    Code:
    set_progress(0.000000);

    It is also best practice to include this element in your scripts as it will reassure people that their handset hasn't frozen during a flash.

    Mount/Unmount a partition:

    To mount a partition you need to use the following syntax:

    Code:
    mount("filesystem-type", "partition-type", "device-specific-location", "mount-point");

    filesystem-type: "ext4" or "yaffs2" (maguro is ext4)
    partition-type: "EMMC" or "MTD" (maguro is EMMC)
    location: Device specific address
    mount-point: /system etc

    So far I have managed to define the following Maguro specific mount points:

    Code:
    "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system"
    "/dev/block/platform/omap/omap_hsmmc.0/by-name/userdata", "/data"
    "/dev/block/platform/omap/omap_hsmmc.0/by-name/cache", "/cache"
    "/dev/block/platform/omap/omap_hsmmc.0/by-name/efs" "/factory"
    "/dev/block/platform/omap/omap_hsmmc.0/by-name/userdata", "/mnt/sdcard"
    "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot"

    Example command would be:

    Code:
    mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system");

    I have taken these mount points from the file output by the maguro when you enter the following adb command:

    Code:
    adb shell "mount > /sdcard/maguro_mountinfo.txt"

    I have to admit I am a little in the dark about the "/factory" partition, any info would be greatly appreciated!

    To unmount a partition you need to input the following command:

    Code:
    unmount("/system");

    Obviously replace the mount partition with whatever partition you are working in.

    Format a partition:

    To format a partition you need to use the following syntax:

    Code:
    format("filesystem-type", "partition-type", "device-specific-location", "0");

    Example:

    Code:
    format("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "0");

    Some scripts include the "0" and some do not, not sure exactly on the function difference when included or not, again clarification would be great.

    Flashing the contents of your ZIP file:

    To flash an entire directory:

    Code:
    package_extract_dir("system", "/system");

    To flash a single file:

    Code:
    package_extract_file("boot.img", "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");

    These commands are structured as follows:

    Entire directory: ("zipfileSource", "destination-partition");
    Single File: ("file", "device-specific-mountpoint");

    Deleting folders & files:

    You can delete multiple folders or files using just one command, as follows:

    To delete files:

    Code:
    delete("file-path-1", "file-path-2", "file-path-3);

    To delete folders/directories:

    Code:
    delete_recursive("directory-path-1", "directory-path-2", "directory-path-3");

    Setting Permissions

    Here are the basics for setting permissions.

    If you want to research the reasons behind this, there is some useful information on Linux permissions here: chmod wiki, linuxquestions.org linux wiki.

    Thanks to JoeSyr for his input and help understanding this section of the tutorial.


    Set permissions of a file or set of files:

    Code:
    set_perm(uid, gid, mode, "filepath1", "filepath2")
    Example:
    Code:
    set_perm(0, 0, 06755, "/system/xbin/su");
    uid - user id
    gid - group id
    mode - permission mode
    filepath... - file to set permission on

    Set permissions of a directory or set of directories and all files and folders within them:

    Code:
    set_perm_recursive(uid, gid, dirmode, filemode, "dirpath1", "dirpath2")
    Example:
    Code:
    set_perm_recursive(0, 0, 0755, 0644, "/system");
    uid - user id
    gid - group id
    dirmode - permission to set to directories contained within the specified directory
    filemode - permission to set to files contained within the specified directory
    dirpath... - directory to set permission on

    Permissions syntax explained...so I can understand it lol (if I do then anyone can!):

    The following are the pre-defined Android UID's & GID's. Taken from the following link: Android UIDs and GIDs

    Code:
    AID_ROOT             0  /* traditional unix root user */
    
    AID_SYSTEM        1000  /* system server */
    AID_RADIO         1001  /* telephony subsystem, RIL */
    AID_BLUETOOTH     1002  /* bluetooth subsystem */
    AID_GRAPHICS      1003  /* graphics devices */
    AID_INPUT         1004  /* input devices */
    AID_AUDIO         1005  /* audio devices */
    AID_CAMERA        1006  /* camera devices */
    AID_LOG           1007  /* log devices */
    AID_COMPASS       1008  /* compass device */
    AID_MOUNT         1009  /* mountd socket */
    AID_WIFI          1010  /* wifi subsystem */
    AID_ADB           1011  /* android debug bridge (adbd) */
    AID_INSTALL       1012  /* group for installing packages */
    AID_MEDIA         1013  /* mediaserver process */
    AID_DHCP          1014  /* dhcp client */
    
    AID_SHELL         2000  /* adb and debug shell user */
    AID_CACHE         2001  /* cache access */
    AID_DIAG          2002  /* access to diagnostic resources */
    
    /* The 3000 series are intended for use as supplemental group id's only. */
    /* They indicate special Android capabilities that the kernel is aware of. */
    AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */
    AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap sockets */
    AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */
    AID_NET_RAW       3004  /* can create raw INET sockets */
    
    AID_MISC          9998  /* access to misc storage */
    AID_NOBODY        9999
    
    AID_APP          10000 /* first app user */
    
    "root",      AID_ROOT
    "system",    AID_SYSTEM
    "radio",     AID_RADIO
    "bluetooth", AID_BLUETOOTH
    "graphics",  AID_GRAPHICS
    "input",     AID_INPUT
    "audio",     AID_AUDIO
    "camera",    AID_CAMERA
    "log",       AID_LOG
    "compass",   AID_COMPASS
    "mount",     AID_MOUNT
    "wifi",      AID_WIFI
    "dhcp",      AID_DHCP
    "adb",       AID_ADB
    "install",   AID_INSTALL
    "media",     AID_MEDIA
    "shell",     AID_SHELL
    "cache",     AID_CACHE
    "diag",      AID_DIAG
    "net_bt_admin", AID_NET_BT_ADMIN
    "net_bt",    AID_NET_BT
    "inet",      AID_INET 
    "net_raw",   AID_NET_RAW
    "misc",      AID_MISC
    "nobody",    AID_NOBODY

    You will need to also understand the way file permissions are represented:

    Example = drwxrwxrwx

    -Use Root Explorer to find the UID, GID, and permissions for a file. Permissions are the string that looks like some variation on 'rwxr-xr--' next to each file. Long press and choose "change owner" to get the UID and GID. You just want the number next to "owner" and "group", respectively.

    -If you're replacing a file, look up these settings for the existing copy and use them. If you're adding a file, just find a file that does the same functions and copy what it has (for example, installing an app to /system/app? Just look at these settings for any other app in that directory).

    -MODE is technically a 4-bit string, but the first character can be omitted. There doesn't seem to be any android file permissions with the first character set. For good practice, I think it's safe to assume you can always use a leading 0 unless you know otherwise for something specific. Or, just use a 3-digit MODE, which says to leave those settings as they are (disabled by default). (I.e. 0644=644).

    The next 9 characters define the file permissions. These permissions are
    given in groups of 3 each.

    The first 3 characters are the permissions for the owner of the file or directory.
    Example = -rwx------

    The next 3 are permissions for the group that the file is owned by.
    Example = ----rwx---

    The final 3 characters define the access permissions for everyone not part of the group.
    Example = -------rwx

    There are 3 possible attributes that make up file access permissions.

    r - Read permission. Whether the file may be read. In the case of a
    directory* this would mean the ability to list the contents of the
    directory.

    w - Write permission. Whether the file may be written to or modified. For
    a directory* this defines whether you can make any changes to the contents
    of the directory. If write permission is not set then you will not be able
    to delete* rename or create a file.

    x - Execute permission. Whether the file may be executed. In the case of a
    directory* this attribute decides whether you have permission to enter*
    run a search through that directory or execute some program from that
    directory

    You set these permissions using the following binary based numerical system:
    Code:
    0:  ---   No Permissions (the user(s) cannot do anything)
    1:  --x   Execute Only (the user(s) can only execute the file)
    2:  -w-   Write Only (the user(s) can only write to the file)
    3:  -wx   Write and Execute Permissions
    4:  r--   Read Only
    5:  r-x   Read and Execute Permissions
    6:  rw-   Read and Write Permissions
    7:  rwx   Read, Write and Execute Permissions

    Default Linux permissions:

    For Files:
    "Read" means to be able to open and view the file
    "Write" means to overwrite or modify the file
    "eXecute" means to run the file as a binary

    For Directories:
    "Read" means to be able to view the contents of the directory
    "Write" means to be able to create new files/directories within the directory
    "eXecute" means to be able to "Change Directory" (cd) into the directory
    Most of the time you set "Read" and "eXecute" together on directories (kind of useless when set by themselves)


    Interestingly through further research it seems this system is based on the Octal Binary system...I may be wrong...
    Code:
    Octal
    
    Binary is also easily converted to the octal numeral system, since octal uses a radix of 8, which is a power of two (namely, 23, so it takes exactly three binary digits to represent an octal digit).
    The correspondence between octal and binary numerals is the same as for the first eight digits of hexadecimal in the table above.
    Binary 000 is equivalent to the octal digit 0, binary 111 is equivalent to octal 7, and so forth.
    
    Octal	Binary
    0	000
    1	001
    2	010
    3	011
    4	100
    5	101
    6	110
    7	111
    
    Converting from octal to binary proceeds in the same fashion as it does for hexadecimal:
    658 = 110 1012
    178 = 001 1112
    And from binary to octal:
    1011002 = 101 1002 grouped = 548
    100112 = 010 0112 grouped with padding = 238
    And from octal to decimal:
    658 = (6 × 81) + (5 × 80) = (6 × 8) + (5 × 1) = 5310
    1278 = (1 × 82) + (2 × 81) + (7 × 80) = (1 × 64) + (2 × 8) + (7 × 1) = 8710

    Flash boot partition

    This uses the following command but with some caveats:
    Code:
    write_raw_image("path to boot.img", "boot");

    An example of this commands use would be to flash a custom kernel, as far as I can tell though you need to place the boot.img in a temp file before the actual flash (clarification on this would be helpful). You would therefore use the following commands as part of your edify script:
    Code:
    package_extract_file("boot.img","/tmp/boot.img");
    write_raw_image("/tmp/boot.img", "device-specific-boot-partition-mount-point");
    delete("/tmp/boot.img");

    It seems this may only be for specific handsets though e.g HTC, having looked through quite a few updater-script files from maguro zips it seems this can just be flashed directly with the following command:
    Code:
    package_extract_file("boot.img", "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");

    Many thanks for further clarification on this particular command from efrant below:

    I feel more comfortable using something like this:
    Code:
    package_extract_file("boot.img", "/tmp/boot.img");
    run_program("/sbin/busybox", "dd", "if=/tmp/radio.img", "of=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");
    delete("/tmp/boot.img")

    The second line is using the "dd" command to flash the image.

    The dd command (included in busybox) is:
    Code:
    dd if=xxx of=yyy

    where xxx is the source image/partition and yyy is the target image/partition. So, for example, to flash a radio image stored in /sdcard called xxlf1.img to a GNex, it would be:
    Code:
    busybox dd if=/sdcard/xxlf1.img of=/dev/block/platform/omap/omap_hsmmc.0/by-name/radio (I've added "busybox" the the beginning, just to be explicit.)

    So, to put it in edify format, it becomes:
    Code:
    run_program("/sbin/busybox", "dd", "if=/sdcard/xxlf1.img", "of=/dev/block/platform/omap/omap_hsmmc.0/by-name/radio");

    However, as I said, I believe your one line:
    Code:
    package_extract_file("boot.img", "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");

    would work.

    Further Commands:

    In progress...


    So, this is by no means an exhaustive list and I would appreciate it that if I have made any mistakes people make me aware in this thread and I can update this tutorial.

    I would also like to add further commands and their uses, if people can provide more I will add them too.

    I hope this helps people out! Many thanks!

    :D
    28
    Hi Folks ( Again )

    I figured that I just couldn't throw the idea of a test app out there and not do anything about it :) ,

    So I did a little hacking around with the updater-binary code and stripped everything out apart from the script-parsing and validation and I like to introduce the edify_checker v0.1 ( Not Even Close To BETA ).

    Feature's:
    Validates function name.
    Validates function parameter count.

    And that's it, for the moment but I figured it was something to be going on with.....

    I've built a windows version and linux version, I tested the windows one on a win7 vm. It's a command line app, so windows users, do whatever you do to run command line applications! :D

    Usage : edify_checker <path_to_updater-script>

    Example outputs:

    1 Invalid Argument Code
    Code:
    C:\Users\test>edify_checker.exe c:\users\test\updater-script
    edify syntax checker v0.1
    Opening Script File:c:\users\test\updater-script        File size:1711 bytes
    validating function names
    validating function parameters
    script aborted: ui_print() expects at least 1 arg, got 0

    2 Unknown Function Name
    Code:
    test@test:/home/test $ ./edify_checker /home/test/scripts/updater-script
    edify syntax checker v0.1
    Opening Script File:upater-script	File size:1887 bytes
    validating function names
    line 3 col 35: unknown function "uiprint"
    1 parse errors

    3. Parsed Successfully
    Code:
    edify syntax checker v0.1
    Opening Script File:upater-script	File size:1887 bytes
    validating function names
    validating function parameters
    script result was []

    As I mentioned this is still a very early build, I've got a couple of ideas of where I can take this to feature wise but I'd be open to suggestion, feature ideas etc.

    I think being able to simulate different device environments would be useful, i.e mount points, build properties , disk sizes etc, basically any variables which affect how an update executes.......

    Finally Here's the link to the github source tree, https://github.com/trevd/android_external_edify_checker, if anyone wants to get involved.
    7
    Hi Folks.

    Figure I may as well share this cheeky little number I was playing around with

    Code:
    package_extract_dir("bin","/tmp");
    package_extract_dir("patches","/tmp");
    set_perm(0, 0, 0755, "/tmp/busybox");
    set_perm(0, 0, 0755, "/tmp/unpack-bootimg");
    set_perm(0, 0, 0755, "/tmp/mkbootimg");
    set_perm(0, 0, 0755, "/tmp/cpio-ramdisk.sh");
    set_perm(0, 0, 0755, "/tmp/cpio-pack-ramdisk.sh");
    run_program("/tmp/busybox", "dd", "if=/dev/block/mmcblk0p2", "of=/tmp/boot.img");
    run_program("/tmp/unpack-bootimg", "-i","/tmp/boot.img","-o","/tmp");
    run_program("/tmp/busybox", "gunzip","-d", "/tmp/ramdisk.cpio.gz");
    run_program("/tmp/busybox", "mkdir","/tmp/ramdisk");
    run_program("/tmp/cpio-ramdisk.sh", "/tmp/ramdisk","/tmp/ramdisk.cpio");
    run_program("/tmp/busybox", "patch","-p1","-i","/tmp/default.prop.patch","/tmp/ramdisk/default.prop");
    run_program("/tmp/busybox", "patch","-p1","-i","/tmp/ueventd.grouper.rc.patch","/tmp/ramdisk/ueventd.grouper.rc");
    run_program("/tmp/cpio-pack-ramdisk.sh", "/tmp/ramdisk","/tmp/new-ramdisk.cpio.gz");
    run_program("/tmp/mkbootimg", "--ramdisk","/tmp/new-ramdisk.cpio.gz","--kernel","/tmp/kernel","-o","/tmp/newboot.img");
    run_program("/tmp/busybox", "dd", "of=/dev/block/mmcblk0p2", "if=/tmp/newboot.img");

    This script demonstrates an on device method of updating the boot image ramdisk' while leave the kernel untouched, it uses standard patch files.
    The main gain here is if folks are using custom kernels they can still apply the update without too much fuss.

    [ devhost ] | [goo.im]
    Here is an example which applies the insecure boot image patch to the nexus-7 grouper ramdisk , feel free to reuse the binaries for you own evil deeds! :laugh:

    This being said I wouldn't be surprised if the apply_patch edify function is doing something similar with the .p files It's probably something we should get an handle on because that may well do in one line what I've demonstrated here, I think there some code and tools in the AOSP source tree which create will create ota's given 2 update zips, I see if I can find some documentation on it. :good:
    5
    That seems like a great idea, it would be a really useful tool for people learning what all the commands do without worrying about borking their phone in the test process!!

    Well I did make a little progress as I had an impending need to test an update script. so I set myself up a cheeky schroot on my linux install and hacked it a bit to run the android sh command ( compiled for x86, obviously) as it's login shell. This gave me a clean root tree to test with on my desktop....

    Obviously this is a Linux only solution, but It does the job of testing pretty well. Somewhat bizzarely, given my contributions to this thread, I rarely do anything with edify and update zips so my personal motivation to go any further isn't that great, I'm not seeking any glory ( or support burden ) that goes with releasing and maintaining these sort of tools. I'm just not that dev. :D , this was more just something I thought about while having a cig under the stars LOL If you're using window, however , I'll look into a windows compatible version of the updater binary, just let me know, although I make no promises. It could probably be combined with cygwin or someone could take the reins with a .Net UI wrapper or whatever.

    As a little christmas treat I've attached the contents recovery based ramdisk for x86, contains busybox, a statically linked version of androids toolbox, the updater and cwm recovery. The contents can be used in combination with an x86 android kernel and grub2,

    The binaries are also good to go on any linux installation that supports executing 32bit binaries. Just for sh*ts and giggles you can even run full cwm from within linux :laugh: Basically you just need to make the framebuffer device in the right location

    sudo mkdir /dev/graphics
    sudo mknod /dev/graphics/fb0 c 29 0 # makes a framebuffer that cwm wants
    sudo <path to recovery>

    You need the /res directory in your rootfs and this will wipeout your /etc/fstab ( it back's it up to /etc/fstab~ ), which is not good if you've not chroot'd

    Anyway I digress, but I thought I share this bit a hackery nonesense. :good: