LK 引导流程

一、Qualcomm平台

1.1 aboot_init函数

app/aboot/aboot.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
void aboot_init(const struct app_descriptor *app)
{
unsigned reboot_mode = 0;
int boot_err_type = 0;
int boot_slot = INVALID;
// 初始化wdog
#if WDOG_SUPPORT
msm_wdog_init();
#endif
// 设置EMMC/NAND页大小
if (target_is_emmc_boot())
{
page_size = mmc_page_size();
page_mask = page_size - 1;
mmc_blocksize = mmc_get_device_blocksize();
mmc_blocksize_mask = mmc_blocksize - 1;
}
else
{
page_size = flash_page_size();
page_mask = page_size - 1;
}
ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
// 读取设备信息
read_device_info(&device);
// 读取允许oem解锁信息
read_allow_oem_unlock(&device);
// 检查多插槽的支持情况
if (partition_multislot_is_supported())
{
boot_slot = partition_find_active_slot();
if (boot_slot == INVALID)
{
boot_into_fastboot = true;
}
else
{
// 将系统状态设置为活跃启动插槽
partition_mark_active_slot(boot_slot);
}
}
// 如果启用则显示splash启动屏幕
#if DISPLAY_SPLASH_SCREEN
#if NO_ALARM_DISPLAY
if (!check_alarm_boot()) {
#endif
#if DISPLAY_HDMI_PRIMARY
if (!strlen(device.display_panel))
strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
sizeof(device.display_panel));
#endif
#if ENABLE_WBC
// 等待显示器关闭的过程
while(pm_app_display_shutdown_in_prgs());
if (!pm_appsbl_display_init_done())
target_display_init(device.display_panel);
else
display_image_on_screen();
#else
target_display_init(device.display_panel);
#endif
#if NO_ALARM_DISPLAY
}
#endif
#endif
// 设置设备序列号SN
target_serialno((unsigned char *) sn_buf);
// 初始化显存
memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
// 检查关机理由,如果是用户强制关机了则正常启动
if (is_user_force_reset())
goto normal_boot;
// 同时按音量上下键则重启手机进入紧急下载模式9008
if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
{
reboot_device(EMERGENCY_DLOAD);
boot_into_fastboot = true;
}
if (!boot_into_fastboot)
{
// 进入recovery模式
if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
boot_into_recovery = 1;
// 进入fastboot模式
if (!boot_into_recovery &&
(keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
boot_into_fastboot = true;
}
#if NO_KEYPAD_DRIVER
if (fastboot_trigger())
boot_into_fastboot = true;
#endif
// 检查重启模式,并进入相应模式
#if USE_PON_REBOOT_REG
reboot_mode = check_hard_reboot_mode();
#else
reboot_mode = check_reboot_mode();
#endif
// recovery模式
if (reboot_mode == RECOVERY_MODE)
{
boot_into_recovery = 1;
}
// fastboot模式
else if(reboot_mode == FASTBOOT_MODE)
{
boot_into_fastboot = true;
}
// alarm模式
else if(reboot_mode == ALARM_BOOT)
{
boot_reason_alarm = true;
}
// dm verify验证
#if VERIFIED_BOOT
else if (VB_V2 == target_get_vb_version())
{
if (reboot_mode == DM_VERITY_ENFORCING)
{
device.verity_mode = 1;
write_device_info(&device);
}
#if ENABLE_VB_ATTEST
else if (reboot_mode == DM_VERITY_EIO)
#else
else if (reboot_mode == DM_VERITY_LOGGING)
#endif
{
device.verity_mode = 0;
write_device_info(&device);
}
else if (reboot_mode == DM_VERITY_KEYSCLEAR)
{
if(send_delete_keys_to_tz())
ASSERT(0);
}
}
#endif

normal_boot:
if (!boot_into_fastboot)
{
if (target_is_emmc_boot())
{
if(emmc_recovery_init())
if(target_use_signed_kernel())
{
if((device.is_unlocked) || (device.is_tampered))
{
#ifdef TZ_TAMPER_FUSE
set_tamper_fuse_cmd();
#endif
#if USE_PCOM_SECBOOT
set_tamper_flag(device.is_tampered);
#endif
}
}
retry_boot:
// 尝试启动active分区
if (partition_multislot_is_supported())
{
boot_slot = partition_find_boot_slot();
partition_mark_active_slot(boot_slot);
if (boot_slot == INVALID)
goto fastboot;
}
boot_err_type = boot_linux_from_mmc();
switch (boot_err_type)
{
case ERR_INVALID_PAGE_SIZE:
case ERR_DT_PARSE:
case ERR_ABOOT_ADDR_OVERLAP:
case ERR_INVALID_BOOT_MAGIC:
if(partition_multislot_is_supported())
{
// 启动失败则取消激活当前插槽,尝试使用另一个插槽启动
partition_deactivate_slot(boot_slot);
goto retry_boot;
}
else
break;
default:
break;
}
}
else
{
recovery_init();
#if USE_PCOM_SECBOOT
if((device.is_unlocked) || (device.is_tampered))
set_tamper_flag(device.is_tampered);
#endif
boot_linux_from_flash();
}
}
fastboot:
// 注册特定的fastboot命令
aboot_fastboot_register_commands();

/* dump partition table for debug info */
// dump分区信息用于debug
partition_dump();
// 初始化进入fastboot模式
fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
#if FBCON_DISPLAY_MSG
// 显示fastboot界面
display_fastboot_menu();
#endif
}

1.2 boot_linux_from_mmc函数

app/aboot/aboot.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
int boot_linux_from_mmc(void)
{
struct boot_img_hdr *hdr = (void*) buf;
struct boot_img_hdr *uhdr;
unsigned offset = 0;
int rcode;
unsigned long long ptn = 0;
int index = INVALID_PTN;
unsigned char *image_addr = 0;
unsigned kernel_actual;
unsigned ramdisk_actual;
unsigned imagesize_actual;
unsigned second_actual = 0;
unsigned int dtb_size = 0;
unsigned int out_len = 0;
unsigned int out_avai_len = 0;
unsigned char *out_addr = NULL;
uint32_t dtb_offset = 0;
unsigned char *kernel_start_addr = NULL;
unsigned int kernel_size = 0;
unsigned int patched_kernel_hdr_size = 0;
int rc;
char *ptn_name = NULL;
#if DEVICE_TREE
struct dt_table *table;
struct dt_entry dt_entry;
unsigned dt_table_offset;
uint32_t dt_actual;
uint32_t dt_hdr_size;
unsigned char *best_match_dt_addr = NULL;
#endif
struct kernel64_hdr *kptr = NULL;
int current_active_slot = INVALID;
if (check_format_bit())
boot_into_recovery = 1;
if (!boot_into_recovery) {
memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
if (rcode <= 0) {
boot_into_ffbm = false;
} else
boot_into_ffbm = true;
} else
boot_into_ffbm = false;
uhdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
hdr = uhdr;
goto unified_boot;
}
// 如果支持多个插槽,则总是使用boot分区
if (boot_into_recovery &&
(!partition_multislot_is_supported()))
ptn_name = "recovery";
else
ptn_name = "boot";
index = partition_get_index(ptn_name);
ptn = partition_get_offset(index);
if(ptn == 0) {
return -1;
}
// 为boot/recovery分区设置定值
mmc_set_lun(partition_get_lun(index));
if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
return -1;
}
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
return ERR_INVALID_BOOT_MAGIC;
}
if (hdr->page_size && (hdr->page_size != page_size)) {
if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) {
return -1;
}
page_size = hdr->page_size;
page_mask = page_size - 1;
}
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
image_addr = (unsigned char *)target_get_scratch_address();
memcpy(image_addr, (void *)buf, page_size);
// 确保cmdline已终止
hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
#if DEVICE_TREE
#ifndef OSVERSION_IN_BOOTIMAGE
dt_size = hdr->dt_size;
#endif
dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
return -1;
}
imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
#else
if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual + (uint64_t)second_actual + page_size)) {
return -1;
}
imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
#endif
#if VERIFIED_BOOT
boot_verifier_init();
#endif
if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
{
return -1;
}
// 更新加载boot.img数据,支持64/32位平台解压缩boot.img
if (partition_multislot_is_supported())
{
current_active_slot = partition_find_active_slot();
}
bs_set_timestamp(BS_KERNEL_LOAD_START);
if ((target_get_max_flash_size() - page_size) < imagesize_actual)
{
return -1;
}
offset = page_size;
// 读取没有签名和头部的image
if (mmc_read(ptn + offset, (void *)(image_addr + offset), imagesize_actual - page_size))
{
return -1;
}
bs_set_timestamp(BS_KERNEL_LOAD_DONE);
if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
{
offset = imagesize_actual;
if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
{
return -1;
}
// 读取签名信息
if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
{
return -1;
}
verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
// 用于测试
if(is_test_mode_enabled() && auth_kernel_img)
return 0;
} else {
second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
#ifdef TZ_SAVE_KERNEL_HASH
aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
#endif
#ifdef MDTP_SUPPORT
{
// 验证MDTP锁
mdtp_ext_partition_verification_t ext_partition;
ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
ext_partition.page_size = page_size;
ext_partition.image_addr = (uint32)image_addr;
ext_partition.image_size = imagesize_actual;
ext_partition.sig_avail = FALSE;
mdtp_fwlock_verify_lock(&ext_partition);
}
#endif /* MDTP_SUPPORT */
}
#if VERIFIED_BOOT
if((boot_verify_get_state() == ORANGE) && (!boot_into_ffbm))
{
#if FBCON_DISPLAY_MSG
display_bootverify_menu(DISPLAY_MENU_ORANGE);
wait_for_users_action();
#else
mdelay(5000);
#endif
}
#endif
#if VERIFIED_BOOT
if (VB_V2 == target_get_vb_version())
{
// 设置boot/system版本
set_os_version((unsigned char *)image_addr);
// 设置信任根
if(!send_rot_command((uint32_t)device.is_unlocked))
ASSERT(0);
}
#endif
// 检查kernel image是不是gzip格式,是则解压,否则继续启动
if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
{
out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
rc = decompress((unsigned char *)(image_addr + page_size),
hdr->kernel_size, out_addr, out_avai_len,
&dtb_offset, &out_len);
if (rc)
{
ASSERT(0);
}
kptr = (struct kernel64_hdr *)out_addr;
kernel_start_addr = out_addr;
kernel_size = out_len;
} else {
if (!strncmp((char*)(image_addr + page_size),
PATCHED_KERNEL_MAGIC,
sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
kptr = (struct kernel64_hdr *)(image_addr + page_size +
PATCHED_KERNEL_HEADER_SIZE);
// kernel的大小是在kernel image开头加上16.dtb在kernel之后
dtb_offset = *((uint32_t*)((unsigned char*)
(image_addr + page_size +
sizeof(PATCHED_KERNEL_MAGIC) -
1)));
// 实际的kernel是从20字节的头部之后开始的
kernel_start_addr = (unsigned char*)(image_addr +
page_size + PATCHED_KERNEL_HEADER_SIZE);
kernel_size = hdr->kernel_size;
patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
} else {
kptr = (struct kernel64_hdr *)(image_addr + page_size);
kernel_start_addr = (unsigned char *)(image_addr + page_size);
kernel_size = hdr->kernel_size;
}
}
// 如果boot.img头部有默认值,则更新kernel/ramdisk/tags地址
update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
// 因为hdr有保存物理地址,所以需要获取虚拟地址
hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
// 检查头部地址是否合法
if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
{
return -1;
}
#ifndef DEVICE_TREE
if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
{
return -1;
}
#endif
// 将kernel/ramdisk/dt放到正确的地址上
memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
#if DEVICE_TREE
if(dt_size) {
dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
table = (struct dt_table*) dt_table_offset;
if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
return -1;
}
// 验证dt_hdr_size是否有错
goes beyound hdr->dt_size*/
if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
return -1;
}
// 在设备树表中找到设备树索引
if(dev_tree_get_entry_info(table, &dt_entry) != 0){
return -1;
}
if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
return -1;
}
// 确保dt_entry不会超过dt_size
if ((dt_entry.offset + dt_entry.size) > dt_size) {
return -1;
}
if (is_gzip_package((unsigned char *)dt_table_offset + dt_entry.offset, dt_entry.size))
{
unsigned int compressed_size = 0;
out_addr += out_len;
out_avai_len -= out_len;
rc = decompress((unsigned char *)dt_table_offset + dt_entry.offset,
dt_entry.size, out_addr, out_avai_len,
&compressed_size, &dtb_size);
if (rc)
{
ASSERT(0);
}
best_match_dt_addr = out_addr;
} else {
best_match_dt_addr = (unsigned char *)dt_table_offset + dt_entry.offset;
dtb_size = dt_entry.size;
}
// 在tags_addr中读取验证设备树
if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
{
return -1;
}
memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
} else {
// 验证tags_addr
if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
{
return -1;
}
// 如果设备树有找到,则在RAM上更新atags,否则直接在kernel头部更新atags地址
void *dtb;
dtb = dev_tree_appended(
(void*)(image_addr + page_size +
patched_kernel_hdr_size),
hdr->kernel_size, dtb_offset,
(void *)hdr->tags_addr);
if (!dtb) {
return -1;
}
}
#endif
if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
target_load_ssd_keystore();
unified_boot:
boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
(const char *)hdr->cmdline, board_machtype(),
(void *)hdr->ramdisk_addr, hdr->ramdisk_size);
return 0;
}

