Linux初始化Nor Flash芯片及驱动

					
Linux 系统初始化NOR FLash芯片及驱动

										
韩大卫@吉林师范大学


本文旨在解析linux系统下, Nor Flash芯片的初始化大致过程, 和cfi标准类型的Flash芯片在linux系统中的底层驱动何如实现,  如何找到并调用其提供的write/read/ioctl实现函数.  

在明确了上述关系后,  可用通过一个用户层的程序, 向Nor Flash芯片指定分区位置写入指定程序, 比如写入linux elf文件,  实现更新系统内核,  写入uboot,  更新引导程序,  写入 “hello ,world!”,  使得系统崩溃掉(这样做的后果是需要将Nor Flash芯片从目标板中取下来, 用烧录器烧入正确的文件后再焊到板子上).

关于linux如何在Nor FLash上建立分区, 请参考博文 <<linux下建立NOR Flash分区>>

内核启动时, 在arch具体CPU子目录下, 如 mips/cavium-octeon, nor flashd 的初始化过程如下:


在arch/mips/cavium-octeon/flash_setup.c


late_initcall(flash_init);

static struct map_info flash_map;

static int __init flash_init(void)
{ 
                
    union cvmx_mio_boot_reg_cfgx region_cfg;
    region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
    if (region_cfg.s.en) {


/*
初始化一个全局数据结构 flash_map,  定义其名为”octeon_nor0”    
*/
        flash_map.name = "octeon_nor0";
        flash_map.phys = region_cfg.s.base << 16;
        flash_map.size = 0x1fc00000 - flash_map.phys;
        flash_map.bankwidth = 1;
        flash_map.virt = ioremap(flash_map.phys, flash_map.size);
        pr_notice("Bootbus flash: Setting flash for %luMB flash at "
              "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
        simple_map_init(&flash_map);
	
		//调用名为cfi_probe 的驱动, 说明该CPU支持CFI标准的flash操作
        mymtd = do_map_probe("cfi_probe", &flash_map);
        if (mymtd) {     
            mymtd->owner = THIS_MODULE;
                         
#ifdef CONFIG_MTD_PARTITIONS
            nr_parts = parse_mtd_partitions(mymtd,
                            part_probe_types,
                            &parts, 0);
            if (nr_parts > 0)
                add_mtd_partitions(mymtd, parts, nr_parts);
            else         
                add_mtd_device(mymtd);
#else                    
            add_mtd_device(mymtd);
#endif                   
        } else {         
            pr_err("Failed to register MTD device for flash\n");
        }                
    }                    
    return 0;            
}                        
                         
late_initcall(flash_init);    


do_map_probe() 会找到并调用指定name的probe函数,定义在drivers/mtd/chips/chipreg.c 中,


struct mtd_info *do_map_probe(const char *name, struct map_info *map)
{             
    struct mtd_chip_driver *drv;
    struct mtd_info *ret;
              
	//获取指定name的驱动
    drv = get_mtd_chip_driver(name);
              
    if (!drv && !request_module("%s", name))
        drv = get_mtd_chip_driver(name);
              
    if (!drv)
        return NULL;
	
	//成功获取指定的驱动器后, 调用其probe()函数, 实现对芯片的探测           
    ret = drv->probe(map);
      
    module_put(drv->module);
            
    if (ret)
        return ret;
           
    return NULL;
}          


get_mtd_chip_driver()定义:

static struct mtd_chip_driver *get_mtd_chip_d
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值