继续分析原来的代码,现在已经进入一个比较重要的函数dbginit(),因此这个函数相当复杂的功能调用。
/*
*Init PMON and debug
*/
cpuinfotab[0] = &DBGREG;
dbginit(NULL);
第一行代码cpuinfotab[0]保存DBG寄存器值,主要包括32个通用寄存器和CP0的32寄存器,以及两个乘法除法这寄存器。
现在就来仔细地查看dbginit(NULL)的实现,代码如下:
/*
*PMON2000 entrypoint. Called after initial setup.
*/
void
dbginit (char *adr)
{
int memsize, freq;
char fs[10], *fp;
char *s;
/*splhigh();*/
memsize = memorysize;
上面保存低端256M内存大小。
__init();/* Do all constructor initialisation */
上面调用初始化C++的构造函数初始化和全局的静态变量。
SBD_DISPLAY ("ENVI", CHKPNT_ENVI);
envinit ();
上面初始化环境变量。
#if defined(SMP)
/* Turn on caches unless opted out */
if (!getenv("nocache"))
md_cacheon();
#endif
上面打开缓存。
SBD_DISPLAY ("SBDD", CHKPNT_SBDD);
tgt_devinit();
上面特定的主板初始化。
#ifdef INET
SBD_DISPLAY ("NETI", CHKPNT_NETI);
init_net (1);
#endif
上面选择网络初始化。
#if NCMD_HIST > 0
SBD_DISPLAY ("HSTI", CHKPNT_HSTI);
histinit ();
#endif
上面初始化是否缓存过去的命令。
#if NMOD_SYMBOLS > 0
SBD_DISPLAY ("SYMI", CHKPNT_SYMI);
syminit ();
#endif
上面选择是否设置符号表初始化。
#ifdef DEMO
SBD_DISPLAY ("DEMO", CHKPNT_DEMO);
demoinit ();
#endif
上面选择是否初始化演示功能。
SBD_DISPLAY ("SBDE", CHKPNT_SBDE);
initial_sr |= tgt_enable (tgt_getmachtype ());
上面保存状态寄存器。
#ifdef SR_FR
Status = initial_sr & ~SR_FR; /* don't confuse naive clients */
#endif
/* Set up initial console terminal state */
ioctl(STDIN, TCGETA, &consterm);
上面初始化终端输出。
#ifdef HAVE_LOGO
tgt_logo();
#else
printf ("/n * PMON2000 Professional *");
#endif
printf ("/nConfiguration [%s,%s", TARGETNAME,
BYTE_ORDER == BIG_ENDIAN ? "EB" : "EL");
上面显示LOGO和显示字节顺序。龙芯是小端格式。
#ifdef INET
printf (",NET");
#endif
#if NSD > 0
printf (",SCSI");
#endif
#if NWD > 0
printf (",IDE");
#endif
printf ("]/nVersion: %s./n", vers);
printf ("Supported loaders [%s]/n", getExecString());
printf ("Supported filesystems [%s]/n", getFSString());
printf ("This software may be redistributed under the BSD copyright./n");
上面显示提示信息。
tgt_machprint();
上面显示厂家信息。
freq = tgt_pipefreq ();
sprintf(fs, "%d", freq);
fp = fs + strlen(fs) - 6;
fp[3] = '/0';
fp[2] = fp[1];
fp[1] = fp[0];
fp[0] = '.';
printf (" %s MHz", fs);
上面显示总线的频率。
freq = tgt_cpufreq ();
sprintf(fs, "%d", freq);
fp = fs + strlen(fs) - 6;
fp[3] = '/0';
fp[2] = fp[1];
fp[1] = fp[0];
fp[0] = '.';
printf (" / Bus @ %s MHz/n", fs);
上面显示CPU频率。
printf ("Memory size %3d MB (%3d MB Low memory, %3d MB High memory) ./n", (memsize+memorysize_high)>>20,
(memsize>>20), (memorysize_high>>20));
tgt_memprint();
上面显示内存的大小。
#if defined(SMP)
tgt_smpstartup();
#endif
上面选择多CPU的初始化。
printf ("/n");
md_clreg(NULL);
md_setpc(NULL, (int32_t) CLIENTPC);
md_setsp(NULL, tgt_clienttos ());
上面清空保存寄存器的变量,并保存新的PC值和堆栈值。
#ifdef AUTOLOAD
s = getenv ("al");
autoload (s);
#else
s = getenv ("autoboot");
autorun (s);
#endif
上面设置是否自动加载操作系统文件。
}
这个函数做了很多工作,下面要仔细地分析每个子函数实现的功能,才能理解后面所做的工作,否则也不知道后面会做些什么。又进入下一层函数分析它的实现。
首先来了解怎么样初始化C++的构函数和全局静态变量。仔细地看一下函数__init(),如下:
void
__init()
{
static int initialized = 0;
/*
* Call global constructors.
* Arrange to call global destructors at exit.
*/
if (!initialized) {
initialized = 1;
__ctors();
}
}
在这个函数里,先判断是否已经初始化全局函数和构造函数,如果没有初始化,就设置为已经初始化,接着调用函数初始化全局__ctors()函数。也许你会问,这些全局函数从那里来的呢?如果你去看看GCC的连接说明文件,就会发现有这个段在那里,因此这些全局函数是由编译器生成的,并不是由用户定义。如果不调用这些全局初始化函数,很多全局变量是没有定义的值,本来你编程时初始化为100的值,可能只是0或者任意的数值。现在又立即去看函数__ctors()的实现,如下:
static void
__ctors()
{
void (**p)(void) = __CTOR_LIST__ + 1;
while (*p)
(**p++)();
}
由于GCC编译器会根据连接文件生成全局调用函数,下面就是连接文件相关内容,如下:
.ctors :
{
__CTOR_LIST__ = .;
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
__CTOR_END__ = .;
}
.dtors :
{
__DTOR_LIST__ = .;
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
__DTOR_END__ = .;
}
编译器就会根据上面的连接脚本生成全局初始化函数和全局析构函数,并且每个函数入口是按照4字节的指针排列的。因此,在函数__ctors()里循环地调用所有函数运行一遍。后面析构函数相应也调用函数__dtors()来实现的。
分享到:
相关推荐
龙芯软件开发------蔡军生.pdf
UOS服务器版MIPS架构龙芯openjdk-8-jdk离线安装包及依赖
龙芯Pmon-gcc-64位编译
此包架构是:龙芯--loongarch JDK版本:jdk-v8.0 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是做...
龙芯系列处理器是中国科学院计算所研制的具有自主知 识产权的通用处理器,它具有低功耗、低成本的特点。龙芯 2E 处理器[3] 是一款实现 64 bit MIPS III 指令集的通用 RISC 处理器。 龙芯 2E 的指令流水线每个时钟...
此包架构是:龙芯--mips 该包版本:jdk-openjdk-1.8 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是...
此包架构是:龙芯--mips 该包版本:nginx-v1.18 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是做...
此包架构是:龙芯--mips 该包版本:mariadb-v10.3 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是做...
龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是做国产软件的,这些必须测试成功,到客户那里直接安装和使用 安装命令: sudo dpkg -i 你的路径/*.deb 安装完可以直接使用 查看是否...
此包架构是:龙芯--loongarch JDK版本:jdk-v8.0 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是做...
此包架构是:龙芯--loongarch 数据库版本:mariadb-v10.3 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司...
使用方式见龙芯杯比赛文档,或者链接:https://oscourse-tsinghua.gitbook.io/loongsoncsprj2020-manual/ucore/long-xin-bian-yi-huan-jing-pei-zhi
此包架构是:龙芯-loongarch 数据库版本:mariadb-v10.3 特意买了几台国产机器安装和测试,有多种CPU电脑测试(1.飞腾-鲲鹏--arm64,2.龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司...
基于SimpleScalar的龙芯CPU模拟器Sim-Godson.pdf
全面介绍龙芯平台的软件开发。剖析各个硬件子模块的初始化过程。致力于国产CPU龙芯平台开发的童鞋不要错过了。
帮助解决龙芯内存参数调试过程中遇到的各种问题,比如;PMON 在263Mhz的频率下能较稳定跑过去,过400 就会直接hang在copy PMON to memory。 S1 SPD 参数的设置 各种内存宏定义 调试模式 调试等等。。
龙芯ls1b-pwm-Led
龙芯--loongarch,3.龙芯--mips,4.兆芯-海光-intel-AMD--X86) 因为我们公司也是做国产软件的,这些必须测试成功,到客户那里直接安装和使用 安装命令: sudo dpkg -i 你的路径/*.deb 安装完可以直接使用 查看是否...
龙芯Loongson2K1000_data数据手册,硬件设计必备材料,软件开发参考.
龙芯中科--龙芯信息化平台的应用迁移工作思考,转自微信号“龙芯中科”