Linux移植添加norflash MTD分区
2019-07-13 06:55发布
生成海报
开发板上只有
Nor Flash,所以为了实现层次文件系统,需要为Linux2.6.20增加Nor Flash MTD驱动支持。其实工作量并不大,因为已经有现成的程序可供参考。
MTD
的驱动程序都集中在drivers/mtd里面。我们需要做的,仅仅是在drivers/mtd/maps下增加自己的分区表。因为有参考的代码,所以比较容易。
/*
* $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
*
* Handle mapping of the NOR flash on Cogent EDB7312 boards
*
* Copyright 2002 SYSGO Real-Time Solutions GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include
#include
#include
#include
#include
#include
#include
#ifdef CONFIG_MTD_PARTITIONS
#include
#endif
#define WINDOW_ADDR 0x00000000 /* NOR FLASH物理地址 */
#define WINDOW_SIZE 0x01000000 /* NOR FLASH大小 */
#define BUSWIDTH 2
#define FLASH_BLOCKSIZE_MAIN 0x20000
#define FLASH_NUMBLOCKS_MAIN 128
/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */
#define PROBETYPES { "cfi_probe", NULL } /* 探测的接口类型,可以是"cfi_probe", "jedec_probe", "map_rom", NULL }; */
#define MSG_PREFIX "EDB7312-NOR:" /* prefix for our printk()'s */ /*printk的前缀 */
#define MTDID "edb7312-nor" /* for mtdparts= partitioning */ /*MTD驱动*/
static struct mtd_info *mymtd;
/*定义一个map_info,代表一块norflash*/
struct map_info edb7312nor_map = {
.name = "NOR flash on EDB7312",
.size = WINDOW_SIZE,
.bankwidth = BUSWIDTH,
.phys = WINDOW_ADDR,
};
#ifdef CONFIG_MTD_PARTITIONS
/*
* MTD partitioning stuff
*/
/* 默认分区信息*/
static struct mtd_partition static_partitions[3] =
{
{
.name = "ARMboot",
.size = 0x40000, //256K
.offset = 0
},
{
.name = "Kernel",
.size = 0x200000, //2M
.offset = 0x40000
},
{
.name = "RootFS",
.size = 0xDC0000, //13M
.offset = 0x240000
},
};
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
#endif
static int mtd_parts_nb = 0;
static struct mtd_partition *mtd_parts = 0;
/*Norflash模型初始化函数
*<1>物理地址映射为虚拟地址: mini2440nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
*<2>探测norflash芯片: do_map_probe(), 得到mtd_info;
*<3>探测分区信息: parse_mtd_partitions(), 得到mtd_partition;
*<4>利用mtd_info和mtd_partition注册设备:add_mtd_device();
*/
int __init init_edb7312nor(void)
{
static const char *rom_probe_types[] = PROBETYPES;
const char **type;
const char *part_type = 0;
printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x
",
WINDOW_SIZE, WINDOW_ADDR);
edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); /*物理地址映射为虚拟地址*/
if (!edb7312nor_map.virt) {
printk(MSG_PREFIX "failed to ioremap
");
return -EIO;
}
simple_map_init(&edb7312nor_map);
mymtd = 0;
type = rom_probe_types;
for(; !mymtd && *type; type++) {
mymtd = do_map_probe(*type, &edb7312nor_map); /*根据map_info探测norflash芯片,若成功则返回mtd_info*/
}
if (mymtd) {
mymtd->owner = THIS_MODULE;
#ifdef CONFIG_MTD_PARTITIONS
/*探测分区信息,若探测成功,则mtd_parts中保存了分区信息;若探测失败,使用数组定义的默认分区信息*/
mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
if (mtd_parts_nb > 0)
part_type = "detected";
if (mtd_parts_nb == 0)
{
mtd_parts = static_partitions;
mtd_parts_nb = ARRAY_SIZE(static_partitions);
part_type = "static";
}
#endif
/*注册设备*/
add_mtd_device(mymtd);
if (mtd_parts_nb == 0)
printk(KERN_NOTICE MSG_PREFIX "no partition info available
");
else
{
printk(KERN_NOTICE MSG_PREFIX
"using %s partition definition
", part_type);
add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
}
return 0;
}
iounmap((void *)edb7312nor_map.virt);
return -ENXIO;
}
/*Norflash模块卸载函数
*<1>注销设备:del_mtd_device();
*<2>销毁map_info:map_destroy();
*<3>取消映射:iounmap();
*/
static void __exit cleanup_edb7312nor(void)
{
if (mymtd) {
del_mtd_device(mymtd); /*注销设备*/
map_destroy(mymtd); /*销毁map_info*/
}
if (edb7312nor_map.virt) {
iounmap((void *)edb7312nor_map.virt);
edb7312nor_map.virt = 0;
}
}
module_init(init_edb7312nor);
module_exit(cleanup_edb7312nor);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marius Groeger ");
MODULE_DESCRIPTION("Generic configurable MTD map driver");
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