You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.2 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. Technologies Co., Ltd. 2016-2020. All rights reserved.
* Description: generat bootargs
* Author: Hisilicon
* Create: 2016-07-06
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#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;
}