- int nrparts = 2, curpart = 0; // CFE and NVRAM always present.
- struct bcm963xx_cfe_map {
- unsigned char tagVersion[4]; // Version of the image tag
- unsigned char sig_1[20]; // Company Line 1
- unsigned char sig_2[14]; // Company Line 2
- unsigned char chipid[6]; // Chip this image is for
- unsigned char boardid[16]; // Board name
- unsigned char bigEndian[2]; // Map endianness -- 1 BE 0 LE
- unsigned char totalLength[IMAGE_LEN]; //Total length of image
- unsigned char cfeAddress[ADDRESS_LEN]; // Address in memory of CFE
- unsigned char cfeLength[IMAGE_LEN]; // Size of CFE
- unsigned char rootAddress[ADDRESS_LEN]; // Address in memory of rootfs
- unsigned char rootLength[IMAGE_LEN]; // Size of rootfs
- unsigned char kernelAddress[ADDRESS_LEN]; // Address in memory of kernel
- unsigned char kernelLength[IMAGE_LEN]; // Size of kernel
- unsigned char dualImage[2]; // Unused at present
- unsigned char inactiveFlag[2]; // Unused at present
- unsigned char reserved1[74]; // Reserved area not in use
- unsigned char imageCRC[4]; // CRC32 of images
- unsigned char reserved2[16]; // Unused at present
- unsigned char headerCRC[4]; // CRC32 of header excluding tagVersion
- unsigned char reserved3[16]; // Unused at present
- } *buf;
- struct mtd_partition *parts;
- int ret;
- size_t retlen;
- unsigned int rootfsaddr, kerneladdr, spareaddr;
- unsigned int rootfslen, kernellen, sparelen, totallen;
- int namelen = 0;
- int i;
- // Allocate memory for buffer
- buf = vmalloc(sizeof(struct bcm963xx_cfe_map));
-
- if (!buf)
- return -ENOMEM;
-
- // Get the tag
- ret = master->read(master,master->erasesize,sizeof(struct bcm963xx_cfe_map), &retlen, (void *)buf);
- if (retlen != sizeof(struct bcm963xx_cfe_map)){
- vfree(buf);
- return -EIO;
- };
- printk("bcm963xx: CFE boot tag found with version %s and board type %s.\n",buf->tagVersion,buf->boardid);
- // Get the values and calculate
- sscanf(buf->rootAddress,"%u", &rootfsaddr);
- rootfsaddr = rootfsaddr - EXTENDED_SIZE;
- sscanf(buf->rootLength, "%u", &rootfslen);
- sscanf(buf->kernelAddress, "%u", &kerneladdr);
- kerneladdr = kerneladdr - EXTENDED_SIZE;
- sscanf(buf->kernelLength, "%u", &kernellen);
- sscanf(buf->totalLength, "%u", &totallen);
- spareaddr = ROUNDUP(totallen,master->erasesize) + master->erasesize;
- sparelen = master->size - spareaddr - master->erasesize;
- // Determine number of partitions
- namelen = 8;
- if (rootfslen > 0){
- nrparts++;
- namelen =+ 6;
- };
- if (kernellen > 0){
- nrparts++;
- namelen =+ 6;
- };
- // Ask kernel for more memory.
- parts = kmalloc(sizeof(*parts)*nrparts+10*nrparts, GFP_KERNEL);
- if (!parts){
- vfree(buf);
- return -ENOMEM;
- };
- memset(parts,0,sizeof(*parts)*nrparts+10*nrparts);
- // Start building partition list
- parts[curpart].name = "CFE";
- parts[curpart].offset = 0;
- parts[curpart].size = master->erasesize;
- curpart++;
- if (kernellen > 0){
- parts[curpart].name = "kernel";
- parts[curpart].offset = kerneladdr;
- parts[curpart].size = kernellen;
- curpart++;
- };
- if (rootfslen > 0){
- parts[curpart].name = "rootfs";
- parts[curpart].offset = rootfsaddr;
- parts[curpart].size = rootfslen;
- if (sparelen > 0)
- parts[curpart].size += sparelen;
- curpart++;
- };
- parts[curpart].name = "nvram";
- parts[curpart].offset = master->size - master->erasesize;
- parts[curpart].size = master->erasesize;
- for (i = 0; i < nrparts; i++) {
- printk("bcm963xx: Partition %d is %s offset %x and length %x\n", i, parts[i].name, parts[i].offset, parts[i].size);
- }
- *pparts = parts;
- vfree(buf);
- return nrparts;
-};