1.3 boot_linux_from_flash函数

app/aboot/aboot.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
int boot_linux_from_flash(void)
{
struct boot_img_hdr *hdr = (void*) buf;
struct ptentry *ptn;
struct ptable *ptable;
unsigned offset = 0;
unsigned char *image_addr = 0;
unsigned kernel_actual;
unsigned ramdisk_actual;
unsigned imagesize_actual;
unsigned second_actual = 0;
#if DEVICE_TREE
struct dt_table *table;
struct dt_entry dt_entry;
unsigned dt_table_offset;
uint32_t dt_actual;
uint32_t dt_hdr_size;
unsigned int dtb_size = 0;
unsigned char *best_match_dt_addr = NULL;
#endif
if (target_is_emmc_boot()) {
hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
return -1;
}
goto continue_boot;
}
// 获取分区表
ptable = flash_get_ptable();
if (ptable == NULL) {
return -1;
}
if(!boot_into_recovery)
{
// 获取boot分区
ptn = ptable_find(ptable, "boot");
if (ptn == NULL) {
return -1;
}
}
else
{
// 获取recovery分区
ptn = ptable_find(ptable, "recovery");
if (ptn == NULL) {
return -1;
}
}
// 从flash中读取boot
if (flash_read(ptn, offset, buf, page_size)) {
return -1;
}
// 校验boot头部
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
return -1;
}
// 校验boot页大小
if (hdr->page_size != page_size) {
return -1;
}
image_addr = (unsigned char *)target_get_scratch_address();
memcpy(image_addr, (void *)buf, page_size);
// 如果boot.img头部有默认值,则更新kernel/ramdisk/tags地址
update_ker_tags_rdisk_addr(hdr, false);
// 通过hdr中保存的物理地址来获取虚拟地址
hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
// 确保cmdline是终止
hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
// 检查头地址是否有效
if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
{
return -1;
}
#ifndef DEVICE_TREE
if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
return -1;
}
imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
{
return -1;
}
#else
#ifndef OSVERSION_IN_BOOTIMAGE
dt_size = hdr->dt_size;
#endif
dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
return -1;
}
imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
{
return -1;
}
#endif
// 从flash中读取整个boot image
bs_set_timestamp(BS_KERNEL_LOAD_START);
if (UINT_MAX - page_size < imagesize_actual)
{
return -1;
}
// 在从flash中读取boot.img和最大签名长度之前,检查RAM是否可用
if (target_get_max_flash_size() < (imagesize_actual + page_size))
{
return -1;
}
offset = page_size;
// 读取不包含签名和头部的image部分
if (flash_read(ptn, offset, (void *)(image_addr + offset), imagesize_actual - page_size))
{
return -1;
}
bs_set_timestamp(BS_KERNEL_LOAD_DONE);
// kernel已签名且设备未解锁的情况进入
if(target_use_signed_kernel() && (!device.is_unlocked))
{
offset = imagesize_actual;
// 读取签名信息
if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
{
return -1;
}
verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
}
offset = page_size;
if(hdr->second_size != 0) {
if (UINT_MAX - offset < second_actual)
{
return -1;
}
offset += second_actual;
// 不实现第二个image的加载
ASSERT(0);
}
// 将kernel和ramdisk移动至正确的地址上
memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
#if DEVICE_TREE
if(dt_size != 0) {
dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
table = (struct dt_table*) dt_table_offset;
if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
return -1;
}
// 检查dt_hdr_size是否有错误
goes beyound hdr->dt_size*/
if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
return -1;
}
// 在设备树表中找到设备树索引
if(dev_tree_get_entry_info(table, &dt_entry) != 0){
return -1;
}
// 从tags_add中读取验证设备树中设备
if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
{
return -1;
}
if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
return -1;
}
// 确保dt_entry没有超过dt_size
if ((dt_entry.offset + dt_entry.size) > dt_size) {
return -1;
}
best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
dtb_size = dt_entry.size;
memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
}
#endif
// kernel已签名且设备未解锁情况下进入
if(target_use_signed_kernel() && (!device.is_unlocked))
{
// 在执行下一步之前确保复写的地址可读
if(device.is_tampered)
{
write_device_info_flash(&device);
}
#if USE_PCOM_SECBOOT
set_tamper_flag(device.is_tampered);
#endif
}
continue_boot:
boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
(const char *)hdr->cmdline, board_machtype(),
(void *)hdr->ramdisk_addr, hdr->ramdisk_size);

