Quotes are needed around a variable value that has a space in it.
[AROS.git] / tools / mksunxiboot / mksunxiboot.c
bloba6b69744aa30fea21e0644b5e60357aee90a0e28
1 /*
2 * (C) Copyright 2007-2011
3 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
4 * Tom Cubie <tangliang@allwinnertech.com>
6 * a simple tool to generate bootable image for sunxi platform.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
33 typedef unsigned char u8;
34 typedef unsigned int u32;
36 /* boot head definition from sun4i boot code */
37 typedef struct boot_file_head
39 u32 jump_instruction; // one intruction jumping to real code
40 u8 magic[8]; // ="eGON.BT0" or "eGON.BT1", not C-style string.
41 u32 check_sum; // generated by PC
42 u32 length; // generated by PC
43 u32 pub_head_size; // the size of boot_file_head_t
44 u8 pub_head_vsn[4]; // the version of boot_file_head_t
45 u8 file_head_vsn[4]; // the version of boot0_file_head_t or boot1_file_head_t
46 u8 Boot_vsn[4]; // Boot version
47 u8 eGON_vsn[4]; // eGON version
48 u8 platform[8]; // platform information
49 }boot_file_head_t;
51 #define BOOT0_MAGIC "eGON.BT0"
52 #define STAMP_VALUE 0x5F0A6C39
53 /* check sum functon from sun4i boot code */
54 int gen_check_sum( void *boot_buf )
56 boot_file_head_t *head_p;
57 u32 length;
58 u32 *buf;
59 u32 loop;
60 u32 i;
61 u32 sum;
63 head_p = (boot_file_head_t *)boot_buf;
64 length = head_p->length;
65 if( ( length & 0x3 ) != 0 ) // must 4-byte-aligned
66 return -1;
67 buf = (u32 *)boot_buf;
68 head_p->check_sum = STAMP_VALUE; // fill stamp
69 loop = length >> 2;
70 /* calculate the sum */
71 for( i = 0, sum = 0; i < loop; i++ )
72 sum += buf[i];
74 /* write back check sum */
75 head_p->check_sum = sum;
77 return 0;
80 #define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
81 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
83 #define SUN4I_SRAM_SIZE (24 * 1024)
84 #define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(boot_file_head_t))
85 #define BLOCK_SIZE 512
86 struct boot_img {
87 boot_file_head_t header;
88 char code[SRAM_LOAD_MAX_SIZE];
89 char pad[BLOCK_SIZE];
92 int main(int argc, char * argv[])
94 int fd_in, fd_out;
95 struct boot_img img;
96 unsigned file_size, load_size;
97 int count;
99 if(argc < 2) {
100 printf("\tThis program makes an input bin file to sun4i bootable image.\n"
101 "\tUsage: %s input_file out_putfile\n", argv[0]);
102 return EXIT_FAILURE;
105 fd_in = open(argv[1], O_RDONLY);
106 if(fd_in < 0) {
107 perror("Open input file:");
108 return EXIT_FAILURE;
111 fd_out = open(argv[2], O_WRONLY|O_CREAT, 0666);
112 if(fd_out < 0) {
113 perror("Open output file:");
114 return EXIT_FAILURE;
117 memset((void *)img.pad, 0, BLOCK_SIZE);
119 /* get input file size */
120 file_size = lseek(fd_in, 0, SEEK_END);
121 printf("File size: 0x%x \n", file_size);
123 if(file_size > SRAM_LOAD_MAX_SIZE) {
124 load_size = SRAM_LOAD_MAX_SIZE;
125 } else {
126 load_size = ALIGN(file_size, sizeof(int));
128 printf("Load size: 0x%x \n", load_size);
130 /* read file to buffer to calculate checksum */
131 lseek(fd_in, 0, SEEK_SET);
132 count = read(fd_in, img.code, load_size);
133 printf("Read 0x%x bytes\n", count);
135 /* fill the header */
136 img.header.jump_instruction = /* b instruction */
137 0xEA000000 | /* jump to the first instruction after the header */
139 (sizeof(boot_file_head_t) / sizeof(int) - 2)
140 & 0x00FFFFFF
142 memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */
143 img.header.length = ALIGN(load_size + sizeof(boot_file_head_t), BLOCK_SIZE);
144 gen_check_sum((void *)&img);
146 count = write(fd_out, (void *)&img, img.header.length);
147 printf("Write 0x%x bytes\n", count);
149 close(fd_in);
150 close(fd_out);
152 return EXIT_SUCCESS;