1/* 2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, 5 * are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this list of 8 * conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific prior written 16 * permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "los_bootargs.h" 32#include "los_base.h" 33#include "string.h" 34 35#if defined(LOSCFG_STORAGE_SPINOR) || defined(LOSCFG_STORAGE_SPINAND) 36#include "mtd_list.h" 37#endif 38 39#ifdef LOSCFG_STORAGE_EMMC 40#include "disk.h" 41#endif 42 43STATIC CHAR *g_cmdLine = NULL; 44STATIC UINT64 g_alignSize = 0; 45STATIC struct BootArgs g_bootArgs[MAX_ARGS_NUM] = {0}; 46 47INT32 LOS_GetCmdLine(VOID) 48{ 49 int ret; 50 51 g_cmdLine = (CHAR *)malloc(COMMAND_LINE_SIZE); 52 if (g_cmdLine == NULL) { 53 PRINT_ERR("Malloc g_cmdLine space error!\n"); 54 return LOS_NOK; 55 } 56 57#ifdef LOSCFG_STORAGE_EMMC 58 los_disk *emmcDisk = los_get_mmcdisk_bytype(EMMC); 59 if (emmcDisk == NULL) { 60 PRINT_ERR("Get EMMC disk failed!\n"); 61 goto ERROUT; 62 } 63 g_alignSize = EMMC_SEC_SIZE; 64 ret = los_disk_read(emmcDisk->disk_id, g_cmdLine, COMMAND_LINE_ADDR / EMMC_SEC_SIZE, 65 COMMAND_LINE_SIZE / EMMC_SEC_SIZE, TRUE); 66 if (ret == 0) { 67 return LOS_OK; 68 } 69#endif 70 71#ifdef LOSCFG_STORAGE_SPINOR 72 struct MtdDev *mtd = GetMtd("spinor"); 73 if (mtd == NULL) { 74 PRINT_ERR("Get spinor mtd failed!\n"); 75 goto ERROUT; 76 } 77 g_alignSize = mtd->eraseSize; 78 ret = mtd->read(mtd, COMMAND_LINE_ADDR, COMMAND_LINE_SIZE, g_cmdLine); 79 if (ret == COMMAND_LINE_SIZE) { 80 return LOS_OK; 81 } 82#endif 83 84#ifdef LOSCFG_STORAGE_SPINAND 85 struct MtdDev *mtd = GetMtd("nand"); 86 if (mtd == NULL) { 87 PRINT_ERR("Get nand mtd failed!\n"); 88 goto ERROUT; 89 } 90 g_alignSize = mtd->eraseSize; 91 ret = mtd->read(mtd, COMMAND_LINE_ADDR, COMMAND_LINE_SIZE, g_cmdLine); 92 if (ret == COMMAND_LINE_SIZE) { 93 return LOS_OK; 94 } 95#endif 96 97 PRINT_ERR("Read cmdline error!\n"); 98ERROUT: 99 free(g_cmdLine); 100 g_cmdLine = NULL; 101 return LOS_NOK; 102} 103 104VOID LOS_FreeCmdLine(VOID) 105{ 106 if (g_cmdLine != NULL) { 107 free(g_cmdLine); 108 g_cmdLine = NULL; 109 } 110} 111 112STATIC INT32 GetBootargs(CHAR **args) 113{ 114#ifdef LOSCFG_BOOTENV_RAM 115 *args = OsGetArgsAddr(); 116 return LOS_OK; 117#else 118 INT32 i; 119 INT32 len = 0; 120 CHAR *tmp = NULL; 121 const CHAR *bootargsName = "bootargs="; 122 123 if (g_cmdLine == NULL) { 124 PRINT_ERR("Should call LOS_GetCmdLine() first!\n"); 125 return LOS_NOK; 126 } 127 128 for (i = 0; i < COMMAND_LINE_SIZE; i += len + 1) { 129 len = strlen(g_cmdLine + i); 130 tmp = strstr(g_cmdLine + i, bootargsName); 131 if (tmp != NULL) { 132 *args = tmp + strlen(bootargsName); 133 return LOS_OK; 134 } 135 } 136 PRINT_ERR("Cannot find bootargs!\n"); 137 return LOS_NOK; 138#endif 139} 140 141INT32 LOS_ParseBootargs(VOID) 142{ 143 INT32 idx = 0; 144 INT32 ret; 145 CHAR *args = NULL; 146 CHAR *argName = NULL; 147 CHAR *argValue = NULL; 148 149 ret = GetBootargs(&args); 150 if (ret != LOS_OK) { 151 return LOS_NOK; 152 } 153 154 while ((argValue = strsep(&args, " ")) != NULL) { 155 argName = strsep(&argValue, "="); 156 if (argValue == NULL) { 157 /* If the argument is not compliance with the format 'foo=bar' */ 158 g_bootArgs[idx].argName = argName; 159 g_bootArgs[idx].argValue = argName; 160 } else { 161 g_bootArgs[idx].argName = argName; 162 g_bootArgs[idx].argValue = argValue; 163 } 164 if (++idx >= MAX_ARGS_NUM) { 165 /* Discard the rest arguments */ 166 break; 167 } 168 } 169 return LOS_OK; 170} 171 172INT32 LOS_GetArgValue(CHAR *argName, CHAR **argValue) 173{ 174 INT32 idx = 0; 175 176 while (idx < MAX_ARGS_NUM) { 177 if (g_bootArgs[idx].argName == NULL) { 178 break; 179 } 180 if (strcmp(argName, g_bootArgs[idx].argName) == 0) { 181 *argValue = g_bootArgs[idx].argValue; 182 return LOS_OK; 183 } 184 idx++; 185 } 186 187 return LOS_NOK; 188} 189 190UINT64 LOS_GetAlignsize(VOID) 191{ 192 return g_alignSize; 193} 194 195UINT64 LOS_SizeStrToNum(CHAR *value) 196{ 197 UINT64 num = 0; 198 199 /* If the string is a hexadecimal value */ 200 if (sscanf_s(value, "0x%llx", &num) > 0) { 201 value += strlen("0x"); 202 if (strspn(value, "0123456789abcdefABCDEF") < strlen(value)) { 203 goto ERROUT; 204 } 205 return num; 206 } 207 208 /* If the string is a decimal value in unit *Bytes */ 209 INT32 ret = sscanf_s(value, "%d", &num); 210 INT32 decOffset = strspn(value, "0123456789"); 211 CHAR *endPos = value + decOffset; 212 if ((ret <= 0) || (decOffset < (strlen(value) - 1))) { 213 goto ERROUT; 214 } 215 216 if (strlen(endPos) == 0) { 217 return num; 218 } else if (strcasecmp(endPos, "k") == 0) { 219 num = num * BYTES_PER_KBYTE; 220 } else if (strcasecmp(endPos, "m") == 0) { 221 num = num * BYTES_PER_MBYTE; 222 } else if (strcasecmp(endPos, "g") == 0) { 223 num = num * BYTES_PER_GBYTE; 224 } else { 225 goto ERROUT; 226 } 227 228 return num; 229 230ERROUT: 231 PRINT_ERR("Invalid value string \"%s\"!\n", value); 232 return num; 233} 234