下面是一个bootloader加载一个kernel image的函数
1. loadImage() --- 参数是nandflash 中的起始地址和结束地址
uint32_t loadImage(uint32_t start, uint32_t end)
{
image_header_t *header = (image_header_t *) nandPage;
uint8_t *src = (uint8_t *) nandPage;
uint8_t *dst;
uint32_t page = PAGE(start);
uint32_t endPage = PAGE(end);
uint32_t crc;
//读nandflash中的内容
page = ReadNandPages(page, src, 1, endPage);
if (!page)
{
puts("ERROR: Cannot read header page\r\n");
return ~0;
}
//然后开始校验是不是标准的kernel image
if (ntohl(header->ih_magic) != IH_MAGIC)
{
puts("ERROR: Header magic mismatch\r\n");
return ~0;
}
switch (header->ih_os)
{
case IH_OS_LINUX:
isUboot = 0;
break;
case IH_OS_U_BOOT:
isUboot = 1;
break;
default:
puts("ERROR: Unsupported OS type\r\n");
return ~0;
}
if (header->ih_arch != IH_ARCH_ARM) {
puts("ERROR: Unsupported ARCH type\r\n");
return ~0;
}
if (header->ih_type != IH_TYPE_KERNEL) {
puts("ERROR: Unsupported Image type\r\n");
return ~0;
}
puts("Image: ");
puts(header->ih_name);
puts("\r\n");
src += sizeof(image_header_t);
dst = (uint8_t *) ntohl(header->ih_load);
switch (header->ih_comp) {
case IH_COMP_NONE:
{
const int inSRAM = PAGE_SIZE - sizeof(image_header_t);
memcpy(dst, src, inSRAM);
dst += PAGE_SIZE - sizeof(image_header_t);
page = ReadNandPages(page, dst, PAGE(ntohl(header->ih_size) - inSRAM), endPage);
if (!page)
{
puts("ERROR: problem reading NAND\r\n");
return ~0;
}
// Calculate CRC
dst = (uint8_t *) ntohl(header->ih_load);
crc = crc32(0, dst, ntohl(header->ih_size));
break;
}
default:
puts("ERROR: Unsupported compression\r\n");
return ~0;
}
// Verify CRC
if (ntohl(header->ih_dcrc) != crc) {
puts("ERROR: CRC mismatch\r\n");
return ~0;
}
return ntohl(header->ih_ep);
}
2. image_header_t --- 用mkimage 做出来的image 都会有这个头。
typedef struct image_header
{
uint32_t ih_magic; /* Magic Number */
uint32_t ih_hcrc; /* Header CRC */
uint32_t ih_time; /* Creation Timestamp */
uint32_t ih_size; /* Image Size */
uint32_t ih_load; /* Address to put image */
uint32_t ih_ep; /* Address to jump to */
uint32_t ih_dcrc; /* Image CRC */
uint8_t ih_os; /* OS */
uint8_t ih_arch; /* CPU arch */
uint8_t ih_type; /* Type */
uint8_t ih_comp; /* Compression */
uint8_t ih_name[IH_NMLEN]; /* Name */
} image_header_t;