在PowerPC的学习中经常碰到S record 格式,下面对它做一个解释:
//========================================================================
//TITLE:
// S-Record格式详解
//AUTHOR:
// norains
//DATE:
// Friday 25-April-2008
//Environment:
// NULL
//========================================================================
一个完整的MOTOROLA S-Record格式数据包含如下区域:
<type> <length> <address> <data> <checksum>
各字段的意思分别如下:
<type>:标示记录的类型,该字段占据1-byte。它可以有如下 数值:“S0”, “S1”, “S2”, “S3”, “S5”, “S7”, “S8” , “S9”
“S0” -- 记录描述信息
“S1”, “S2”, “S3” -- 记录存储的数据。这三者的区别在于地址(address)的长度不同,S1为2-byte,S2为3-byte,以及S3为4-byte。
“S5” -- 包含了“S1”, “S2”, “S3”的信息。
“S7”, “S8”, “S9” -- 确定程序的开始地址。这三者的区别也在于地址(address)的长度不同,S9为2-byte,S8为3-byte,以及S7为4-byte。
<length>:标示了数据的长度,确切地说,是 <address>, <data> 和<checksum>这三个字段的byte的个数。该字段占据1-byte。
<address>:标示了数据写入的起始地址。该字段的长度取决于<type>的取值。
<data>:标示了存储的数据。该字段占据的byte个数可以这样计算:<length>的值 - <address>字段的长度(取值为2、3、4) - 1(<checksum>字段的长度)
<checksum>:标示校验位,占据1-byte。该数据可以由<address>和<data>的数据累加然后每bit取反获得。
最后我们以一条数据记录格式作为例子:
S30A801000930300000000CF
S3是记录的格式(<type>)。
0A是长度(<length>),为十六进制,标识有10个byte。因为两个十六进制才是1-byte,所以801000930300000000CF的长度为10而不是20.换句话说,这数据列应该如此表示:80 10 00 93 03 00 00 00 00 CF。
因为type是S3,所以地址(<address>)占4-byte,因此需要写入的地址为:0x80100093。
既然已经知道了地址,那么数据(<data>)很显然就是0x0300000000了。
最后的1-byte就是校验位(<chksum>)。例子数值由此得来:0xFF - ((0x0A + 0x80 + 0x10 + 0x00 + 0x93 + 0x03 + 0x00 + 0x00 + 0x00 + 0x00) & 0xFF)
=============================================================================
S19格式文件详解(S-record)
S-record格式文件是Freescale CodeWarrior编译器生成的后缀名为.S19的程序文件,是一段直接烧写进MCU的ASCII码,英文全称问Motorola format for EEPROM programming。
网上有关S-record格式文件的资料很少,经过我的收集和实验,整理出以下文档,方便大家对Freescale单片机做深入了解。
1、格式定义及含义
S-record每行最大是78个字节,156个字符
S-record format
type | count | address | data | checksum |
type(类型):2个字符。用来描述记录的类型 (S0,S1,S2,S3,S5,S7,S8,S9)。
count(计数):2个字符。 用来组成和说明了一个16进制的值,显示了在记录中剩余成对字符的计数。
address(地址):4或6或8个字节。用来组成和说明了一个16进制的值,显示了数据应该装载的地址, 这部分的长度取决于载入地址的字节数。2个字节的地址占用4个字符,3个字节的地址占用6个字符,4个字节的地址占用8个字符。
data(数据):0—64字符。用来组成和说明一个代表了内存载入数据或者描述信息的16进制的值。
checksum(校验和):2个字符。这些字符当被配对并换算成16进制数据的时候形成了一个最低有效字符节,该字符节用来表达作为补充数据,地址和数据库的字符对所代表的(字节的)补码的byte总和。即计数值、地址场和数据场的若干字符以两个字符为一对,将它们相加求和,和的溢出部分不计,只保留最低两位字符NN,checksum =0xFF-0xNN。
S0 Record:记录类型是“S0” (0x5330)。地址场没有被用,用零置位(0x0000)。数据场中的信息被划分为以下四个子域:
name(名称):20个字符,用来编码单元名称
ver(版本):2个字符,用来编码版本号
rev(修订版本):2个字符,用来编码修订版本号
description(描述):0-36个字符,用来编码文本注释
此行表示程序的开始,不需烧入memory。
S1 Record:记录类型是“S1” (0x5331)。地址场由2个字节地址来说明。数据场由可载入的数据组成。
S2 Record:记录类型是“S2” (0x5332)。地址场由3个字节地址来说明。数据场由可载入的数据组成。
S3 Record:记录类型是“S3” (0x5333)。地址场由4个字节地址来说明。数据场由可载入的数据组成。
S5 Record:记录类型是“S5” (0x5335)。地址场由2字节的值说明,包含了先前传输的S1、S2、S3记录的计数。没有数据场。
S7 Record:记录类型是“S7” (0x5337)。地址场由4字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
S8 Record:记录类型是“S8” (0x5338)。地址场由3字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
S9 Record:记录类型是“S9” (0x5339)。地址场由2字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
根据不同的描述信息,在以上三种不同的结束行中选择一种使用
2、EXAMPLE
2.1 example I
S19文件首行: S021000036384B50524F47202020313143524541544544204259204541535936384B6D
首行翻译信息: S0 0000 6 8 K P R O G 1 1 C R E A T E D B Y E A S Y 6 8 K
色块图例:module name version number revision number checksum
checksum的算法:
0x21+0x00+0x00+0x36+0x38+0x4B+0x50+0x52+0x4F+0x47+0x20+0x20+0x20+0x31+0x31+0x43+0x52+0x45+0x41+0x54+0x45+0x44
+0x20+0x42+0x59+0x20+0x45+0x41+0x53+0x59+0x36+0x38+0x4B=0x792
checksum=0xFF-0x92=6D
注意:EASy68K总是用S8 record作为结束行。
2.2 example II
S123C000CF1400790011CC09395B105A124A8046304A8000300001C01BCB73140007340027
色块图例:type count address data checksum
2.3 example III
S224308000C61E877C1516C6197B151ACE04C07E15187A153EC74A90F9301D026A01C6017BF0
色块图例:type count address data checksum
3、另附Freescale HCS12DP256B 16位单片机空程序S19文件:
S0520000453A5C576F6F64795C4C6561726E696E675C50726F6772616D6D655C42444DD2FDB5BCB3CCD0F25C44556D795C447032 35365C62696E5C48435331325F53657269616C5F4D6F6E69746F722E6162735A
S123C000CF1100790011CC09395B105A124A8004304A8000300000C01BC01F00000000001B
S104C020001B
S105FFFEC0003D
S22430800010EF20FEFEC017FDC015270E35ED31EC3169700434FB310326F2FEC019EC31274F
S2113080200BED31180A30700434F920F10AE7
S804000000FB
大家可以尝试理解一下。
=====================================================================
objcopy
copy and translate object files:
- 複製 .o 檔 (obj file) 的內部內容到另一個檔案中 (.o 檔或是單純地做 hex dump)
- 將一個 binary data (如JPEG 圖片) 做成 .o 檔
- 把執行碼從 ELF 中抽取出來
- 只抽取指定的 section
常用參數
objcopy [`-I' bfdname|`--input-target='bfdname]
[`-O' bfdname|`--output-target='bfdname]
[`-B' bfdarch|`--binary-architecture='bfdarch]
[`-S'|`--strip-all']
[`-g'|`--strip-debug']
[`-j' sectionname|`--only-section='sectionname]
[`-R' sectionname|`--remove-section='sectionname]
[`--help']
infile [outfile]
GNU binutil manual
使用範例
- 列出可用的 BFD target
$ objdump -i BFD header file version (GNU Binutils for Ubuntu) 2.18 elf32-i386 (header little endian, data little endian) i386 a.out-i386-linux (header little endian, data little endian) i386 efi-app-ia32 (header little endian, data little endian) i386 elf32-little (header little endian, data little endian) i386 elf32-big (header big endian, data big endian) i386 elf64-x86-64 (header little endian, data little endian) i386 efi-app-x86_64 (header little endian, data little endian) i386 elf64-little (header little endian, data little endian) i386 elf64-big (header big endian, data big endian) i386 srec (header endianness unknown, data endianness unknown) i386 symbolsrec (header endianness unknown, data endianness unknown) i386 tekhex (header endianness unknown, data endianness unknown) i386 binary (header endianness unknown, data endianness unknown) i386 ihex (header endianness unknown, data endianness unknown) i386 trad-core (header endianness unknown, data endianness unknown) elf32-i386 a.out-i386-linux efi-app-ia32 elf32-little elf32-big i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf32-little elf32-big elf64-x86-64 efi-app-x86_64 elf64-little elf64-big srec i386 elf64-x86-64 efi-app-x86_64 elf64-little elf64-big srec symbolsrec tekhex binary ihex trad-core i386 symbolsrec tekhex binary ihex ---------
- 將一個 JPEG 圖片檔 做成 .o 檔
$ objcopy -I binary -O elf32-i386 -B i386 image.jpg image.o
- 把執行碼從 ELF 中抽取出來,去除 symbol table, relocation information, .comment section, 和 .note section
$ objcopy -O binary -S -R .comment -R .note code.o code.bin
- 只抽取指定的 section
$ objcopy -O binary -j .text code.o code.bin