2024年5月6日发(作者:疏山槐)
维普资讯
总第155期
舰船电子工程
V01.26 No.5
2OO6年第5期
Ship Electronic Eqgineeifng
87
TI TMS320C6000系列DSP平台下的
系统引导分析
丁宜栋武宗涛赫芳
(海军计算技术研究所北京100841)
摘要对TITMS320C60 ̄系列DSP软件系统的上电引导过程进行剖析,并对系统引导模块BOOT深入分析。通过对
引导模块中初始化函数AUTOINIT和初始化常量表CINIT的解析,使得开发人员对系统中变量的初始化有了全面的了解。
基于此,开发人员可以拓展自己的相关应用,如软件的版权保护。
关键词引导模块;CMD文件;MAP文件
中图分类号TIB9
Boot Process Analysis of TI TMS320C6(X ̄DSP Software System
Ding Yidong Wu zaogtao He Fang
(Navy Computing Technology Research Insittute, ̄ijmg 100841)
Abstract paper discusses the power—on boot process ofTI TMS320C6000 D 8oftwa ̄system and gi惴a i, ̄isht to the boot
module deeply.WitIl the resolve of boot module’s autoinit function and cinit table.the developers have a eomprehemive undemandign of
system’s variablei ̄iifalization.Based onthis,the developers can extend speciifc application oftheir own,for example,the copyright pro-
feet of software.
Key WOldS boot module,CMD me,map me
O.ms number蚴
1 引言 2上电引导过程
开发基于主机平台下的应用时,由于其上都有
11平台系统是从复位向量开始执行的。系统
操作系统,如Windows或Unix,因此,应用系统的载
加电后由硬件复位指令把代码搬移到片内程序存
人由于操作系统的介入而简单起来,开发人员不需
储器,然后从程序的0地址开始执行,首先执行的
要了解也不需要掌握系统的引导过程,只需专注于
是用户程序的RESET中断,该中断跳到用户引导
与应用紧密相关的设计开发。然而,与此不同的
模块BOOT的C—int00()函数人口。
是,在进行嵌入式开发时,目标板上通常都没有操 引导模块的名字为boot.C或boot.88m,可以从
作系统或者就算有也是把它们作为应用系统的一
系统库中提取出来,直接作为定制模块嵌入到用户
部分而对开发人员透明。因此,开发人员、特别是 的项目中去。不同系列的DSP对应不同的引导模
系统设计师需要全面掌握嵌入式应用开发的整个
块,也对应着不同的系统库,如62系列的系统库为
过程,尤其是引导过程,以便灵活驾驭嵌入式应用
rts6200.1ib或rts6200e.1ib,64系列的系统库为
的开发,并可根据自身需要进行不依赖于特定系统
rts6400.1ib或rts6400e.1ib,67系列的系统库为
工具的软件生成、版本制作及版权保护等。
rts6700.1ib或rts6700e.1ib。引导模块BOOT中C一
收稿日期:2006年2月26日,修回日期"2006年3月6日
维普资讯
丁宜栋等:TI TMS320C60 ̄系列DSP平台下的系统引导分析 总第155期
initO0()函数的主要作用是初始化C运行时环境并
调用系统函数auto—init()对初始化数据表cinit进
行解析。该表中存放的是声明为static的静态变量
和其它字符串常量。注意的是,声明为const的全
局变量不放在该表中,而是单独放在一起,是非格
式信息。
在该过程中,涉及到变量的初始化。该初始化
过程存在两种情形,一种是运行时刻的初始化,一
种是程序载人时刻的初始化,与链接器linker的选
项有关。前者使用一c选项进行链接,后者使用一
CR选项进行链接。
2.1运行时刻自动初始化
使用该种方法,cinit段与其它初始化段一起被
载人内存。链接器定义一个名字叫cinit的专门符
号,该符号指向内存初始化表的起始。当程序开始
运行时,C引导例程BOOT模块把cinit表中的数据
拷贝至BSS段中的相应变量,也就是用表中的数据
来初始化相应的内存变量。这就允许把初始化数
据事先存储于外部慢速存储器中(如FLASH ROM
或E2PROM)并在程序每次起始运行时再拷贝至快
速存储器(如片内存储器)其它快速零等待存储器,
以加快程序运行。图1给出了该过程的示意图。
Cinit
InilializationTabIe
.
cinit section
(SLOW—MEM)
B D0t
r 0L tilfe
.
bss section
(FAST—MEM)
J.
、
图1变量运行时刻初始化示意图
2.2载入时刻初始化
变量载人时刻初始化通过节省引导时间和初
始化表占用的内
存从而提高了性
能。当使用一cr
选项时,链接器
设置cinit段的段
头的
图2变量载入时刻初始化示意图COPY位,告诉装
载器LOADER不要把cinit段载入内存,同时设置
cinit符号为一1,告诉引导例程BOOT模块初始化
表不在内存。相应地,引导时也就不存在运行时刻
的初始化过程。图2给出了载人时刻的初始化示
意图。
3 引导模块
在,兀TMS320C6000 DSPS的引导过程期间,引
导模块BOOT起着非常重要的作用。具体来说,该
模块完成如下的功能:
・
设置系统堆栈
・
处理运行时间初始化表cinit和自动初始化
全局变量(当使用一e编译器选项时)
・
调用所有的全局结构函数constructor()
・
调用main()函数
・
当main()函数返回时调用exit()函数
也就是说,该引导模块完成所有的与系统底层
相关的操作后随即进入用户自己的程序,执行用户
自己的相关操作。在该期间,涉及到一个很重要的
操作,即解析初始化数据段或初始化表c
蛐 一 眦
init。默认
情况下,c编译器共创建如下一些初始化段,见表
1。
表1初始化段
显示初始化的全局和静态变量
用eonst修饰符修饰的全局和静态变量
大的switch语句的跳转表
可执行代码和常数
从表中可以看出,通常情况下,c编译器把常
量存放于cinit、const段,把代码段存放于text段。c
编译器为显式初始化的全局变量以及静态变量产
生一张数据表(系统中只有一张这样的表),并把它
们置于cinit段。该表具有如下格式:
表2初始化表cinit格式
.
cinjt seeti0n
[Initia
兵中,
[!zatio
初始化记录中的第一个字段为该记录的
nrecordn[
长度,即所有初始化数据的个数,以字节计。第二
个字段为初始化数据在BSS段中的起始位置。第
三个字段为该记录中的初始化数据。引导模块设
置完堆栈后,调用auto—init()函数。该函数完成对
cinit表的初始化。下面给出了该段函数的典型代
码。
void
auto
——
init(eonst void*cinit)
{
eonst ̄isned int recptr=cinit;
intlength;
if((int)Iecptr!=一1)/*若初始化数据表不为空*/
维普资讯
2OO6年第5期 舰船电子工程 89
{while((1ength=*reeptr++)!=0)/*若长度不为0
{ .
/*.einit表中每个记录的结构:第一个字段为以字节
计的长度,*/
/*第二个字段为要拷贝的数据在.Ms段中的地址,
/*第三个字段为要拷贝的数据*/I
char*to=(void*)*recptr++;/*指向.bss段中的
地址*/
char*from=(void*)reeptr;/*指向要拷贝的地址*/
/*把初始化数据表中的每个记录中的数据项*/
memepy(to,from,le ̄,th);
from+=length;/*移到下一个记录*/
reeptr=ALIGN
—
FIR(from);
}
}
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*Process Pinit table.*/
/ consists ofpointers to init fimc'dons.*/
, section is NUlL terminated ,
/ pointer is=一1 if section does not exist.*/
/*一一一一一一一一一一一一一一一一一一一一一一*/
if((int)一#nit一!:一1)
{
int i=0:
while(一#nit_[i]!=mJIZ)
一
pinit_[i++]();
}
}
Auto
—
init()函数的作用是解析einit表结构:
把表中的初始化数据根据表中的ram地址信息来
初始化相应的rain。因此,如果einit表中ram被定
义在片外的话,由于系统原boot模块默认情况下
并没有也不知道如何对片外ram进行初始化,在这
种情况下,如果表中存在定义在片外的静态变量的
话,那么系统引导模块boot中的自动初始化函数
auto
—
init()就无法对片外进行访问,也就无法对片
外ram进行初始化,从而导致系统无法正确引导,
程序也就无法正常运行。解决该问题的一种作法
是把静态变量全部定义到片内,这样的话,就不存
在上述的问题了。但是,对于规模较大的应用,把
静态变量全部定义到片内(片内资源是比较有限
的)是不现实的,因此,解决方案之二就是在使用片
外资源之前先行初始化,初始化之后就可以对片外
存储器进行访问了。
4定制引导模块
通常情况下,由于不同的硬件电路设计选型不
同的片外资源,如片外存储器。因此,可能需要定
制系统引导模块boot,把对片外初始化的代码加进
去,这样,系统boot就能够正确访问片外存储器,
从而也就能够正确解析einit表了,也能够对初始
化数据进行正确的访问,从而能够正确地引导。如
下图中的阴影部分即为系统引导模块BOOT中由
用户所添加。
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*THE SP MUSr BE ALIGNED ON AN 8一BⅥE BOUND.
ARY.
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*一7:取7的卒 码*/
一
asm(”and一7,SP,SP”);
/*在此处根据用户所选RAM的型号进行相应的初始化
::’::::E‘蛐 cEj0;=cr吐苫: X,0 :::’: :::I
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*S】 UP THE G10B^I.PAGE P0lIN IER IN B14.*/
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*C编译器把S bss定义为.bss段的起始地址
一
asm(”一global¥MS”);
一
asm(”mvkl SMS,DP'’);
一
asm(”mukh S SM,DP”);
图3定制用户自己的引导模块
5 结束语
通过文中对系统引导过程的分析,使得用户对
TMS320C系列DsP的引导可以有一个比较清晰和
全面的了解;通过einit表的解析,使得用户可以进
一
步加深对系统的深入了解并在此基础上扩展其
它应用,如对软件进行版权保护,对于从事嵌入式
应用开发的人员来讲有着现实的指导意义和具体
的借鉴作用。
参考文献
[1]丁宜栋.开发TMS320C6000 DSP嵌人式应用[J].现
代计算机,2000,(11):39—4o
2024年5月6日发(作者:疏山槐)
维普资讯
总第155期
舰船电子工程
V01.26 No.5
2OO6年第5期
Ship Electronic Eqgineeifng
87
TI TMS320C6000系列DSP平台下的
系统引导分析
丁宜栋武宗涛赫芳
(海军计算技术研究所北京100841)
摘要对TITMS320C60 ̄系列DSP软件系统的上电引导过程进行剖析,并对系统引导模块BOOT深入分析。通过对
引导模块中初始化函数AUTOINIT和初始化常量表CINIT的解析,使得开发人员对系统中变量的初始化有了全面的了解。
基于此,开发人员可以拓展自己的相关应用,如软件的版权保护。
关键词引导模块;CMD文件;MAP文件
中图分类号TIB9
Boot Process Analysis of TI TMS320C6(X ̄DSP Software System
Ding Yidong Wu zaogtao He Fang
(Navy Computing Technology Research Insittute, ̄ijmg 100841)
Abstract paper discusses the power—on boot process ofTI TMS320C6000 D 8oftwa ̄system and gi惴a i, ̄isht to the boot
module deeply.WitIl the resolve of boot module’s autoinit function and cinit table.the developers have a eomprehemive undemandign of
system’s variablei ̄iifalization.Based onthis,the developers can extend speciifc application oftheir own,for example,the copyright pro-
feet of software.
Key WOldS boot module,CMD me,map me
O.ms number蚴
1 引言 2上电引导过程
开发基于主机平台下的应用时,由于其上都有
11平台系统是从复位向量开始执行的。系统
操作系统,如Windows或Unix,因此,应用系统的载
加电后由硬件复位指令把代码搬移到片内程序存
人由于操作系统的介入而简单起来,开发人员不需
储器,然后从程序的0地址开始执行,首先执行的
要了解也不需要掌握系统的引导过程,只需专注于
是用户程序的RESET中断,该中断跳到用户引导
与应用紧密相关的设计开发。然而,与此不同的
模块BOOT的C—int00()函数人口。
是,在进行嵌入式开发时,目标板上通常都没有操 引导模块的名字为boot.C或boot.88m,可以从
作系统或者就算有也是把它们作为应用系统的一
系统库中提取出来,直接作为定制模块嵌入到用户
部分而对开发人员透明。因此,开发人员、特别是 的项目中去。不同系列的DSP对应不同的引导模
系统设计师需要全面掌握嵌入式应用开发的整个
块,也对应着不同的系统库,如62系列的系统库为
过程,尤其是引导过程,以便灵活驾驭嵌入式应用
rts6200.1ib或rts6200e.1ib,64系列的系统库为
的开发,并可根据自身需要进行不依赖于特定系统
rts6400.1ib或rts6400e.1ib,67系列的系统库为
工具的软件生成、版本制作及版权保护等。
rts6700.1ib或rts6700e.1ib。引导模块BOOT中C一
收稿日期:2006年2月26日,修回日期"2006年3月6日
维普资讯
丁宜栋等:TI TMS320C60 ̄系列DSP平台下的系统引导分析 总第155期
initO0()函数的主要作用是初始化C运行时环境并
调用系统函数auto—init()对初始化数据表cinit进
行解析。该表中存放的是声明为static的静态变量
和其它字符串常量。注意的是,声明为const的全
局变量不放在该表中,而是单独放在一起,是非格
式信息。
在该过程中,涉及到变量的初始化。该初始化
过程存在两种情形,一种是运行时刻的初始化,一
种是程序载人时刻的初始化,与链接器linker的选
项有关。前者使用一c选项进行链接,后者使用一
CR选项进行链接。
2.1运行时刻自动初始化
使用该种方法,cinit段与其它初始化段一起被
载人内存。链接器定义一个名字叫cinit的专门符
号,该符号指向内存初始化表的起始。当程序开始
运行时,C引导例程BOOT模块把cinit表中的数据
拷贝至BSS段中的相应变量,也就是用表中的数据
来初始化相应的内存变量。这就允许把初始化数
据事先存储于外部慢速存储器中(如FLASH ROM
或E2PROM)并在程序每次起始运行时再拷贝至快
速存储器(如片内存储器)其它快速零等待存储器,
以加快程序运行。图1给出了该过程的示意图。
Cinit
InilializationTabIe
.
cinit section
(SLOW—MEM)
B D0t
r 0L tilfe
.
bss section
(FAST—MEM)
J.
、
图1变量运行时刻初始化示意图
2.2载入时刻初始化
变量载人时刻初始化通过节省引导时间和初
始化表占用的内
存从而提高了性
能。当使用一cr
选项时,链接器
设置cinit段的段
头的
图2变量载入时刻初始化示意图COPY位,告诉装
载器LOADER不要把cinit段载入内存,同时设置
cinit符号为一1,告诉引导例程BOOT模块初始化
表不在内存。相应地,引导时也就不存在运行时刻
的初始化过程。图2给出了载人时刻的初始化示
意图。
3 引导模块
在,兀TMS320C6000 DSPS的引导过程期间,引
导模块BOOT起着非常重要的作用。具体来说,该
模块完成如下的功能:
・
设置系统堆栈
・
处理运行时间初始化表cinit和自动初始化
全局变量(当使用一e编译器选项时)
・
调用所有的全局结构函数constructor()
・
调用main()函数
・
当main()函数返回时调用exit()函数
也就是说,该引导模块完成所有的与系统底层
相关的操作后随即进入用户自己的程序,执行用户
自己的相关操作。在该期间,涉及到一个很重要的
操作,即解析初始化数据段或初始化表c
蛐 一 眦
init。默认
情况下,c编译器共创建如下一些初始化段,见表
1。
表1初始化段
显示初始化的全局和静态变量
用eonst修饰符修饰的全局和静态变量
大的switch语句的跳转表
可执行代码和常数
从表中可以看出,通常情况下,c编译器把常
量存放于cinit、const段,把代码段存放于text段。c
编译器为显式初始化的全局变量以及静态变量产
生一张数据表(系统中只有一张这样的表),并把它
们置于cinit段。该表具有如下格式:
表2初始化表cinit格式
.
cinjt seeti0n
[Initia
兵中,
[!zatio
初始化记录中的第一个字段为该记录的
nrecordn[
长度,即所有初始化数据的个数,以字节计。第二
个字段为初始化数据在BSS段中的起始位置。第
三个字段为该记录中的初始化数据。引导模块设
置完堆栈后,调用auto—init()函数。该函数完成对
cinit表的初始化。下面给出了该段函数的典型代
码。
void
auto
——
init(eonst void*cinit)
{
eonst ̄isned int recptr=cinit;
intlength;
if((int)Iecptr!=一1)/*若初始化数据表不为空*/
维普资讯
2OO6年第5期 舰船电子工程 89
{while((1ength=*reeptr++)!=0)/*若长度不为0
{ .
/*.einit表中每个记录的结构:第一个字段为以字节
计的长度,*/
/*第二个字段为要拷贝的数据在.Ms段中的地址,
/*第三个字段为要拷贝的数据*/I
char*to=(void*)*recptr++;/*指向.bss段中的
地址*/
char*from=(void*)reeptr;/*指向要拷贝的地址*/
/*把初始化数据表中的每个记录中的数据项*/
memepy(to,from,le ̄,th);
from+=length;/*移到下一个记录*/
reeptr=ALIGN
—
FIR(from);
}
}
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*Process Pinit table.*/
/ consists ofpointers to init fimc'dons.*/
, section is NUlL terminated ,
/ pointer is=一1 if section does not exist.*/
/*一一一一一一一一一一一一一一一一一一一一一一*/
if((int)一#nit一!:一1)
{
int i=0:
while(一#nit_[i]!=mJIZ)
一
pinit_[i++]();
}
}
Auto
—
init()函数的作用是解析einit表结构:
把表中的初始化数据根据表中的ram地址信息来
初始化相应的rain。因此,如果einit表中ram被定
义在片外的话,由于系统原boot模块默认情况下
并没有也不知道如何对片外ram进行初始化,在这
种情况下,如果表中存在定义在片外的静态变量的
话,那么系统引导模块boot中的自动初始化函数
auto
—
init()就无法对片外进行访问,也就无法对片
外ram进行初始化,从而导致系统无法正确引导,
程序也就无法正常运行。解决该问题的一种作法
是把静态变量全部定义到片内,这样的话,就不存
在上述的问题了。但是,对于规模较大的应用,把
静态变量全部定义到片内(片内资源是比较有限
的)是不现实的,因此,解决方案之二就是在使用片
外资源之前先行初始化,初始化之后就可以对片外
存储器进行访问了。
4定制引导模块
通常情况下,由于不同的硬件电路设计选型不
同的片外资源,如片外存储器。因此,可能需要定
制系统引导模块boot,把对片外初始化的代码加进
去,这样,系统boot就能够正确访问片外存储器,
从而也就能够正确解析einit表了,也能够对初始
化数据进行正确的访问,从而能够正确地引导。如
下图中的阴影部分即为系统引导模块BOOT中由
用户所添加。
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*THE SP MUSr BE ALIGNED ON AN 8一BⅥE BOUND.
ARY.
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*一7:取7的卒 码*/
一
asm(”and一7,SP,SP”);
/*在此处根据用户所选RAM的型号进行相应的初始化
::’::::E‘蛐 cEj0;=cr吐苫: X,0 :::’: :::I
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*S】 UP THE G10B^I.PAGE P0lIN IER IN B14.*/
/*一一一一一一一一一一一一一一一一一一一一一一*/
/*C编译器把S bss定义为.bss段的起始地址
一
asm(”一global¥MS”);
一
asm(”mvkl SMS,DP'’);
一
asm(”mukh S SM,DP”);
图3定制用户自己的引导模块
5 结束语
通过文中对系统引导过程的分析,使得用户对
TMS320C系列DsP的引导可以有一个比较清晰和
全面的了解;通过einit表的解析,使得用户可以进
一
步加深对系统的深入了解并在此基础上扩展其
它应用,如对软件进行版权保护,对于从事嵌入式
应用开发的人员来讲有着现实的指导意义和具体
的借鉴作用。
参考文献
[1]丁宜栋.开发TMS320C6000 DSP嵌人式应用[J].现
代计算机,2000,(11):39—4o