4.这样也能执行到c语言里去了。那就跑吧。然后困扰我三天的问题就这样来了。串口输出是乱码,记得以前移植到时候没出现乱码,不知道以前怎么搞的,估计是patch过网上的包。现在去搜,说是串口模块时钟不对,我愿意为是兼容的。网上就那么提了一下。郁闷之极我去看2410和2440的芯片手册,发现的确不是那会事。时钟配置差远了。还有一个问题是start.S里我的总线速率配置的是1:2:4(值是3)可是到c语言里不知哪里给我改成了1:4:8(值是5),最后发现如果配置成1:2:4然后使用400.5M的话总线速度会超过允许值。不过调试的时候还没出现问题。于是改成5.在UBOOT中串口的配置是自己计算的,所以我无论如何也想不通为什么会算错(看来那时候我傻了,傻到不知道如何找错误了).网上搜到是pclk的问题之后,我开始调试,发现串口寄存器计算出来的值不对.然后我重新考虑了MCLK,HCLK ,PCLK,然后看网上的移植,直接配置了PCLK的值,我是极度不推荐了。写死这个值,就等于结束了这次移植,以后遇到还要重新搞。我根据芯片手册重写了get_PCLK,函数,这里对寄存器结构进行了扩展,因为2440增加了寄存器。写到这里的时候,串口输出就正确了。但是又卡在了网络上,网卡自检失败。我以为莫非是总线配置错误?(我还是太笨了,这个配置是openjtag自带的初始化程序初始化的。这个是支持2410和2440的。)然后就调试,走到它跑飞的地方,我是很有耐心的。以前做逆向工程时候练就的。结果呢,发现使用了一个异常的地址。一步步的回来找,发现竟然是个BUG,在没有初始化结构变量就先使用了。哎呀。估计下一个版本会更正吧。调节这两个代码的位置就ok了。
以后就要增加nand的读写了。这个曾经做过,但是失败在不知为什么就不认nand了。由于学习stm32,先放下这个了。
关键代码:
int cs8900_initialize(u8 dev_num, int base_addr)
{
struct eth_device *dev;
struct cs8900_priv *priv;
dev = malloc(sizeof(*dev));
if (!dev) {
free(dev);
return 0;
}
memset(dev, 0, sizeof(*dev));
priv = malloc(sizeof(*priv));
if (!priv) {
free(priv);
return 0;
}
memset(priv, 0, sizeof(*priv));
priv->regs = (struct cs8900_regs *)base_addr;
dev->iobase = base_addr;//原文这2句在下面,导致出错
dev->priv = priv;
/* Load MAC address from EEPROM */
cs8900_get_enetaddr(dev);
dev->init = cs8900_init;
dev->halt = cs8900_halt;
dev->send = cs8900_send;
dev->recv = cs8900_recv;
sprintf(dev->name, "%s-%hu", CS8900_DRIVERNAME, dev_num);
eth_register(dev);
return 0;
}
ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
ulong nRet = 0;
// 下面是对HCLK频率的计算
unsigned int nCLKDIVN = readl(&clk_power->CLKDIVN);
unsigned int nCAMDIVN = readl(&clk_power->CAMDIVN);
switch(nCLKDIVN & 6)
{
case 0:
nRet = get_FCLK();
break;
case 2:
nRet = get_FCLK() / 2;
break;
case 4:
if (nCAMDIVN & 0x100)
{
nRet = get_FCLK() / 8;
}
else
{
nRet = get_FCLK() / 4;
}
break;
case 6:
if (nCAMDIVN & 0x80)
{
nRet = get_FCLK() / 6;
}
else
{
nRet = get_FCLK() / 3;
}
break;
default:
break;
}
return nRet;
}
|