Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
bootable_recovery
Commits
928d471e
Commit
928d471e
authored
16 years ago
by
The Android Open Source Project
Browse files
Options
Download
Email Patches
Plain Diff
auto import from //branches/cupcake/...@125939
parent
ff3d9382
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
79 additions
and
24 deletions
+79
-24
recovery.c
recovery.c
+79
-24
No files found.
recovery.c
View file @
928d471e
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <linux/input.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/types.h>
#include <time.h>
#include <time.h>
...
@@ -63,6 +64,48 @@ static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
...
@@ -63,6 +64,48 @@ static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
* --wipe_cache - wipe cache (but not user data), then reboot
* --wipe_cache - wipe cache (but not user data), then reboot
*
*
* After completing, we remove /cache/recovery/command and reboot.
* After completing, we remove /cache/recovery/command and reboot.
* Arguments may also be supplied in the bootloader control block (BCB).
* These important scenarios must be safely restartable at any point:
*
* FACTORY RESET
* 1. user selects "factory reset"
* 2. main system writes "--wipe_data" to /cache/recovery/command
* 3. main system reboots into recovery
* 4. get_args() writes BCB with "boot-recovery" and "--wipe_data"
* -- after this, rebooting will restart the erase --
* 5. erase_root() reformats /data
* 6. erase_root() reformats /cache
* 7. finish_recovery() erases BCB
* -- after this, rebooting will restart the main system --
* 8. main() calls reboot() to boot main system
*
* OTA INSTALL
* 1. main system downloads OTA package to /cache/some-filename.zip
* 2. main system writes "--update_package=CACHE:some-filename.zip"
* 3. main system reboots into recovery
* 4. get_args() writes BCB with "boot-recovery" and "--update_package=..."
* -- after this, rebooting will attempt to reinstall the update --
* 5. install_package() attempts to install the update
* NOTE: the package install must itself be restartable from any point
* 6. finish_recovery() erases BCB
* -- after this, rebooting will (try to) restart the main system --
* 7. ** if install failed **
* 7a. prompt_and_wait() shows an error icon and waits for the user
* 7b; the user reboots (pulling the battery, etc) into the main system
* 8. main() calls maybe_install_firmware_update()
* ** if the update contained radio/hboot firmware **:
* 8a. m_i_f_u() writes BCB with "boot-recovery" and "--wipe_cache"
* -- after this, rebooting will reformat cache & restart main system --
* 8b. m_i_f_u() writes firmware image into raw cache partition
* 8c. m_i_f_u() writes BCB with "update-radio/hboot" and "--wipe_cache"
* -- after this, rebooting will attempt to reinstall firmware --
* 8d. bootloader tries to flash firmware
* 8e. bootloader writes BCB with "boot-recovery" (keeping "--wipe_cache")
* -- after this, rebooting will reformat cache & restart main system --
* 8f. erase_root() reformats /cache
* 8g. finish_recovery() erases BCB
* -- after this, rebooting will (try to) restart the main system --
* 9. main() calls reboot() to boot main system
*/
*/
static
const
int
MAX_ARG_LENGTH
=
4096
;
static
const
int
MAX_ARG_LENGTH
=
4096
;
...
@@ -105,52 +148,64 @@ check_and_fclose(FILE *fp, const char *name) {
...
@@ -105,52 +148,64 @@ check_and_fclose(FILE *fp, const char *name) {
// - the contents of COMMAND_FILE (one per line)
// - the contents of COMMAND_FILE (one per line)
static
void
static
void
get_args
(
int
*
argc
,
char
***
argv
)
{
get_args
(
int
*
argc
,
char
***
argv
)
{
if
(
*
argc
>
1
)
return
;
// actual command line arguments take priority
char
*
argv0
=
(
*
argv
)[
0
];
struct
bootloader_message
boot
;
struct
bootloader_message
boot
;
if
(
!
get_bootloader_message
(
&
boot
))
{
memset
(
&
boot
,
0
,
sizeof
(
boot
));
if
(
boot
.
command
[
0
]
!=
0
&&
boot
.
command
[
0
]
!=
255
)
{
get_bootloader_message
(
&
boot
);
// this may fail, leaving a zeroed structure
LOGI
(
"Boot command: %.*s
\n
"
,
sizeof
(
boot
.
command
),
boot
.
command
);
}
if
(
boot
.
status
[
0
]
!=
0
&&
boot
.
status
[
0
]
!=
255
)
{
if
(
boot
.
command
[
0
]
!=
0
&&
boot
.
command
[
0
]
!=
255
)
{
LOGI
(
"Boot
status
: %.*s
\n
"
,
sizeof
(
boot
.
status
),
boot
.
status
);
LOGI
(
"Boot
command
: %.*s
\n
"
,
sizeof
(
boot
.
command
),
boot
.
command
);
}
}
// Ensure that from here on, a reboot goes back into recovery
if
(
boot
.
status
[
0
]
!=
0
&&
boot
.
status
[
0
]
!=
255
)
{
strcpy
(
boot
.
command
,
"
boot
-recovery"
);
LOGI
(
"Boot status: %.*s
\n
"
,
sizeof
(
boot
.
status
)
,
boot
.
status
);
set_bootloader_message
(
&
boot
);
}
// --- if arguments weren't supplied, look in the bootloader control block
if
(
*
argc
<=
1
)
{
boot
.
recovery
[
sizeof
(
boot
.
recovery
)
-
1
]
=
'\0'
;
// Ensure termination
boot
.
recovery
[
sizeof
(
boot
.
recovery
)
-
1
]
=
'\0'
;
// Ensure termination
const
char
*
arg
=
strtok
(
boot
.
recovery
,
"
\n
"
);
const
char
*
arg
=
strtok
(
boot
.
recovery
,
"
\n
"
);
if
(
arg
!=
NULL
&&
!
strcmp
(
arg
,
"recovery"
))
{
if
(
arg
!=
NULL
&&
!
strcmp
(
arg
,
"recovery"
))
{
*
argv
=
(
char
**
)
malloc
(
sizeof
(
char
*
)
*
MAX_ARGS
);
*
argv
=
(
char
**
)
malloc
(
sizeof
(
char
*
)
*
MAX_ARGS
);
(
*
argv
)[
0
]
=
arg
v0
;
(
*
argv
)[
0
]
=
strdup
(
arg
)
;
for
(
*
argc
=
1
;
*
argc
<
MAX_ARGS
;
++*
argc
)
{
for
(
*
argc
=
1
;
*
argc
<
MAX_ARGS
;
++*
argc
)
{
if
((
arg
=
strtok
(
NULL
,
"
\n
"
))
==
NULL
)
break
;
if
((
arg
=
strtok
(
NULL
,
"
\n
"
))
==
NULL
)
break
;
(
*
argv
)[
*
argc
]
=
strdup
(
arg
);
(
*
argv
)[
*
argc
]
=
strdup
(
arg
);
}
}
LOGI
(
"Got arguments from boot message
\n
"
);
LOGI
(
"Got arguments from boot message
\n
"
);
return
;
}
else
if
(
boot
.
recovery
[
0
]
!=
0
&&
boot
.
recovery
[
0
]
!=
255
)
{
}
else
if
(
boot
.
recovery
[
0
]
!=
0
&&
boot
.
recovery
[
0
]
!=
255
)
{
LOGE
(
"Bad boot message
\n\"
%.20s
\"\n
"
,
boot
.
recovery
);
LOGE
(
"Bad boot message
\n\"
%.20s
\"\n
"
,
boot
.
recovery
);
}
}
}
}
FILE
*
fp
=
fopen_root_path
(
COMMAND_FILE
,
"r"
);
// --- if that doesn't work, try the command file
if
(
fp
==
NULL
)
return
;
if
(
*
argc
<=
1
)
{
FILE
*
fp
=
fopen_root_path
(
COMMAND_FILE
,
"r"
);
if
(
fp
!=
NULL
)
{
char
*
argv0
=
(
*
argv
)[
0
];
*
argv
=
(
char
**
)
malloc
(
sizeof
(
char
*
)
*
MAX_ARGS
);
(
*
argv
)[
0
]
=
argv0
;
// use the same program name
*
argv
=
(
char
**
)
malloc
(
sizeof
(
char
*
)
*
MAX_ARGS
);
char
buf
[
MAX_ARG_LENGTH
];
(
*
argv
)[
0
]
=
argv0
;
// use the same program name
for
(
*
argc
=
1
;
*
argc
<
MAX_ARGS
;
++*
argc
)
{
if
(
!
fgets
(
buf
,
sizeof
(
buf
),
fp
))
break
;
(
*
argv
)[
*
argc
]
=
strdup
(
strtok
(
buf
,
"
\r\n
"
));
// Strip newline.
}
char
buf
[
MAX_ARG_LENGTH
]
;
check_and_fclose
(
fp
,
COMMAND_FILE
)
;
for
(
*
argc
=
1
;
*
argc
<
MAX_ARGS
&&
fgets
(
buf
,
sizeof
(
buf
),
fp
);
++*
argc
)
{
LOGI
(
"Got arguments from %s
\n
"
,
COMMAND_FILE
);
(
*
argv
)[
*
argc
]
=
strdup
(
strtok
(
buf
,
"
\r\n
"
));
// Strip newline.
}
}
}
check_and_fclose
(
fp
,
COMMAND_FILE
);
// --> write the arguments we have back into the bootloader control block
LOGI
(
"Got arguments from %s
\n
"
,
COMMAND_FILE
);
// always boot into recovery after this (until finish_recovery() is called)
strlcpy
(
boot
.
command
,
"boot-recovery"
,
sizeof
(
boot
.
command
));
strlcpy
(
boot
.
recovery
,
"recovery
\n
"
,
sizeof
(
boot
.
recovery
));
int
i
;
for
(
i
=
1
;
i
<
*
argc
;
++
i
)
{
strlcat
(
boot
.
recovery
,
(
*
argv
)[
i
],
sizeof
(
boot
.
recovery
));
strlcat
(
boot
.
recovery
,
"
\n
"
,
sizeof
(
boot
.
recovery
));
}
set_bootloader_message
(
&
boot
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment