S3C2440 SD卡速度的优化

K390机器采用S3C2440平台,使用Linux2.6.17系统,将整个驱动,系统移好后,发现SD卡驱动相对新的Linux内核,有很多不足之处,如不支持1G以上的卡,读写速度非常慢等。由于升级系统需要重新移植所有驱动,会大大的增加开发工作量,因此有必要将高版本的SD卡驱动的一些改良的部分移植到低版本的系统上。

2.6.17版本的SD卡驱动放在/drivers/mmc一个文件夹下,使用模块方式时,该文件夹下将会生成mmc_core.kommc_block.ko以及s3c2440mci.ko三个文件。加载驱动时,依次加载这三个文件即可。2.6.17以上的版本,SD卡驱动也放在/drivers/mmc目录下,但是该目录下存放了cardcore以及host三个文件夹。对应的文件夹分别产生mmc_block.kommc_core.ko以及s3cmci.ko

在不明白低版本SD卡速度的情况下,依次比较这三个KO文件的源代码,经反复测试,mmc_block.kommc_core.ko对速度的影响不大,关键在s3c2440mci.ko,即高版本的s3cmci.ko

经比较得知,高版本的s3cmci.ko对应的源文件s3cmci.c中,使用了tasklet中断底半部机制。正是这种机制,结合do_pio_read以及do_pio_write机制,使得SD卡复制响应速度大大加快。

s3cmci_probe中添加tasklet_init初始化函数,同时修改SD卡的CLK,然后修改s3cmci_send_request响应机制,对照s3cmci.c将整个机制全移到s3c2440mci.c中,这时编译成功,但是加载s3c2440mci.ko时内核崩溃,加调试信息跟踪,发现程序在调用do_pio_read时程序崩溃。do_pio_read函数会调用get_data_buffer函数,该函数又会调用sg_virt函数,用于获得内存块起始地址。

低版本的内核中并没有sg_virt这个函数,将高版本的函数复制到低版本内核中,具体位置在linux/scatterlist.h中,其代码如下:

static inline void *sg_virt(struct scatterlist *sg)

{

         return page_address(sg_page(sg)) + sg->offset;

}

同时将sg_page及其调用的函数全复制到scatterlist.h,生成KO文件后加载驱动,程序仍然崩溃。这下陷入绝境之中。通过屏蔽相关代码可以确定,程序崩溃的罪亏祸首就是这个函数!通过加打印信息将sg->offsetsg->page_link打印出来,发现开发板上正常情况下,sg->page_link是不会为0的,而K390上这个值第一次之后就一直为0.看来就是因为这个值造成程序崩溃。再次比较scatterlist.h中的内存地址返回机制,将sg_virt函数中的page_address的传入参数改为sg->page,问题解决。修改后的代码如下:

static inline void *sg_virt(struct scatterlist *sg)

{

         //return page_address(sg_page(sg)) + sg->offset;

         return page_address(sg->page) + sg->offset;

}

重新编译,将新生成的kernel烧进K390机器,同时加载三个ko文件,这时SD卡的速度较之前大有改善。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值