3 #include <linux/types.h>
4 #include <asm/arch/bits.h>
6 #include <linux/string.h>
7 #include <android_bootimg.h>
8 #include <linux/mtd/mtd.h>
9 #include <linux/mtd/nand.h>
11 #include <android_boot.h>
12 #include <environment.h>
13 #include <jffs2/jffs2.h>
14 #include <boot_mode.h>
15 #include <android_recovery.h>
20 #define dprintf(fmt, args...) printf(fmt, ##args)
22 void nv_patch(char * addr, int size)
25 for(i=0; i<FIXNV_SIZE-size; i++){
26 addr[size + i] = 0xff;
29 addr[FIXNV_SIZE + i] = 0x5a;
31 *((unsigned int*)&addr[FIXNV_SIZE - 8]) = size;//keep the real fixnv file size.
34 extern int get_recovery_message(struct recovery_message *out);
35 extern int set_recovery_message(const struct recovery_message *in);
36 int read_update_header_for_bootloader(struct update_header *header)
41 int update_firmware_image (struct update_header *header, char *name)
47 /* Bootloader / Recovery Flow
49 * On every boot, the bootloader will read the recovery_message
50 * from flash and check the command field. The bootloader should
51 * deal with the command field not having a 0 terminator correctly
52 * (so as to not crash if the block is invalid or corrupt).
54 * The bootloader will have to publish the partition that contains
55 * the recovery_message to the linux kernel so it can update it.
57 * if command == "boot-recovery" -> boot recovery.img
58 * else if command == "update-radio" -> update radio image (below)
59 * else -> boot boot.img (normal boot)
62 * 1. the bootloader will attempt to load and validate the header
63 * 2. if the header is invalid, status="invalid-update", goto #8
64 * 3. display the busy image on-screen
65 * 4. if the update image is invalid, status="invalid-radio-image", goto #8
66 * 5. attempt to update the firmware (depending on the command)
67 * 6. if successful, status="okay", goto #8
68 * 7. if failed, and the old image can still boot, status="failed-update"
69 * 8. write the recovery_message, leaving the recovery field
70 * unchanged, updating status, and setting command to
74 * The bootloader will not modify or erase the cache partition.
75 * It is recovery's responsibility to clean up the mess afterwards.
78 int get_mode_from_file(void)
80 struct recovery_message msg;
81 struct update_header header;
82 char partition_name[32];
83 unsigned valid_command = 0;
85 // get recovery message
86 if(get_recovery_message(&msg))
87 return UNKNOW_REBOOT_MODE;
88 if (msg.command[0] != 0 && msg.command[0] != 255) {
89 dprintf("Recovery command: %.*s\n", sizeof(msg.command), msg.command);
91 msg.command[sizeof(msg.command)-1] = '\0'; //Ensure termination
93 if (!strcmp("boot-recovery",msg.command)) {
97 if (!strcmp("update-radio",msg.command)) {
99 strcpy(partition_name, "FOTA");
102 //Todo: Add support for bootloader update too.
105 //We need not to do anything
106 return 0; // Boot in normal mode
109 if (read_update_header_for_bootloader(&header)) {
110 strcpy(msg.status, "invalid-update");
111 goto SEND_RECOVERY_MSG;
114 if (update_firmware_image (&header, partition_name)) {
115 strcpy(msg.status, "failed-update");
116 goto SEND_RECOVERY_MSG;
118 strcpy(msg.status, "OKAY");
121 strcpy(msg.command, "boot-recovery");
122 set_recovery_message(&msg); // send recovery message
124 return UNKNOW_REBOOT_MODE;
127 void recovery_mode(void)
129 printf("%s\n", __func__);
131 #if BOOT_NATIVE_LINUX
132 vlx_nand_boot(RECOVERY_PART, CONFIG_BOOTARGS, BACKLIGHT_ON);
134 vlx_nand_boot(RECOVERY_PART, NULL, BACKLIGHT_ON);