Example #1
0
        public bool WriteImage(Stream ImageStream)
        {
            if (Images == null || ImageStream == null)
            {
                return(false);
            }
            if (Images.Count == 0)
            {
                return(false);
            }

            try
            {
                BinaryWriter writer = new BinaryWriter(ImageStream);

                // Write the boot header to various locations
                // 0x00000, 0x20000, 0x40000 and 0x60000
                for (int block = 0; block < 4; block++)
                {
                    writer.BaseStream.Seek(0x20000 * block, SeekOrigin.Begin);
                    if (!WriteBootHeader(writer, Header))
                    {
                        return(false);
                    }
                }

                // When writing the bootloader, there is a copy at 0x1f000, 0x3f000, 0x5f000
                // and at 0x7f000
                // Copy the headers and data over
                for (int copyIter = 0; copyIter < 4; copyIter++)
                {
                    // Seek to the end page of the block
                    writer.BaseStream.Seek((0x10000 + (0x20000 * copyIter)) | 0xf000, SeekOrigin.Begin);

                    // Write the preamble
                    // First, seek to the last page of the block
                    try
                    {
                        // Now write the magic
                        writer.Write((uint)0x574255aa);
                        // Then write the number of images
                        writer.Write((uint)Images.Count);
                        // Now skip one 32 bit word
                        writer.BaseStream.Seek(sizeof(uint), SeekOrigin.Current);
                        // Finally write the last magic
                        writer.Write((uint)0x57425963);
                    }
                    catch (Exception)
                    {
                        return(false);
                    }

                    // Write all the images
                    ushort block = 0;
                    for (ushort imageID = 0; imageID < Images.Count; imageID++)
                    {
                        // Retrieve the image
                        ImageEntry  img  = Images[imageID];
                        ImageHeader head = new ImageHeader();
                        ushort      numBlocks;

                        if (!CheckEntry(img))
                        {
                            return(false);
                        }

                        // Calculate the blocks
                        if (imageID == 0)
                        {
                            numBlocks = 3;
                        }
                        else
                        {
                            numBlocks = CalculateBlocks(img.Data.Length);
                        }

                        // Construct the header
                        head.ImageID        = imageID;
                        head.ImageName      = img.Name;
                        head.ImageType      = img.Type;
                        head.StartBlock     = block;
                        head.EndBlock       = (ushort)(head.StartBlock + numBlocks);
                        head.ExecuteAddress = img.ExecAddr;
                        head.FileSize       = (uint)img.Data.Length;

                        // On the bootloader image, adjust the size
                        if (imageID == 0)
                        {
                            head.FileSize += 0x20;
                        }

                        // Write the header
                        if (!WriteEntryHeader(writer, head))
                        {
                            return(false);
                        }

                        // On the first write of every image, write the data
                        // For id 0, write it every time to a new location
                        if (copyIter == 0 || imageID == 0)
                        {
                            uint offset;
                            if (imageID == 0)
                            {
                                offset = (uint)((copyIter * BytesPerBlock) + 0x20);
                            }
                            else
                            {
                                offset = (uint)(block * BytesPerBlock);
                            }

                            if (!WriteEntryData(writer, img, offset))
                            {
                                return(false);
                            }
                        }

                        block += numBlocks;
                    }
                }
            }
            catch (Exception)
            {
                return(false);
            }

            return(true);
        }