/* * Copyright (c) Hisilicon Technologies Co., Ltd. Technologies Co., Ltd. 2016-2020. All rights reserved. * Description: generat bootargs * Author: Hisilicon * Create: 2016-07-06 */ #include #include #include #include #include "securec.h" #define BOOTARGS_LEN 4096 #define MAX_LINE_LENGTH BOOTARGS_LEN #define BOOTARGS_PLACEHOLDER_SIZE 0x4 #define PATH_MAX_LEN 1024 static void usage(void) { printf("Usage: mkbootargs:\n" " -r bootargs_input: read a bootargs.txt\n" " -o bootargs_bin: write a bootargs.bin\n" " -s bootargssize: size in KB. usually, bootargssize is set to the bootargs partition size. default:512.\n" " mkbootargs will read a 'bootargs_input.txt' and generat a 'bootargs.bin' and 'Partition_table.xml'.\n"); printf("Example:./makebootargs -s 64\n"); } static void change_end_char(char *line, int len) { int i; if ((line == NULL) || (len < 0) || (len > MAX_LINE_LENGTH)) { return; } for (i = 0; i < len; i++) { if (line[i] != '\0') { if ((line[i] == '\n') || (line[i] == 0xd)) { line[i] = '\0'; } } else { break; } } } static int read_bootargs(unsigned char *buf, unsigned int size, FILE *fp_input) { unsigned int offset = 0; char line[MAX_LINE_LENGTH]; size_t len, ret_len; if ((buf == NULL) || (fp_input == NULL) || (size <= 0)) { return -1; } memset_s(line, sizeof(line), 0, MAX_LINE_LENGTH); while (fgets(line, (MAX_LINE_LENGTH - 1), fp_input) != NULL) { change_end_char(line, MAX_LINE_LENGTH - 1); len = strlen(line); printf("%u--%s\n", len, line); if (size >= (BOOTARGS_PLACEHOLDER_SIZE + offset)) { ret_len = size - BOOTARGS_PLACEHOLDER_SIZE - offset; } else { break; } if ((ret_len <= 0) || (ret_len >= size) || (len >= MAX_LINE_LENGTH) || (len < 0) || (len > ret_len)) { break; } if (memcpy_s(buf + BOOTARGS_PLACEHOLDER_SIZE + offset, ret_len, line, len) != 0) { printf("[%s:%d] memcpy_s failed!", __func__, __LINE__); break; } offset += (len + 1); memset_s(line, sizeof(line), 0, MAX_LINE_LENGTH); } return 0; } static int path_split(char *path, unsigned int size, char *file_name, unsigned int name_size) { char *tmp_name = NULL; char *tmp_dir = NULL; size_t len; unsigned int i; unsigned int pos = 0; if ((path == NULL) || (file_name == NULL)) { return -1; } len = strlen(path); if ((len >= size) || (len <= 0)) { return -1; } if (path[len - 1] == '/') { path[len - 1] = '\0'; } for (i = 0; i < len; i++) { if (path[i] == '/') { pos = i; } } tmp_name = path + pos + 1; if (pos == 0) { if (path[0] == '/') { tmp_dir = "/"; } else { tmp_name = path; tmp_dir = "."; } } else { path[pos] = '\0'; } if (strcpy_s(file_name, name_size, tmp_name) != 0) { return -1; } if (tmp_dir != NULL) { if (strcpy_s(path, size, tmp_dir) != 0) { return -1; } } return 0; } static int check_out_file_path(const char *file_path, char *out_file_path, unsigned int size) { char *buf = NULL; char *file_name = NULL; int ret = -1; size_t len; if ((file_path == NULL) || (out_file_path == NULL) || (size <= 0)) { return ret; } buf = malloc(size); if (buf == NULL) { return ret; } file_name = malloc(size); if (file_name == NULL) { free(buf); return ret; } if (strcpy_s(buf, size, file_path) != 0) { goto ERR; } if (path_split(buf, size, file_name, size) < 0) { goto ERR; } len = strlen(buf); if ((len >= size) || realpath(buf, out_file_path) == NULL) { goto ERR; } if (strcat_s(out_file_path, size, "/") != 0) { goto ERR; } if (strcat_s(out_file_path, size, file_name) != 0) { goto ERR; } ret = 0; ERR: free(buf); free(file_name); return ret; } static int build_bootargs_bin(const char *input_filename, const char *out_filename, unsigned int flash_size) { FILE *fp = NULL; FILE *fp_input = NULL; unsigned char *buf = NULL; char bootargs_input[PATH_MAX]; char bootargs_output[PATH_MAX]; if ((input_filename == NULL) || (out_filename == NULL) || (flash_size <= 0)) { return -1; } if (strlen(input_filename) >= PATH_MAX_LEN || realpath(input_filename, bootargs_input) == NULL) { printf("input file is not exist\n"); return -1; } if (check_out_file_path(out_filename, bootargs_output, PATH_MAX) != 0) { printf("output file path is not exist\n"); return -1; } buf = malloc(flash_size); if (buf == NULL) { printf("open bootargs out of memory\n"); return -1; } fp = fopen(bootargs_output, "w+b"); if (fp == NULL) { printf("open bootargs.bin error."); free(buf); return -1; } fp_input = fopen(bootargs_input, "rb"); if (fp_input == NULL) { printf("open 'bootargs_input' faild, please input bootargs:"); free(buf); (void)fclose(fp); return -1; } memset_s(buf, flash_size, 0x00, flash_size); if (read_bootargs(buf, flash_size, fp_input) == 0) { fwrite(buf, flash_size, 1, fp); /* init flash data */ } free(buf); (void)fclose(fp); if (fp_input != stdin) { fclose(fp_input); } return 0; } int main(int argc, char *argv[]) { unsigned int size = 512; // flash size. char bootargs_input[PATH_MAX_LEN] = "bootargs_input.txt"; // bootargs_input file name char bootargs_bin[PATH_MAX_LEN] = "bootargs.bin"; // bootargs file name int oc, ret, num; if (argc < 2) { // parameter must be greater than 2 usage(); return 1; } while ((oc = getopt(argc, argv, "r:o:s:")) != -1) { switch (oc) { case 'r': if (sprintf_s(bootargs_input, sizeof(bootargs_input), "%s", optarg) < 0) { printf("sprintf_s return failed\n"); return -1; } printf("optarg:%s\n", optarg); break; case 'o': if (sprintf_s(bootargs_bin, sizeof(bootargs_bin), "%s", optarg) < 0) { printf("sprintf_s return failed\n"); return -1; } printf("optarg:%s\n", optarg); break; case 's': num = atoi(optarg); if (num >= 0) { size = (unsigned int)num; } printf("optarg:%s\n", optarg); break; default: printf("unknow args\n"); break; } } if (size > 1) { printf("flash size is %dKB.\n", size); size = size * 1024; // 1024 for KB to byte } else { printf("flash size too small.\n"); } ret = build_bootargs_bin(bootargs_input, bootargs_bin, size); return ret; }