因为需要,我现在想要用secondary master上启动VxWorks,
bootline这样写:
"ata=1,0(0,0) host:/ata0/vxworks h=10.0.0.1 e=10.0.0.2 u=target"
启动后,发现调用ataload函数失败,不能初始化硬盘,添加打印信息发现,
在调用ataDrv时,不能接收到硬盘中断,导致不能获得相应的信号量,引起错误。
怎样才能初始化secondary master上的硬盘呢?请高手指点。
VxWorks是从0,0开始初始化硬盘的,你可以从target/config/comps/vxworks/10bsp.cdf文件的对INCLUDE_ATA组件看出来,它给DOSFS_NAMES_ATA_PRIMARY_MASTER这个参数定义了一个默认值为/ata0a,其它的为空。在INCLUDE_ATA组件的初始化函数里面可以看出,顺序是DOSFS_NAMES_ATA_PRIMARY_MASTER、DOSFS_NAMES_ATA_PRIMARY_SLAVE、DOSFS_NAMES_ATA_SECONDARY_MASTER、DOSFS_NAMES_ATA_SECONDARY_SLAVE,而且判断依据是名字是否为“”即空字符串。所以解决方法可能有3个:
其一:在配置VxWorks映象的里面,改上面这些宏,把DOSFS_NAMES_ATA_PRIMARY_MASTER搞为空,你想要的才有值;
其二:把这个组件做个本地修改(注意是本地修改,不要修改target/config/comps目录下的任何文件),方法是在bsp目录下创建一个cdf文件,把INCLUDE_ATA给改了。
其三:在config.h文件里面直接设置好上述宏,生成映象的时候就不要再修改了。。。。。
我的问题不是在VxWork image执行的时候,是在boot image执行的时候,当我引导行像上面的方式写的话,ataDrv函数返回错误,根本无法初始化硬盘,连"Attaching to ATA disk device..."这句话都不会出来,也就是还没有执行到usrAtaConfig这个函数。
在bootConfig.c中,会初始化硬盘,调用ataLoad函数,主要代码如下:
if (ataDrv (ctrl, pAtaResource->drives, pAtaResource->intVector,
pAtaResource->intLevel, pAtaResource->configType,
pAtaResource->semTimeout, pAtaResource->wdgTimeout) == ERROR) //现在我的问题就出在这个地方
{ //这会返回错误
printErr ("Could not initialize.\n");
return (ERROR);
}
printf ("Attaching to ATA disk device... ");
dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */
if (usrAtaConfig (ctrl, drive, fileName) == ERROR)
{
printErr ("usrAtaConfig failed.\n");
return (ERROR);
}
中断挂接都成功了,也使能了可编程中断控制器,在pc.h中定义ATA1的中断号是9,
在bios中也看不到具体是哪个中断号,只是在计算机启动的那个界面上能看到ide控制器的中断号是14,
与ata0的中断号一样,我把ata1的中断号也改成14也不行。
(void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (vector),
(VOIDFUNCPTR)ataIntr, ctrl); //中断服务程序ataintr中会释放信号量
sysIntEnablePIC (level);
调试开关我已经打开了,下面是ataDrv.c中的一段代码,
for (drive = 0; drive < drives; drive++)
{
pType = &ataTypes[ctrl][drive];
pDrive = &pCtrl->drive[drive];
pParam = &pDrive->param;
if (pType->cylinders == 0)
break;
if ((pCtrl->ctrlType == ATA_PCMCIA) ||
((pCtrl->ctrlType != ATA_PCMCIA) && (drive == 0)))
{
if (ataCmd (ctrl, drive, ATA_CMD_DIAGNOSE, NULL, NULL) != OK) //程序在这个地方出错,
{ //原因是得不到信号量
semGive (&pCtrl->muteSem); //输出的中断次数为0
return (ERROR);
}
}
/* find out geometry */
if ((configType & ATA_GEO_MASK) == ATA_GEO_FORCE)
{
(void) ataCmd (ctrl, drive, ATA_CMD_INITP, NULL, NULL);
(void) ataPread (ctrl, drive, (char *)pParam);
}
else if ((configType & ATA_GEO_MASK) == ATA_GEO_PHYSICAL)
{
(void) ataPread (ctrl, drive, (char *)pParam);
pType->cylinders = pParam->cylinders - 1;
pType->heads = pParam->heads;
pType->sectors = pParam->sectors;
}
else if ((configType & ATA_GEO_MASK) == ATA_GEO_CURRENT)
{
(void) ataPread (ctrl, drive, (char *)pParam);
if ((pParam->currentCylinders != 0) &&
(pParam->currentHeads != 0) &&
(pParam->currentSectors != 0))
{
pType->cylinders = pParam->currentCylinders - 1;
pType->heads = pParam->currentHeads;
pType->sectors = pParam->currentSectors;
}
else
{
pType->cylinders = pParam->cylinders - 1;
pType->heads = pParam->heads;
pType->sectors = pParam->sectors;
}
}
ataCmd()函数如下
LOCAL STATUS ataCmd()
{
...
while (retry)
{
ataWait (ctrl, ATA_STAT_READY);
switch (cmd)
{
case ATA_CMD_DIAGNOSE:
ATA_IO_BYTE_WRITE (pCtrl->sdh, ATA_SDH_IBM | (drive << 4));
break;
...
ATA_IO_BYTE_WRITE (pCtrl->command, cmd);
semStatus = semTake (&pCtrl->syncSem, //因为收不到硬盘中断,所以一直得不到信号量
sysClkRateGet() * pCtrl->semTimeout); //导致函数返回错误
if ((pCtrl->intStatus & ATA_STAT_ERR) || (semStatus == ERROR))
{
#ifdef ATA_DEBUG
int error = ATA_IO_BYTE_READ(pCtrl->error);
printErr ("ataCmd err: status=0x%x semStatus=%d err=0x%x\n",
pCtrl->intStatus, semStatus, error);
...
有没有修改硬盘的具体参数啊?我记得我以前也用过硬盘启动,也是secondary master.只要把几个硬盘的具体参数修改对就行了.
有奖活动 | |
---|---|
【有奖活动——B站互动赢积分】活动开启啦! | |
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |