How does the reboot into recovery mode work?

3,149 views
Skip to first unread message

Bjarke F.

unread,
Mar 30, 2011, 4:58:00 AM3/30/11
to android-porting
Hi,

When I perform a "adb reboot recovery" my device restarts, and the
bootloader then starts the kernel with the root option set to the
special recovery root file system.

How does the running linux system tell the boot loader to do this
after the reboot?

Chinmay S

unread,
Mar 30, 2011, 8:59:19 AM3/30/11
to bjar...@gmail.com, android-porting
Hi Bjarke,

When the kernel reboots into recovery-mode, its a warm-reset.
(NOT a cold-reset where contents of ALL registers are lost.)

Before warm-reboot, the kernel sets a particular register to a specify value
(the value in this register is retained even after a warm-reset.)

The bootloader just reads this register as part of it boot-up routine
and upon finding the specific recovery value, starts the kernel and
points it to the recovery-fs this time as you rightly identified.

The exact register used may vary in different architectures/devices.

Regards
CVS

Bjarke Freund-Hansen

unread,
Mar 30, 2011, 11:58:30 AM3/30/11
to Chinmay S, android...@googlegroups.com
Hi CVS

Thanks a lot for your explanation. Do you have any pointer for where
in the source I should look for this functionality?

Specifically I have been looking at the source for adb which seems to
call the __reboot syscall with "recovery" as a parameter. But nowhere
in the Android Linux kernel can I see this information being stored
for use by the the bootloader. Also looking at the
bootable/bootloader/legacy, which I assume is the default bootloader,
I am unable to locate where the command to boot into recovery mode is
picked up. Can you point me in the right direction?

Thanks in advance.

/Bjarke

--
Bjarke Freund-Hansen  <bjar...@gmail.com>

Shachar Shemesh

unread,
Mar 30, 2011, 4:44:06 PM3/30/11
to android...@googlegroups.com
On 30/03/11 17:58, Bjarke Freund-Hansen wrote:
> Hi CVS
>
> Thanks a lot for your explanation. Do you have any pointer for where
> in the source I should look for this functionality?
>
> Specifically I have been looking at the source for adb which seems to
> call the __reboot syscall with "recovery" as a parameter. But nowhere
> in the Android Linux kernel can I see this information being stored
> for use by the the bootloader. Also looking at the
> bootable/bootloader/legacy, which I assume is the default bootloader,
> I am unable to locate where the command to boot into recovery mode is
> picked up. Can you point me in the right direction?
>
> Thanks in advance.
>
>

I was trying to figure out the answer to very similar question a while
back (September 2009, to be precise). I don't remember the precise
things I looked at, but I published it at
http://www.lingnu.com/en/android/68-htcandroidrebootoptions.html. From
the bottom of that page:
> The reboot command line is taken from the reboot command source for
> the open source version, at system/core/toolbox/reboot.c. The "-n" and
> "-p" options are handled there.
>
> The argument for reboot is transferred, as is, into the kernel. The
> meanings provided here are taken from the HTC Magic kernel sources
> (available from the HTC web site) at arch/arm/mach-msm/pm.c.
>

I hope this helps.

Shachar

--
Shachar Shemesh
Lingnu Open Source Consulting Ltd.
http://www.lingnu.com

Bjarke F.

unread,
Mar 31, 2011, 2:43:58 AM3/31/11
to android-porting
Hi.

Thanks for the link. This describes pretty much what I already have
discovered myself.

What I am interested in in is the exact method used for passing on a
command to the bootloader.
Where in the kernel source is the functionality and where in the
bootloader source is it picked up?

I would really appreciate if anyone can enlighten me on this, I have
spend quite a lot of time searching for this without much luck.

/Bjarke

Robin Gujjar

unread,
Mar 31, 2011, 4:43:15 AM3/31/11
to android-porting
Hi Bjarke,


Hmm .... i implemented it, what ever you are looking. foloow the below
Step :

=={ I am assuming your recovery image is already implemented and ready
to boot }===
Step : 1 : Open a simple file in android data or Cache partitions.
from Java file ex: RecoverySystem.java, in which very first call come
for recovery. and write any string in that File ex: "xyz" . Do this
stuff from java code.

Step 2: Now Go to Uboot main file and when there a read happen for
boot cmd, read the this file( i hope you can implement this by reading
your file system from uboot code :) Option one read the file , second
read the number of character in the file and then compare in uboot
code and if match with your defind set go ahead for boot recovery
image.). i hope you know , at this point , you will be changing your
boot cmd ---> ponting on recovery Image.

Step 3 : dis works , very few change is required for the above
solution. hope you will enjoy the above step : )
Step 4; --> think about the above opened file, what you can do for
next step.

-- Robin

Bjarke F.

unread,
Mar 31, 2011, 7:14:10 AM3/31/11
to android-porting
Hi Robin

