ZYNQ芯片通过FSBL或U-Boot SPL启动Linux内核
当前编译好FDT fdt.dtb和zImage放在SD卡中,使用XSDK建立fsbl工程,在sd.c中添加函数:
1 u32 SDLoadImage(char *filename, u32 DestinationAddress)
2 {
3 FRESULT rc;
4 UINT br;
5 UINT bl;
6 TCHAR *path = "0:/"; /* Logical drive number is 0 */
7
8 f_close(&fil);
9
10 rc = f_mount(&fatfs, path, 0);
11 fsbl_printf(DEBUG_INFO,"SD: rc= %.8x\n\r", rc);
12
13 if (rc != FR_OK) {
14 return XST_FAILURE;
15 }
16
17 strcpy_rom(buffer, filename);
18 boot_file = (char *)buffer;
19
20 rc = f_open(&fil, boot_file, FA_READ);
21 if (rc) {
22 fsbl_printf(DEBUG_GENERAL,"SD: Unable to open file %s: %d\n", boot_file, rc);
23 return XST_FAILURE;
24 }
25
26 bl = (&fil)->fsize;
27
28 rc = f_lseek(&fil, 0L);
29 if (rc) {
30 return XST_FAILURE;
31 }
32
33 rc = f_read(&fil, (void*)DestinationAddress, bl, &br);
34
35 if (rc) {
36 fsbl_printf(DEBUG_GENERAL,"*** ERROR: f_read returned %d\r\n", rc);
37 }
38
39 f_close(&fil);
40
41 return XST_SUCCESS;
42 }
在main函数中添加启动内核代码:
1 const int32_t devicetree_addr = 0x20000000; /* Do not overlap with vmlinux */
2 const int32_t zimage_entry = 0x10008000; /* Do not overlap with vmlinux */
3
4 /* Loading Devicetree and zImage */
5 fsbl_printf(DEBUG_INFO,"Loading fdt.dtb\r\n");
6 Status = SDLoadImage("fdt.dtb", devicetree_addr);
7 if (Status != XST_SUCCESS) {
8 fsbl_printf(DEBUG_GENERAL,"SD_INIT_FAIL\r\n");
9 OutputStatus(SD_INIT_FAIL);
10 FsblFallback();
11 }
12
13 fsbl_printf(DEBUG_INFO,"Loading Kernel Image\r\n");
14 Status = SDLoadImage("zImage", zimage_entry);
15 if (Status != XST_SUCCESS) {
16 fsbl_printf(DEBUG_GENERAL,"SD_INIT_FAIL\r\n");
17 OutputStatus(SD_INIT_FAIL);
18 FsblFallback();
19 }
20
21 void (*kernel_entry)(int zero, int arch, int params);
22 kernel_entry = (void (*)(int, int, int))zimage_entry;
23
24 fsbl_printf(DEBUG_INFO,"Starting Kernel ...\r\n\n");
25 kernel_entry(0x0, 0x0, devicetree_addr);
即可从SD加载Image并启动Linux系统。
如果是u-boot spl Falcon mode直接启动uImage,定义CONFIG_SPL_OS_BOOT=y,注意uImage的信息头内容要正确,LOADADDR开始的空间不可与实际ENTRYADDR即内核真正运行的地址重叠覆盖。
mkimage -Aarm -Olinux -Tkernel -Cnone -a0x20008000 -e0x00108000 -n'Linux-4.0.0' -d zImage uImage
保证zImage运行解压内核的代码在0x20008000开始运行,解压出来内核放在0x00108000开始的空间,内核从0x00108000开始启动。