github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/bootloader/lkenv/lkenv_v1.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2020 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package lkenv 21 22 import ( 23 "fmt" 24 ) 25 26 /** 27 * Following structure has to be kept in sync with c structure defined by 28 * include/lk/snappy-boot_v1.h 29 * c headerfile is used by bootloader, this ensures sync of the environment 30 * between snapd and bootloader 31 32 * when this structure needs to be updated, 33 * new version should be introduced instead together with c header file, 34 * which is to be adopted by bootloader 35 * 36 * !!! Support for old version has to be maintained, as it is not guaranteed 37 * all existing bootloader would adopt new version! 38 */ 39 type SnapBootSelect_v1 struct { 40 /* Contains value BOOTSELECT_SIGNATURE defined above */ 41 Signature uint32 42 /* snappy boot select version */ 43 Version uint32 44 45 /* snap_mode, one of: 'empty', "try", "trying" */ 46 Snap_mode [SNAP_FILE_NAME_MAX_LEN]byte 47 /* current core snap revision */ 48 Snap_core [SNAP_FILE_NAME_MAX_LEN]byte 49 /* try core snap revision */ 50 Snap_try_core [SNAP_FILE_NAME_MAX_LEN]byte 51 /* current kernel snap revision */ 52 Snap_kernel [SNAP_FILE_NAME_MAX_LEN]byte 53 /* current kernel snap revision */ 54 Snap_try_kernel [SNAP_FILE_NAME_MAX_LEN]byte 55 56 /* gadget_mode, one of: 'empty', "try", "trying" */ 57 Gadget_mode [SNAP_FILE_NAME_MAX_LEN]byte 58 /* GADGET assets: current gadget assets revision */ 59 Snap_gadget [SNAP_FILE_NAME_MAX_LEN]byte 60 /* GADGET assets: try gadget assets revision */ 61 Snap_try_gadget [SNAP_FILE_NAME_MAX_LEN]byte 62 63 /** 64 * Reboot reason 65 * optional parameter to signal bootloader alternative reboot reasons 66 * e.g. recovery/factory-reset/boot asset update 67 */ 68 Reboot_reason [SNAP_FILE_NAME_MAX_LEN]byte 69 70 /** 71 * Matrix for mapping of boot img partition to installed kernel snap revision 72 * 73 * First column represents boot image partition label (e.g. boot_a,boot_b ) 74 * value are static and should be populated at gadget built time 75 * or latest at image build time. Values are not further altered at run time. 76 * Second column represents name currently installed kernel snap 77 * e.g. pi2-kernel_123.snap 78 * initial value representing initial kernel snap revision 79 * is populated at image build time by snapd 80 * 81 * There are two rows in the matrix, representing current and previous kernel revision 82 * following describes how this matrix should be modified at different stages: 83 * - at image build time: 84 * - extracted kernel snap revision name should be filled 85 * into free slot (first row, second column) 86 * - snapd: 87 * - when new kernel snap revision is being installed, snapd cycles through 88 * matrix to find unused 'boot slot' to be used for new kernel snap revision 89 * from free slot, first column represents partition label to which kernel 90 * snap boot image should be extracted. Second column is then populated with 91 * kernel snap revision name. 92 * - snap_mode, snap_try_kernel, snap_try_core behaves same way as with u-boot 93 * - bootloader: 94 * - bootloader reads snap_mode to determine if snap_kernel or snap_try_kernel is used 95 * to get kernel snap revision name 96 * kernel snap revision is then used to search matrix to determine 97 * partition label to be used for current boot 98 * - bootloader NEVER alters this matrix values 99 * 100 * [ <bootimg 1 part label> ] [ <kernel snap revision installed in this boot partition> ] 101 * [ <bootimg 2 part label> ] [ <kernel snap revision installed in this boot partition> ] 102 */ 103 Bootimg_matrix [SNAP_BOOTIMG_PART_NUM][2][SNAP_FILE_NAME_MAX_LEN]byte 104 105 /** 106 * name of the boot image from kernel snap to be used for extraction 107 * when not defined or empty, default boot.img will be used 108 */ 109 Bootimg_file_name [SNAP_FILE_NAME_MAX_LEN]byte 110 111 /** 112 * gadget assets: Matrix for mapping of gadget asset partitions 113 * Optional boot asset tracking, based on bootloader support 114 * Some boot chains support A/B boot assets for increased robustness 115 * example being A/B TrustExecutionEnvironment 116 * This matrix can be used to track current and try boot assets for 117 * robust updates 118 * Use of Gadget_asset_matrix matches use of Bootimg_matrix 119 * 120 * [ <boot assets 1 part label> ] [ <currently installed assets revision in this partition> ] 121 * [ <boot assets 2 part label> ] [ <currently installed assets revision in this partition> ] 122 */ 123 Gadget_asset_matrix [SNAP_BOOTIMG_PART_NUM][2][SNAP_FILE_NAME_MAX_LEN]byte 124 125 /* unused placeholders for additional parameters in the future */ 126 Unused_key_01 [SNAP_FILE_NAME_MAX_LEN]byte 127 Unused_key_02 [SNAP_FILE_NAME_MAX_LEN]byte 128 Unused_key_03 [SNAP_FILE_NAME_MAX_LEN]byte 129 Unused_key_04 [SNAP_FILE_NAME_MAX_LEN]byte 130 Unused_key_05 [SNAP_FILE_NAME_MAX_LEN]byte 131 Unused_key_06 [SNAP_FILE_NAME_MAX_LEN]byte 132 Unused_key_07 [SNAP_FILE_NAME_MAX_LEN]byte 133 Unused_key_08 [SNAP_FILE_NAME_MAX_LEN]byte 134 Unused_key_09 [SNAP_FILE_NAME_MAX_LEN]byte 135 Unused_key_10 [SNAP_FILE_NAME_MAX_LEN]byte 136 Unused_key_11 [SNAP_FILE_NAME_MAX_LEN]byte 137 Unused_key_12 [SNAP_FILE_NAME_MAX_LEN]byte 138 Unused_key_13 [SNAP_FILE_NAME_MAX_LEN]byte 139 Unused_key_14 [SNAP_FILE_NAME_MAX_LEN]byte 140 Unused_key_15 [SNAP_FILE_NAME_MAX_LEN]byte 141 Unused_key_16 [SNAP_FILE_NAME_MAX_LEN]byte 142 Unused_key_17 [SNAP_FILE_NAME_MAX_LEN]byte 143 Unused_key_18 [SNAP_FILE_NAME_MAX_LEN]byte 144 Unused_key_19 [SNAP_FILE_NAME_MAX_LEN]byte 145 Unused_key_20 [SNAP_FILE_NAME_MAX_LEN]byte 146 147 /* unused array of 10 key value pairs */ 148 Key_value_pairs [10][2][SNAP_FILE_NAME_MAX_LEN]byte 149 150 /* crc32 value for structure */ 151 Crc32 uint32 152 } 153 154 func newV1() *SnapBootSelect_v1 { 155 return &SnapBootSelect_v1{ 156 Version: SNAP_BOOTSELECT_VERSION_V1, 157 Signature: SNAP_BOOTSELECT_SIGNATURE, 158 } 159 } 160 161 func (v1 *SnapBootSelect_v1) currentCrc32() uint32 { return v1.Crc32 } 162 func (v1 *SnapBootSelect_v1) currentVersion() uint32 { return v1.Version } 163 func (v1 *SnapBootSelect_v1) currentSignature() uint32 { return v1.Signature } 164 165 func (v1 *SnapBootSelect_v1) get(key string) string { 166 switch key { 167 case "snap_mode": 168 return cToGoString(v1.Snap_mode[:]) 169 case "snap_kernel": 170 return cToGoString(v1.Snap_kernel[:]) 171 case "snap_try_kernel": 172 return cToGoString(v1.Snap_try_kernel[:]) 173 case "snap_core": 174 return cToGoString(v1.Snap_core[:]) 175 case "snap_try_core": 176 return cToGoString(v1.Snap_try_core[:]) 177 case "snap_gadget": 178 return cToGoString(v1.Snap_gadget[:]) 179 case "snap_try_gadget": 180 return cToGoString(v1.Snap_try_gadget[:]) 181 case "reboot_reason": 182 return cToGoString(v1.Reboot_reason[:]) 183 case "bootimg_file_name": 184 return cToGoString(v1.Bootimg_file_name[:]) 185 } 186 return "" 187 } 188 189 func (v1 *SnapBootSelect_v1) set(key, value string) { 190 switch key { 191 case "snap_mode": 192 copyString(v1.Snap_mode[:], value) 193 case "snap_kernel": 194 copyString(v1.Snap_kernel[:], value) 195 case "snap_try_kernel": 196 copyString(v1.Snap_try_kernel[:], value) 197 case "snap_core": 198 copyString(v1.Snap_core[:], value) 199 case "snap_try_core": 200 copyString(v1.Snap_try_core[:], value) 201 case "snap_gadget": 202 copyString(v1.Snap_gadget[:], value) 203 case "snap_try_gadget": 204 copyString(v1.Snap_try_gadget[:], value) 205 case "reboot_reason": 206 copyString(v1.Reboot_reason[:], value) 207 case "bootimg_file_name": 208 copyString(v1.Bootimg_file_name[:], value) 209 } 210 } 211 212 func (v1 *SnapBootSelect_v1) bootImgKernelMatrix() (bootimgMatrixGeneric, error) { 213 return (bootimgMatrixGeneric)((&v1.Bootimg_matrix)[:]), nil 214 } 215 216 func (v1 *SnapBootSelect_v1) bootImgRecoverySystemMatrix() (bootimgMatrixGeneric, error) { 217 return nil, fmt.Errorf("internal error: v1 lkenv has no boot image partition recovery system matrix") 218 }