| OLD | NEW |
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 * | 4 * |
| 5 * Functions for loading a kernel from disk. | 5 * Functions for loading a kernel from disk. |
| 6 * (Firmware portion) | 6 * (Firmware portion) |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "load_kernel_fw.h" | 9 #include "load_kernel_fw.h" |
| 10 | 10 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 uint16_t lowest_kernel_key_version = 0xFFFF; | 102 uint16_t lowest_kernel_key_version = 0xFFFF; |
| 103 uint16_t lowest_kernel_version = 0xFFFF; | 103 uint16_t lowest_kernel_version = 0xFFFF; |
| 104 KernelImage *kim = NULL; | 104 KernelImage *kim = NULL; |
| 105 | 105 |
| 106 /* Read current kernel key index from TPM. Assumes TPM is already | 106 /* Read current kernel key index from TPM. Assumes TPM is already |
| 107 * initialized. */ | 107 * initialized. */ |
| 108 /* TODO: Is that a safe assumption? Normally, SetupTPM() would be called | 108 /* TODO: Is that a safe assumption? Normally, SetupTPM() would be called |
| 109 * when the RW firmware is verified. Is it harmful to call SetupTPM() | 109 * when the RW firmware is verified. Is it harmful to call SetupTPM() |
| 110 * again if it's already initialized? It'd be easier if we could just do | 110 * again if it's already initialized? It'd be easier if we could just do |
| 111 * that. */ | 111 * that. */ |
| 112 tpm_kernel_key_version = GetStoredVersion(KERNEL_KEY_VERSION); | 112 GetStoredVersions(KERNEL_VERSIONS, |
| 113 tpm_kernel_version = GetStoredVersion(KERNEL_VERSION); | 113 &tpm_kernel_key_version, |
| 114 | 114 &tpm_kernel_version); |
| 115 do { | 115 do { |
| 116 /* Read GPT data */ | 116 /* Read GPT data */ |
| 117 gpt.sector_bytes = blba; | 117 gpt.sector_bytes = blba; |
| 118 gpt.drive_sectors = params->ending_lba + 1; | 118 gpt.drive_sectors = params->ending_lba + 1; |
| 119 if (0 != AllocAndReadGptData(&gpt)) | 119 if (0 != AllocAndReadGptData(&gpt)) |
| 120 break; | 120 break; |
| 121 | 121 |
| 122 /* Initialize GPT library */ | 122 /* Initialize GPT library */ |
| 123 if (GPT_SUCCESS != GptInit(&gpt)) | 123 if (GPT_SUCCESS != GptInit(&gpt)) |
| 124 break; | 124 break; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 if (kim) | 234 if (kim) |
| 235 Free(kim); | 235 Free(kim); |
| 236 | 236 |
| 237 // Write and free GPT data | 237 // Write and free GPT data |
| 238 WriteAndFreeGptData(&gpt); | 238 WriteAndFreeGptData(&gpt); |
| 239 | 239 |
| 240 // Handle finding a good partition | 240 // Handle finding a good partition |
| 241 if (good_partition >= 0) { | 241 if (good_partition >= 0) { |
| 242 | 242 |
| 243 /* See if we need to update the TPM */ | 243 /* See if we need to update the TPM */ |
| 244 if (lowest_kernel_key_version > tpm_kernel_key_version) { | 244 if ((lowest_kernel_key_version > tpm_kernel_key_version) || |
| 245 WriteStoredVersion(KERNEL_KEY_VERSION, lowest_kernel_key_version); | 245 (lowest_kernel_key_version == tpm_kernel_key_version && |
| 246 WriteStoredVersion(KERNEL_VERSION, lowest_kernel_version); | 246 lowest_kernel_version > tpm_kernel_version)) { |
| 247 } | 247 WriteStoredVersions(KERNEL_VERSIONS, |
| 248 else if (lowest_kernel_key_version == tpm_kernel_key_version && | 248 lowest_kernel_key_version, |
| 249 lowest_kernel_version > tpm_kernel_version) { | 249 lowest_kernel_version); |
| 250 WriteStoredVersion(KERNEL_VERSION, lowest_kernel_version); | |
| 251 } | 250 } |
| 252 | 251 |
| 253 if (BOOT_MODE_RECOVERY != params->boot_mode) { | 252 if (BOOT_MODE_RECOVERY != params->boot_mode) { |
| 254 /* We can lock the TPM now, since we've decided which kernel we | 253 /* We can lock the TPM now, since we've decided which kernel we |
| 255 * like. If we don't find a good kernel, we leave the TPM | 254 * like. If we don't find a good kernel, we leave the TPM |
| 256 * unlocked so we can try again on the next boot device. If no | 255 * unlocked so we can try again on the next boot device. If no |
| 257 * kernels are good, we'll reboot to recovery mode, so it's ok to | 256 * kernels are good, we'll reboot to recovery mode, so it's ok to |
| 258 * leave the TPM unlocked in that case too. | 257 * leave the TPM unlocked in that case too. |
| 259 * | 258 * |
| 260 * If we're already in recovery mode, we need to leave PP unlocked, | 259 * If we're already in recovery mode, we need to leave PP unlocked, |
| 261 * so don't lock the kernel versions. */ | 260 * so don't lock the kernel versions. */ |
| 262 LockKernelVersionsByLockingPP(); | 261 LockKernelVersionsByLockingPP(); |
| 263 } | 262 } |
| 264 | 263 |
| 265 /* Success! */ | 264 /* Success! */ |
| 266 return LOAD_KERNEL_SUCCESS; | 265 return LOAD_KERNEL_SUCCESS; |
| 267 } | 266 } |
| 268 | 267 |
| 269 // Handle error cases | 268 // Handle error cases |
| 270 if (found_partition) | 269 if (found_partition) |
| 271 return LOAD_KERNEL_INVALID; | 270 return LOAD_KERNEL_INVALID; |
| 272 else | 271 else |
| 273 return LOAD_KERNEL_NOT_FOUND; | 272 return LOAD_KERNEL_NOT_FOUND; |
| 274 /* TODO: no error code for "internal error", but what would the firmware do | 273 /* TODO: no error code for "internal error", but what would the firmware do |
| 275 * with that anyway? So in the do-while(0) code above, the firmware just | 274 * with that anyway? So in the do-while(0) code above, the firmware just |
| 276 * does 'break' to indicate an internal error... */ | 275 * does 'break' to indicate an internal error... */ |
| 277 } | 276 } |
| OLD | NEW |