The steps you outline seems like a solution that we can use. Thanks.

One detail though, when I issue a "adb reboot recovery" or "adb reboot
bootloader" I need to somehow write something that informs the
bootloader to do the right thing. Do you know how to do this?

Robin Gujjar

unread,
Mar 31, 2011, 8:25:00 AM3/31/11
to android-porting
OK --> " I need to somehow write something that informs the
bootloader to do the right thing. Do you know how to do this? "

If you have set of register in your processor which old the value in
power up or down mode-value retention.. You can utilized that write
some thing in register read at boot time and divert the path for
booting==> go for recovery.

If not , write some file or value on your storage media eg: NAND, SD/
MMC and read at the boot up.if you are trying it through adb then, i
do not know much about USB and adb i have only used it.

try from , UI -factory reset.hope it will help you.

Srikant

unread,
Mar 31, 2011, 9:56:03 AM3/31/11
to android-porting
Hi Bjarke,

Briefly the call flow here:

The bootCommand() function in RecoverySystem.java calls the
pm.reboot() with the user passed argument as "recovery".

The pm.reboot() is implemented in PowerManager.java, where it calls
the mService.reboot() with the reason code as "recovery".

The mService.reboot() is implemented in PowerManagerService.java,
where it calls ShutdownThread.reboot(mContext, finalReason, false);

The PowerManagerService.java communicates with the recovery.c through
JNI, where the reboot() is called with reason code.

The __reboot system call
__reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_RESTART2, "recovery");
is called in init.c

There are some methods which update/pass the commands to the
bootloader in firmware.c and bootloader.c

The __reboot sys call enters to the Kernel from sys.c, where the cmds
are passed to the Kernel and kernel_restart() function gets called.
kernel_restart_prepare(cmd); and machine_restart(cmd); are called
futher from here based on the linux reboot arguments.

Hope this helps and let us discuss/know if you have any furhter info.

-



On Mar 31, 4:14 pm, "Bjarke F." <bjark...@gmail.com> wrote:
> > > /Bjarke- Hide quoted text -
>
> - Show quoted text -

Shachar Shemesh

unread,
Mar 31, 2011, 4:33:35 PM3/31/11
to android...@googlegroups.com

I think the thing you are missing is that the boot loader is not (as far
as I know) open source. There is (was - have not looked in quite a
while, and my info might be out of date) an implementation of the
fastboot protocol in the AOSP tree, but that's just the USB protocol for
talking between the boot loader and a PC through a USB cable, not the
boot loader itself.

As such, you can look at what the kernel does in order to leave the mark
for the boot loader to boot into recovery, but not what the boot loader
is doing with this info.

I hope this clears up the confusion (or, make someone correct me, so I
know better :-).

Bjarke F.

unread,
Apr 1, 2011, 2:51:05 AM4/1/11
to android-porting
Hi Srikant

I will try to continue your explanation below to explain the parts I
do not understand:

On Mar 31, 3:56 pm, Srikant <w.sreeka...@gmail.com> wrote:

> Briefly the call flow here:
>
> The bootCommand() function in RecoverySystem.java calls the
> pm.reboot() with the user passed argument as "recovery".
>
> The pm.reboot() is implemented in PowerManager.java, where it calls
> the mService.reboot() with the reason code as "recovery".
>
> The mService.reboot() is implemented in PowerManagerService.java,
> where it calls ShutdownThread.reboot(mContext, finalReason, false);
>
> The PowerManagerService.java communicates with the recovery.c through
> JNI, where the reboot() is called with reason code.
>
> The __reboot system call
> __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
>                          LINUX_REBOOT_CMD_RESTART2, "recovery");
> is called in init.c

> The __reboot sys call enters to the Kernel from sys.c, where the cmds
> are passed to the Kernel and kernel_restart() function gets called.
> kernel_restart_prepare(cmd); and machine_restart(cmd);  are called
> futher from here based on the linux reboot arguments.

Reboot syscall is defined in kernel/sys.c as:
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
where kernel_restart() is called with the reboot reason ("recovery").

kernel_restart() calls kernel_restart_prepare() and machine_restart(),
both with the "recovery" command. (As you have explained.)

kernel_restart_prepare() passes on the recovery command to every
element in the reboot notifier list.

machine_restart() passes on the restart option to architecture
specific code, in my case (and most android cases I guess) it is arm.
Eventually arch_reset() is called, again with the recovery command, in
my case the implementation is in arch/arm/plat-mxc/system.c, and
nowhere in this function is the "recovery" command parameter used.

So, I guess either I need to modify arch/arm/plat-mxc/system.c to
store this command value for the bootloader (which I guess is not
easy, as I assume at this point all drivers are finalised.)
Another solution would be to implement a reboot notifier to do the
same, which would happen earlier in the shutdown process, and I should
be able to access the block devices at that point(?) Maybe such a
notifier is already present, and I have just been unable to find it?


