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 extern void reboot_devices(unsigned reboot_mode);
24 void nv_patch(char * addr, int size)
27 for(i=0; i<FIXNV_SIZE-size; i++){
28 addr[size + i] = 0xff;
31 addr[FIXNV_SIZE + i] = 0x5a;
33 *((unsigned int*)&addr[FIXNV_SIZE - 8]) = size;//keep the real fixnv file size.
36 extern int get_recovery_message(struct recovery_message *out);
37 extern int set_recovery_message(const struct recovery_message *in);
38 int read_update_header_for_bootloader(struct update_header *header)
43 int update_firmware_image (struct update_header *header, char *name)
49 /* Bootloader / Recovery Flow
51 * On every boot, the bootloader will read the recovery_message
52 * from flash and check the command field. The bootloader should
53 * deal with the command field not having a 0 terminator correctly
54 * (so as to not crash if the block is invalid or corrupt).
56 * The bootloader will have to publish the partition that contains
57 * the recovery_message to the linux kernel so it can update it.
59 * if command == "boot-recovery" -> boot recovery.img
60 * else if command == "update-radio" -> update radio image (below)
61 * else -> boot boot.img (normal boot)
64 * 1. the bootloader will attempt to load and validate the header
65 * 2. if the header is invalid, status="invalid-update", goto #8
66 * 3. display the busy image on-screen
67 * 4. if the update image is invalid, status="invalid-radio-image", goto #8
68 * 5. attempt to update the firmware (depending on the command)
69 * 6. if successful, status="okay", goto #8
70 * 7. if failed, and the old image can still boot, status="failed-update"
71 * 8. write the recovery_message, leaving the recovery field
72 * unchanged, updating status, and setting command to
76 * The bootloader will not modify or erase the cache partition.
77 * It is recovery's responsibility to clean up the mess afterwards.
80 int get_mode_from_file(void)
82 struct recovery_message msg;
83 struct update_header header;
84 char partition_name[32];
85 unsigned valid_command = 0;
87 // get recovery message
88 if(get_recovery_message(&msg))
89 return UNKNOW_REBOOT_MODE;
90 if (msg.command[0] != 0 && msg.command[0] != 255) {
91 dprintf("Recovery command: %.*s\n", sizeof(msg.command), msg.command);
93 msg.command[sizeof(msg.command)-1] = '\0'; //Ensure termination
95 if (!strcmp("boot-recovery",msg.command)) {
99 if (!strcmp("update-radio",msg.command)) {
101 strcpy(partition_name, "FOTA");
104 //Todo: Add support for bootloader update too.
107 //We need not to do anything
108 return 0; // Boot in normal mode
111 if (read_update_header_for_bootloader(&header)) {
112 strcpy(msg.status, "invalid-update");
113 goto SEND_RECOVERY_MSG;
116 if (update_firmware_image (&header, partition_name)) {
117 strcpy(msg.status, "failed-update");
118 goto SEND_RECOVERY_MSG;
120 strcpy(msg.status, "OKAY");
123 strcpy(msg.command, "boot-recovery");
124 set_recovery_message(&msg); // send recovery message
126 return UNKNOW_REBOOT_MODE;
129 void recovery_mode(void)
131 printf("%s\n", __func__);
133 #if BOOT_NATIVE_LINUX
134 vlx_nand_boot(RECOVERY_PART, CONFIG_BOOTARGS, BACKLIGHT_ON);
136 vlx_nand_boot(RECOVERY_PART, NULL, BACKLIGHT_ON);
141 #ifdef CONFIG_RAMDISK_BOOT
142 int do_recovery(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
144 puts("Tizen Recovery mode\n");
151 U_BOOT_CMD(recovery, 1, 1, do_recovery,
152 "TIZEN Recovery mode",