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开始启动。

 

posted @ 2022-06-05 11:21  BH5HSV  阅读(400)  评论(0编辑  收藏  举报