Referring to sprabb1b.pdf "Using the TMS320C6747/45/43 Bootloader" there is some pseudo-code for the CRC calculation. Code quoted at the end of this post for reference. I think it has some errors. Also I have some questions and comments about things that could be better documented.
1. The decrement of bit_no needs to happen at the end of the while loops
2. In the incomplete last word processing, word = (word << remain * 8) >> remain * 8; the byte shift for padding should be (4 - remain), not current 'remain'
3. In the crc calc crc = ((word >> bit_no) & 0x1) ^ (crc << 1); , the xor "^" can be replaced with a simple or "|"
I
have verified that with changes 1..3, this generates the same CRC as
the AISgen gui. (I haven't yet verifed that the bootloader actually
accepts these CRCs...)
4. Note that the CRC is calculated over the ADDRESS and SIZE parameters of the section load command, plus all the data. (found this by trawling AISgen source code)
5. Note that this 'CRC' is not the same as the 'normal' CRC-32 calculation, which would append 32 zero bits to the end of the data and include those in the iteration. I.e. you can't use CRC-32 routines from a library to generate AIS CRCs.
6. For the Section Fill command, is the CRC calculated just over the parameters of the command as present in the AIS file and read from ROM, or also over the expanded data as filled into RAM?
7. Does the Validate CRC command also restart (zero initial crc for) the CRC calculation for subsequent section(s)? (apparently yes?)
8. Referring now to OMAP-L138_FlashAndBootUtils_2_30:
When an input section has a length not a multiple of 4 bytes, AISgen emits an AIS section load command with the size field rounded up to the next multiple of 4. The padding byte(s) are non-zero, (In my case it is one byte 0x25) and the CRC includes them. But sprabb1b says "If the length of the section content is not a multiple of 4 bytes, appropriate zero padding is added to make it so; zero padding is not reflected in the SIZE argument." I assume the CRC should only be calculated over SIZE bytes, not including padding.
CRC calc from appendix C of sprabb1b:
// Process complete 32-bit words
for (size / 4)
{
// Load a word from memory
word = *dataPtr++;
// Update CRC
bit_no = 31;
while (bit_no >= 0)
{
bit_no--;
msb_bit = crc & 0x80000000;
crc = ((word >> bit_no) & 0x1) ^ (crc << 1);
if (msb_bit)
crc ^= 0x04C11DB7;
}
// CRC-32 polynomial
}
// Process incomplete last word if present
if (remain = size % 4)
{
word = *dataPtr;
// Pad incomplete word with zeros to make it complete
word = (word << remain * 8) >> remain * 8;
// Update CRC
bit_no = 31;
while (bit_no >= 0)
{
bit_no--;
msb_bit = crc & 0x80000000;
crc = ((word >> bit_no) & 0x1) ^ (crc << 1);
if (msb_bit)
crc ^= 0x04C11DB7;
}
// CRC-32 polynomial
}