1. 自制BL1
参考Android_Exynos4412_iROM_Secure_Booting_Guide_Ver.1.00.00.pdf,Exynos4412会自动把BL加载到0x0202_1400运行。所以BL1的入口地址需要设置为0x0202_1400,这样才能保证位置相关码可以正常执行。
Exynos4412内部的BL0会对BL1进行校验,BL1的头部为16字节的校验码,这个校验码是根据头部之后,其余的(8k-16)字节的数据计算出来的,工具源码可以参考mkbl1。对于编译生成的文件不足8k的情况,要将其用0填充到8k。当然,这里是以非安全启动方式来说明的。
编写源码时,要在对面中预留16字节的占位符,比如:
1.word 0x0
2.word 0x0
3.word 0x0
4.word 0x0
5
6 .global _start
7_start:
8 ldr sp, =0x02040000
9 bl _main
至于15k的BL1文件如何制作,我没有找到资料。
1.1. mkbl1源码
1#include <stdio.h>
2#include <string.h>
3
4#define BL1_SIZE 8 * 1024
5#define HEAD_SIZE 16
6
7static unsigned int calc_checksum(unsigned char *buf, unsigned int buf_size)
8{
9 unsigned int checksum = 0;
10 int i;
11
12 for(i = HEAD_SIZE; i < buf_size; i++) {
13 checksum += buf[i] & 0xff;
14 }
15
16 return checksum;
17}
18
19static unsigned int calc_header(unsigned char *head, unsigned int checksum)
20{
21 int i;
22
23 memset(head, 0x00, HEAD_SIZE);
24
25 head[3] = (0x1f >> 24) & 0xff;
26 head[2] = (0x1f >> 16) & 0xff;
27 head[1] = (0x1f >> 8 ) & 0xff;
28 head[0] = (0x1f >> 0 ) & 0xff;
29
30 head[7] = (checksum >> 24) & 0xff;
31 head[6] = (checksum >> 16) & 0xff;
32 head[5] = (checksum >> 8 ) & 0xff;
33 head[4] = (checksum >> 0 ) & 0xff;
34
35 head[0] ^= 0xbc;
36 head[1] ^= 0xca;
37 head[2] ^= 0xba;
38 head[3] ^= 0xcb;
39 head[4] ^= 0xcb;
40 head[5] ^= 0xce;
41 head[6] ^= 0xcd;
42 head[7] ^= 0xdf;
43 head[8] ^= 0xb7;
44 head[9] ^= 0xba;
45 head[10] ^= 0xbe;
46 head[11] ^= 0xbb;
47 head[12] ^= 0xba;
48 head[13] ^= 0xad;
49 head[14] ^= 0xdf;
50 head[15] ^= 0xdf;
51
52 for(i = 1; i < HEAD_SIZE; i++) {
53 head[i] ^= head[i-1];
54 }
55}
56
57int main(int argc, char *argv[])
58{
59 unsigned char head[HEAD_SIZE];
60 unsigned char buffer[BL1_SIZE];
61
62 char *infile;
63 char *outfile = "E4412bl1.bin";
64 FILE *fin, *fout;
65
66 int filesize;
67 unsigned int checksum;
68
69 if (argc < 2 || 0 == strcmp(argv[1], "?") || 0 == strcmp(argv[1], "help")) {
70 printf("Usage: %s <infile> [outfile=E4412bl1.bin]\n", argv[0]);
71 return -1;
72 }
73
74 infile = argv[1];
75 if (argc > 2) {
76 outfile = argv[2];
77 }
78
79 fin = fopen(infile, "rb");
80 if (!fin) {
81 printf("Can not open file '%s'\n", infile);
82 return -1;
83 }
84
85 fseek(fin, 0L, SEEK_END);
86 filesize = ftell(fin);
87 if (filesize > BL1_SIZE) {
88 printf("file %s size is %d, larger than %d!\n", infile, filesize, BL1_SIZE);
89 fclose(fin);
90 return -1;
91 }
92 fseek(fin, 0L, SEEK_SET);
93
94 // clear buffer in BL1_SIZE
95 memset(buffer, 0x00, sizeof(buffer));
96
97 if (filesize != fread(buffer, 1, filesize, fin)) {
98 printf("Can't read %s\n", infile);
99 fclose(fin);
100 return -1;
101 }
102 fclose(fin);
103
104 fout = fopen(outfile, "wb");
105 if (fout == NULL) {
106 printf("Can not open file '%s'\n", outfile);
107 return -1;
108 }
109
110 checksum = calc_checksum(buffer, filesize);
111 calc_header(head, checksum);
112
113 printf("checksum is 0x%08X of %d bytes\n", checksum, filesize);
114 printf("input [%s], output [%s]\n", infile, outfile);
115
116 fwrite(buffer, 1, BL1_SIZE, fout);
117 fseek(fout, 0L, SEEK_SET);
118 // write header
119 fwrite(head, 1, sizeof(head), fout);
120
121 fflush(fout);
122 fclose(fout);
123
124 return 0;
125}