2 * @copyright Copyright (c) 2018-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <sys/types.h>
31 #include "boot_hal_boothallog.h"
33 #define BOOT_PARTATION "/dev/mmcblk0boot1"
34 #define BOOTINFO_FILEA "/repro/mmcblk0boot1-launch_a.bin"
35 #define BOOTINFO_FILEB "/repro/mmcblk0boot1-launch_b.bin"
37 #define MMCBLK0BOOT1_FORCE_RO "/sys/class/block/mmcblk0boot1/force_ro"
38 #define MMCBLK0BOOT1_SIZE_PATH "/sys/class/block/mmcblk0boot1/size"
39 #define MMCBLK0BOOT1_SIZE_DEF (0x1000000)
40 #define BOOTINFO_SIZE (0x20000)
41 #define SECTOR_SIZE (512)
42 #define FILEPATH_MAX (256)
44 #define BOOT_CMDLINE "/proc/cmdline"
45 #define CMDLINE_MAX_SIZE (256)
46 #define BOOT_ROOTFS_A "/dev/mmcblk0p1"
47 #define BOOT_ROOTFS_B "/dev/mmcblk0p2"
48 #define BOOTARGS_LST_ROOT "root="
51 #define BOOT_COPYBUF_SIZE (64 * 1024)
53 static int EnableMmcBlk(const char *path) {
57 if ((fd = open(path, O_RDWR)) < 0) {
61 if (write(fd, enable, sizeof(enable)) < 0) {
70 static int GetMmcBlkCount(const char *path) {
72 char block_size[16] = {0};
74 if ((fd = open(path, O_RDONLY)) < 0) {
78 if (read(fd, block_size, sizeof(block_size)) < 0) {
84 return strtol(block_size, NULL, 10);
87 static ssize_t BootReadN(int fd, void *buffer, size_t n) {
91 buf = reinterpret_cast<char *>(buffer);
92 for (tot_read = 0; tot_read < n;) {
94 num_read = read(fd, buf, n - tot_read);
100 if (errno == EINTR) {
106 tot_read += num_read;
112 static ssize_t BootWriteN(int fd, const void *buffer, size_t n) {
116 buf = (const char *)buffer;
117 for (tot_written = 0; tot_written < n;) {
119 num_written = write(fd, buf, n - tot_written);
121 if (num_written <= 0) {
122 if (num_written == -1 && errno == EINTR) {
128 tot_written += num_written;
134 BootHalStatus setSide(unsigned int upTableID[]) {
135 BootHalStatus ret = BOOTHAL_RET_ERR_FAIL;
138 int sector_count = 0;
140 char binfo_file[FILEPATH_MAX] = {0};
143 if (NULL == upTableID) {
144 return BOOTHAL_RET_ERR_PARAM;
147 if (upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] == BOOTHAL_SIDE_A) {
148 snprintf(binfo_file, FILEPATH_MAX, "%s", BOOTINFO_FILEA);
149 } else if (upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] == BOOTHAL_SIDE_B) {
150 snprintf(binfo_file, FILEPATH_MAX, "%s", BOOTINFO_FILEB);
152 ret = BOOTHAL_RET_ERR_PARAM;
156 binfo_fd = open(binfo_file, O_RDONLY);
158 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "open %s:%s", binfo_file, strerror(errno));
159 ret = BOOTHAL_RET_ERR_FAIL;
163 mmc_fd = open(BOOT_PARTATION, O_WRONLY);
165 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "open %s:%s", BOOT_PARTATION, strerror(errno));
166 ret = BOOTHAL_RET_ERR_FAIL;
171 * enable mmcblk0boot1 for write
173 if (EnableMmcBlk(MMCBLK0BOOT1_FORCE_RO) < 0) {
174 ret = BOOTHAL_RET_ERR_FAIL;
179 * Get sector count of mmcblk0boot1 block from sys-file, every sector size is 512byte.
180 * The mmcblk0boot1 block default size is 16M.
182 if ((sector_count = GetMmcBlkCount(MMCBLK0BOOT1_SIZE_PATH)) < 0) {
183 mmc_offset = MMCBLK0BOOT1_SIZE_DEF - BOOTINFO_SIZE;
185 mmc_offset = sector_count * SECTOR_SIZE - BOOTINFO_SIZE;
189 * The environment should be write to the latest 128K of mmcblk0boot1.
191 if (lseek(mmc_fd, mmc_offset, SEEK_SET) < 0) {
192 ret = BOOTHAL_RET_ERR_FAIL;
196 buf = reinterpret_cast<char *>(mmap(NULL, BOOT_COPYBUF_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0));
197 if (buf == MAP_FAILED) {
198 ret = BOOTHAL_RET_ERR_FAIL;
205 rd = BootReadN(binfo_fd, buf, BOOT_COPYBUF_SIZE);
211 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "read:%s", strerror(errno));
212 ret = BOOTHAL_RET_ERR_FAIL;
216 wr = BootWriteN(mmc_fd, buf, rd);
218 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "write(%s):%s", BOOT_PARTATION, strerror(errno));
219 ret = BOOTHAL_RET_ERR_WRITE;
224 if (fsync(mmc_fd) < 0) {
225 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "fsync:%s", strerror(errno));
227 ret = BOOTHAL_RET_SUCCESS;
231 if (close(binfo_fd) < 0) {
232 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno));
237 if (close(mmc_fd) < 0) {
238 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno));
243 munmap(buf, BOOT_COPYBUF_SIZE);
249 BootHalStatus getSide(unsigned int upTableID[]) {
250 BootHalStatus ret = BOOTHAL_RET_SUCCESS;
253 char buf[CMDLINE_MAX_SIZE] = {0};
256 if (NULL == upTableID) {
257 return BOOTHAL_RET_ERR_PARAM;
260 if ((fd = open(BOOT_CMDLINE, O_RDONLY)) < 0) {
261 ret = BOOTHAL_RET_ERR_FAIL;
265 if ((rd_size = BootReadN(fd, buf, CMDLINE_MAX_SIZE)) < 0) {
266 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "read %s error:%s", BOOT_CMDLINE, strerror(errno));
267 ret = BOOTHAL_RET_ERR_FAIL;
271 rootfs = strstr(buf, BOOTARGS_LST_ROOT);
273 ret = BOOTHAL_RET_ERR_FAIL;
277 rootfs += strlen(BOOTARGS_LST_ROOT);
278 if (strncmp(rootfs, BOOT_ROOTFS_A, strlen(BOOT_ROOTFS_A)) == 0 &&
279 (rootfs[strlen(BOOT_ROOTFS_A)] == ' ' || rootfs[strlen(BOOT_ROOTFS_A)] == '\0')) {
280 upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] = BOOTHAL_SIDE_A;
281 } else if (strncmp(rootfs, BOOT_ROOTFS_B, strlen(BOOT_ROOTFS_B)) == 0 &&
282 (rootfs[strlen(BOOT_ROOTFS_B)] == ' ' || rootfs[strlen(BOOT_ROOTFS_B)] == '\0')) {
283 upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] = BOOTHAL_SIDE_B;
285 ret = BOOTHAL_RET_ERR_FAIL;
291 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno));
298 BootHalStatus setBootColdStart(void) {
301 * This feature needs to be implemented by the vendor.
303 return BOOTHAL_RET_SUCCESS;
306 BootHalStatus getBootMode(uint32_t *mode) {
308 return BOOTHAL_RET_ERR_PARAM;
312 return BOOTHAL_RET_SUCCESS;