Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(926)

Side by Side Diff: common/cmd_cros_rec.c

Issue 5989010: Create Chrome OS recovery firmware procedure. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/u-boot-next.git
Patch Set: update new vboot struct Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « common/Makefile ('k') | include/config_cmd_all.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 *
6 * Alternatively, this software may be distributed under the terms of the
7 * GNU General Public License ("GPL") version 2 as published by the Free
8 * Software Foundation.
9 */
10
11 /* Debug commands for Chrome OS recovery mode firmware */
12
13 #include <common.h>
14 #include <command.h>
15 #include <lcd.h>
16 #include <malloc.h>
17 #include <mmc.h>
18 #include <usb.h>
19
20 #include <bmpblk_header.h>
21 #include <chromeos/gbb_bmpblk.h>
22 #include <chromeos/hardware_interface.h>
23
24 #include <gbb_header.h>
25 #include <load_firmware_fw.h>
26 #include <load_kernel_fw.h>
27 #include <chromeos/boot_device_impl.h>
28
29 #define PREFIX "cros_rec: "
30
31 #ifdef VBOOT_DEBUG
32 #define WARN_ON_FAILURE(action) do { \
33 int return_code = (action); \
34 if (return_code != 0) \
35 debug(PREFIX "%s failed, returning %d\n", \
36 #action, return_code); \
37 } while (0)
38 #else
39 #define WARN_ON_FAILURE(action) action
40 #endif
41
42 /* MMC dev number of SD card */
43 #define MMC_DEV_NUM_SD 1
44
45 #define WAIT_MS_BETWEEN_PROBING 200
46
47 uint8_t *g_gbb_base = NULL;
48 int g_is_dev = 0;
49
50 static void sleep_ms(int msecond)
51 {
52 const ulong start = get_timer(0);
53 const ulong delay = msecond * CONFIG_SYS_HZ / 1000;
54
55 while (!ctrlc() && get_timer(start) < delay)
56 udelay(100);
57 }
58
59 static int is_mmc_storage_present(void)
60 {
61 return mmc_legacy_init(MMC_DEV_NUM_SD) == 0;
62 }
63
64 static int is_usb_storage_present(void)
65 {
66 int i;
67 /* TODO: Seek a better way to probe USB instead of restart it */
68 usb_stop();
69 i = usb_init();
70 #ifdef CONFIG_USB_STORAGE
71 if (i >= 0) {
72 /* Scanning bus for storage devices, mode = 1. */
73 return usb_stor_scan(1) == 0;
74 }
75 #else
76 return i;
77 #endif
78 }
79
80 static int write_log(void)
81 {
82 /* TODO: Implement it when Chrome OS firmware logging is ready. */
83 return 0;
84 }
85
86 static int clear_ram_not_in_use(void)
87 {
88 /* TODO: Implement it when the memory layout is defined. */
89 return 0;
90 }
91
92 static int load_and_boot_kernel(uint8_t *load_addr, size_t load_size)
93 {
94 LoadKernelParams par;
95 block_dev_desc_t *dev_desc;
96 VbNvContext vnc;
97 int i, status;
98 GoogleBinaryBlockHeader *gbbh = (GoogleBinaryBlockHeader *)g_gbb_base;
99 char buffer[CONFIG_SYS_CBSIZE];
100
101 if ((dev_desc = get_bootdev()) == NULL) {
102 printf(PREFIX "No boot device set yet\n");
103 return 1;
104 }
105
106 par.gbb_data = g_gbb_base;
107 par.gbb_size = CONFIG_LENGTH_GBB;
108 par.shared_data_blob = NULL;
109 par.shared_data_size = 0;
110 par.bytes_per_lba = (uint64_t) dev_desc->blksz;
111 par.ending_lba = (uint64_t) get_limit() - 1;
112 par.kernel_buffer = load_addr;
113 par.kernel_buffer_size = load_size;
114 par.boot_flags = BOOT_FLAG_RECOVERY | BOOT_FLAG_SKIP_ADDR_CHECK;
115 /* TODO: load vnc.raw from NV storage */
116 par.nv_context = &vnc;
117
118 if (g_is_dev) {
119 par.boot_flags |= BOOT_FLAG_DEVELOPER;
120 }
121
122 status = LoadKernel(&par);
123
124 if (vnc.raw_changed) {
125 /* TODO: save vnc.raw to NV storage */
126 }
127
128 switch (status) {
129 case LOAD_KERNEL_SUCCESS:
130 printf(PREFIX "Success; good kernel found on device\n");
131 printf(PREFIX "partition_number: %lld\n",
132 par.partition_number);
133 printf(PREFIX "bootloader_address: 0x%llx\n",
134 par.bootloader_address);
135 printf(PREFIX "bootloader_size: 0x%llx\n", par.bootloader_size);
136 printf(PREFIX "partition_guid: ");
137 for (i = 0; i < 16; i++)
138 printf("%02x", par.partition_guid[i]);
139 putc('\n');
140
141 lcd_clear();
142
143 strcpy(buffer, "console=ttyS0,115200n8 ");
144 strcat(buffer, getenv("platform_extras"));
145 setenv("bootargs", buffer);
146 sprintf(buffer, "%lld", par.partition_number + 1);
147 setenv("rootpart", buffer);
148
149 source(CONFIG_LOADADDR + par.bootloader_address -
150 0x100000, NULL);
151 run_command("bootm ${loadaddr}", 0);
152 break;
153 case LOAD_KERNEL_NOT_FOUND:
154 printf(PREFIX "No kernel found on device\n");
155 break;
156 case LOAD_KERNEL_INVALID:
157 printf(PREFIX "Only invalid kernels found on device\n");
158 break;
159 case LOAD_KERNEL_RECOVERY:
160 printf(PREFIX "Internal error; reboot to recovery mode\n");
161 break;
162 case LOAD_KERNEL_REBOOT:
163 printf(PREFIX "Internal error; reboot to current mode\n");
164 break;
165 default:
166 printf(PREFIX "Unexpected return status from LoadKernel: %d\n",
167 status);
168 return 1;
169 }
170 return 0;
171 }
172
173 static int load_recovery_image_in_mmc(void)
174 {
175 char buffer[CONFIG_SYS_CBSIZE];
176 sprintf(buffer, "mmcblk%dp", MMC_DEV_NUM_SD);
177 setenv("devname", buffer);
178 set_bootdev("mmc", MMC_DEV_NUM_SD, 0);
179 return load_and_boot_kernel((uint8_t *)CONFIG_LOADADDR, 0x01000000);
180 }
181
182 static int load_recovery_image_in_usb(void)
183 {
184 /* TODO: Find the correct dev num of USB storage instead of always 0 */
185 setenv("devname", "sda");
186 set_bootdev("usb", 0, 0);
187 return load_and_boot_kernel((uint8_t *)CONFIG_LOADADDR, 0x01000000);
188 }
189
190 static int init_gbb_in_ram(void)
191 {
192 firmware_storage_t file;
193 if (init_firmware_storage(&file)) {
194 debug(PREFIX "init_firmware_storage failed\n");
195 return -1;
196 }
197 g_gbb_base = malloc(CONFIG_LENGTH_GBB);
198 if (!g_gbb_base) {
199 debug(PREFIX "Unable to malloc g_gbb_base\n");
200 return -1;
201 }
202 if (read_firmware_device(&file, CONFIG_OFFSET_GBB, g_gbb_base,
203 CONFIG_LENGTH_GBB)) {
204 debug(PREFIX "Unable to read firmware to g_gbb_base\n");
205 return -1;
206 }
207 return 0;
208 }
209
210 static int show_screen(ScreenIndex scr)
211 {
212 static ScreenIndex cur_scr;
213 if (cur_scr == scr) {
214 return 0;
215 } else {
216 cur_scr = scr;
217 return display_screen_in_bmpblk(g_gbb_base, scr);
218 }
219 }
220
221 int do_cros_rec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
222 {
223 WARN_ON_FAILURE(write_log());
224 WARN_ON_FAILURE(clear_ram_not_in_use());
225 WARN_ON_FAILURE(init_gbb_in_ram());
226
227 g_is_dev = is_developer_mode_gpio_asserted();
228
229 if (!g_is_dev) {
230 /* Wait for user to plug out SD card and USB storage device */
231 while (is_mmc_storage_present() || is_usb_storage_present()) {
232 show_screen(SCREEN_RECOVERY_MODE);
233 sleep_ms(WAIT_MS_BETWEEN_PROBING);
234 }
235 }
236
237 for (;;) {
238 /* Wait for user to plug in SD card or USB storage device */
239 while (!is_mmc_storage_present() && !is_usb_storage_present()) {
240 show_screen(SCREEN_RECOVERY_NO_OS);
241 sleep_ms(WAIT_MS_BETWEEN_PROBING);
242 }
243 if (is_mmc_storage_present()) {
244 WARN_ON_FAILURE(load_recovery_image_in_mmc());
245 /* Wait for user to plug out SD card */
246 while (is_mmc_storage_present()) {
247 show_screen(SCREEN_RECOVERY_MISSING_OS);
248 sleep_ms(WAIT_MS_BETWEEN_PROBING);
249 }
250 } else if (is_usb_storage_present()) {
251 WARN_ON_FAILURE(load_recovery_image_in_usb());
252 /* Wait for user to plug out USB storage device */
253 while (is_usb_storage_present()) {
254 show_screen(SCREEN_RECOVERY_MISSING_OS);
255 sleep_ms(WAIT_MS_BETWEEN_PROBING);
256 }
257 }
258 }
259
260 /* This point is never reached */
261 return 0;
262 }
263
264 U_BOOT_CMD(cros_rec, 1, 1, do_cros_rec, "recovery mode firmware", NULL);
OLDNEW
« no previous file with comments | « common/Makefile ('k') | include/config_cmd_all.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698