Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crc32.txt: standardize document format

Each text file under Documentation follows a different
format. Some doesn't even have titles!

Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:

- Add a title for the document;
- Mark literal blocks.

While here, replace a comma by a dot at the end of a paragraph.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>

authored by

Mauro Carvalho Chehab and committed by
Jonathan Corbet
2e4e6f30 e8cb6f1e

+42 -35
+42 -35
Documentation/crc32.txt
··· 1 - A brief CRC tutorial. 1 + ================================= 2 + brief tutorial on CRC computation 3 + ================================= 2 4 3 5 A CRC is a long-division remainder. You add the CRC to the message, 4 6 and the whole thing (message+CRC) is a multiple of the given ··· 10 8 is used by a lot of hardware implementations, and is why so many 11 9 protocols put the end-of-frame flag after the CRC. 12 10 13 - It's actually the same long division you learned in school, except that 11 + It's actually the same long division you learned in school, except that: 12 + 14 13 - We're working in binary, so the digits are only 0 and 1, and 15 14 - When dividing polynomials, there are no carries. Rather than add and 16 15 subtract, we just xor. Thus, we tend to get a bit sloppy about ··· 43 40 the polynomial from the remainder and we're back to where we started, 44 41 ready to process the next bit. 45 42 46 - A big-endian CRC written this way would be coded like: 47 - for (i = 0; i < input_bits; i++) { 48 - multiple = remainder & 0x80000000 ? CRCPOLY : 0; 49 - remainder = (remainder << 1 | next_input_bit()) ^ multiple; 50 - } 43 + A big-endian CRC written this way would be coded like:: 44 + 45 + for (i = 0; i < input_bits; i++) { 46 + multiple = remainder & 0x80000000 ? CRCPOLY : 0; 47 + remainder = (remainder << 1 | next_input_bit()) ^ multiple; 48 + } 51 49 52 50 Notice how, to get at bit 32 of the shifted remainder, we look 53 51 at bit 31 of the remainder *before* shifting it. ··· 58 54 32 bits later. Thus, the first 32 cycles of this are pretty boring. 59 55 Also, to add the CRC to a message, we need a 32-bit-long hole for it at 60 56 the end, so we have to add 32 extra cycles shifting in zeros at the 61 - end of every message, 57 + end of every message. 62 58 63 59 These details lead to a standard trick: rearrange merging in the 64 60 next_input_bit() until the moment it's needed. Then the first 32 cycles 65 61 can be precomputed, and merging in the final 32 zero bits to make room 66 - for the CRC can be skipped entirely. This changes the code to: 62 + for the CRC can be skipped entirely. This changes the code to:: 67 63 68 - for (i = 0; i < input_bits; i++) { 69 - remainder ^= next_input_bit() << 31; 70 - multiple = (remainder & 0x80000000) ? CRCPOLY : 0; 71 - remainder = (remainder << 1) ^ multiple; 72 - } 64 + for (i = 0; i < input_bits; i++) { 65 + remainder ^= next_input_bit() << 31; 66 + multiple = (remainder & 0x80000000) ? CRCPOLY : 0; 67 + remainder = (remainder << 1) ^ multiple; 68 + } 73 69 74 - With this optimization, the little-endian code is particularly simple: 75 - for (i = 0; i < input_bits; i++) { 76 - remainder ^= next_input_bit(); 77 - multiple = (remainder & 1) ? CRCPOLY : 0; 78 - remainder = (remainder >> 1) ^ multiple; 79 - } 70 + With this optimization, the little-endian code is particularly simple:: 71 + 72 + for (i = 0; i < input_bits; i++) { 73 + remainder ^= next_input_bit(); 74 + multiple = (remainder & 1) ? CRCPOLY : 0; 75 + remainder = (remainder >> 1) ^ multiple; 76 + } 80 77 81 78 The most significant coefficient of the remainder polynomial is stored 82 79 in the least significant bit of the binary "remainder" variable. ··· 86 81 87 82 As long as next_input_bit is returning the bits in a sensible order, we don't 88 83 *have* to wait until the last possible moment to merge in additional bits. 89 - We can do it 8 bits at a time rather than 1 bit at a time: 90 - for (i = 0; i < input_bytes; i++) { 91 - remainder ^= next_input_byte() << 24; 92 - for (j = 0; j < 8; j++) { 93 - multiple = (remainder & 0x80000000) ? CRCPOLY : 0; 94 - remainder = (remainder << 1) ^ multiple; 95 - } 96 - } 84 + We can do it 8 bits at a time rather than 1 bit at a time:: 97 85 98 - Or in little-endian: 99 - for (i = 0; i < input_bytes; i++) { 100 - remainder ^= next_input_byte(); 101 - for (j = 0; j < 8; j++) { 102 - multiple = (remainder & 1) ? CRCPOLY : 0; 103 - remainder = (remainder >> 1) ^ multiple; 86 + for (i = 0; i < input_bytes; i++) { 87 + remainder ^= next_input_byte() << 24; 88 + for (j = 0; j < 8; j++) { 89 + multiple = (remainder & 0x80000000) ? CRCPOLY : 0; 90 + remainder = (remainder << 1) ^ multiple; 91 + } 104 92 } 105 - } 93 + 94 + Or in little-endian:: 95 + 96 + for (i = 0; i < input_bytes; i++) { 97 + remainder ^= next_input_byte(); 98 + for (j = 0; j < 8; j++) { 99 + multiple = (remainder & 1) ? CRCPOLY : 0; 100 + remainder = (remainder >> 1) ^ multiple; 101 + } 102 + } 106 103 107 104 If the input is a multiple of 32 bits, you can even XOR in a 32-bit 108 105 word at a time and increase the inner loop count to 32.