> There are some methods which update/pass the commands to the
> bootloader in firmware.c and bootloader.c

Yes, I assume you are referring to the ones that live in devices/htc/
common/updater (on the android-2.3.1_r1 branch). I guess it will
require some work to include that code in the kernel, do you believe
that would be the right approach?


> Hope this helps and let us discuss/know if you have any furhter info.

Thanks a lot. :)

/Bjarke

Bjarke F.

unread,
Apr 1, 2011, 3:00:36 AM4/1/11
to android-porting
Hi

On Mar 31, 10:33 pm, Shachar Shemesh <shac...@shemesh.biz> wrote:
> On 31/03/11 08:43, Bjarke F. wrote:

> I think the thing you are missing is that the boot loader is not (as far
> as I know) open source. There is (was - have not looked in quite a
> while, and my info might be out of date) an implementation of the
> fastboot protocol in the AOSP tree, but that's just the USB protocol for
> talking between the boot loader and a PC through a USB cable, not the
> boot loader itself.

Yes, that is definitely part of my confusion. :) I have come to the
understanding that the implementation in bootable/bootloader/legacy is
a reference implementation for a bootloader, with the most useful part
being the fastboot+usbloader implementation.

> As such, you can look at what the kernel does in order to leave the mark
> for the boot loader to boot into recovery, but not what the boot loader
> is doing with this info.

That is exactly what I am chasing right now, but I cannot find the
code were the kernel leaves this mark. See my answer to Srikant for a
description of where I have been searching.

> I hope this clears up the confusion (or, make someone correct me, so I
> know better :-).

A bit, thanks. :)

/Bjarke

Chinmay S

unread,
Apr 1, 2011, 8:33:07 AM4/1/11
to bjar...@gmail.com, android-porting
Hi Bjarke,

You are on the right track.

But unfortunately pointing out "one-place" or "one-file" is not possible right now,
as we do not know the device/architecture you are working on.

Things are further complicated by the fact that
we do not know which bootloader you are going to use on your device.

So, let me illustrate with an example:

[1.] Consider you are working on a omap-board.

[2.] The architecture-specific code is arch_reset, present in
File: arch/arm/plat-omap/include/play/system.h
http://android.git.kernel.org/?p=kernel/linux-2.6.git;a=blob;f=arch/arm/plat-omap/include/plat/system.h

[3.] The final call to arch_reset is present in arm_machine_restart( )
File: arch/arm/kernel/process.c
http://android.git.kernel.org/?p=kernel/linux-2.6.git;a=blob;f=arch/arm/kernel/process.c

[4.] We will now implement a new function set_reboot_recovery_mode.
We use omap_writel( unused_SAR_reg_addr, special-hex-pattern )
SAR (or save-and-restore) registers retain their value after a warm-reset.

[5.] In arch_reset, check the param mode being passed to it.
Call set_reboot_recovery_mode here if mode is "recovery".

-- Execution along reboot-path continues --
-- Device reboots here. ( warm-reset ) --

[6.] After warm-reset, in the bootloader code, check the value in unused_SAR_reg_addr.
If it contains special-hex-pattern then in bootloader, code it so that the kernel is loaded
and point it to the recovery-fs (instead of the regular-fs partition).


As you can see the process of implementing recovery mode is
VERY
specific to the device we are using. There may not be an
exact "one-place" where we do this.

More info about your particular device will definitely help in
deciding the right way to implement recovery-fs feature.


Regards
CVS

Shachar Shemesh

unread,
Apr 1, 2011, 11:53:54 AM4/1/11
to android...@googlegroups.com
On 01/04/11 09:51, Bjarke F. wrote:
>
> Yes, I assume you are referring to the ones that live in devices/htc/
> common/updater (on the android-2.3.1_r1 branch). I guess it will
> require some work to include that code in the kernel, do you believe
> that would be the right approach?
>
>
>
Just one thing. Someone on this thread suggested that you save the fact
that the boot needs to go into recovery on the flash. I'd like to urge
you not to follow this advice. People expect a phone/device/whatever
that goes through a power cycle to boot as if nothing happened. It is
decidedly not a good idea to have persistent record of the desired boot
type.

JTD

unread,
Apr 1, 2011, 3:21:12 PM4/1/11
to android...@googlegroups.com
Take a look at the U-boot bootloader implementation. I know that freescale's android BSP's provide support for recovery mode and they are based on uboot (http://git.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=summary)

Deepak M

unread,
Apr 18, 2012, 9:26:19 AM4/18/12
to android...@googlegroups.com
hi,

I am working on android 4.0.4 and facing below problem : 

1. when i tried the option factory reset from option menu the user data contents are not erased but the phone is rebooting.

please help me to find out the files which need to be checked ... or is there any implemntation required in code to erase user data.

thanks in advance   
Reply all
Reply to author
Forward
0 new messages