return 0;
}

1.4 boot_linux函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
void boot_linux(void *kernel, unsigned *tags,
const char *cmdline, unsigned machtype,
void *ramdisk, unsigned ramdisk_size)
{
unsigned char *final_cmdline;
#if DEVICE_TREE
int ret = 0;
#endif
void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
uint32_t tags_phys = PA((addr_t)tags);
struct kernel64_hdr *kptr = ((struct kernel64_hdr*)(PA((addr_t)kernel)));
ramdisk = (void *)PA((addr_t)ramdisk);
final_cmdline = update_cmdline((const char*)cmdline);
#if DEVICE_TREE
// 更新设备树
ret = update_device_tree((void *)tags,(const char *)final_cmdline, ramdisk, ramdisk_size);
if(ret)
{
ASSERT(0);
}
#else
// 生成atags
generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
#endif
free(final_cmdline);
#if VERIFIED_BOOT
if (VB_V2 == target_get_vb_version())
{
if (device.verity_mode == 0) {
#if FBCON_DISPLAY_MSG
#if ENABLE_VB_ATTEST
display_bootverify_menu(DISPLAY_MENU_EIO);
wait_for_users_action();
if(!pwr_key_is_pressed)
shutdown_device();
#else
display_bootverify_menu(DISPLAY_MENU_LOGGING);
#endif
wait_for_users_action();
#else
mdelay(5000);
#endif
}
}
#endif
#if VERIFIED_BOOT
// 为设备信息提供写保护
if (!boot_into_recovery && target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
{
ASSERT(0);
}
#endif
// 如果有启用splash屏幕需要关闭
#if DISPLAY_SPLASH_SCREEN
target_display_shutdown();
#endif
// 平台差异性清除
target_uninit();
enter_critical_section();
platform_uninit();
arch_disable_cache(UCACHE);
#if ARM_WITH_MMU
arch_disable_mmu();
#endif
bs_set_timestamp(BS_KERNEL_ENTRY);
if (IS_ARM64(kptr))
// 跳转至64位kernel
scm_elexec_call((paddr_t)kernel, tags_phys);
else
// 跳转至32位kernel
entry(0, machtype, (unsigned*)tags_phys);
}