From: "Garcia Jérémie" <GARCIAJ@3il.fr>
To: "Josh Boyer" <jwboyer@jdub.homelinux.org>
Cc: linuxppc-dev@ozlabs.org
Subject: RE : How to read/write in flash memories (MTD)?
Date: Fri, 1 Apr 2005 10:40:53 +0200 [thread overview]
Message-ID: <D4FDDD1349B5AC46B68FC26AD8AF42D6226B19@exnet.3il.fr> (raw)
Josh,
Your reply confirmed my feeling. So I've decided to use the MTD but with =
my own driver as I found in a tutorial. So I made the file (module) =
/drivers/mtd/maps/myBoardFlash.c in order to support my 2 flash =
memories. You can see the code below, but once again (sorry...) I have =
some questions and doubts on it.=20
1- Is that driver correct for my case?=20
2- Are those R/W routines are usable?
3- In our application we want to download source code and achievable =
code using Ethernet (so R/W operations). Do I need a filesystem for that =
as JFFS 2 ?=20
4- Giving this driver, what is the process to use my R/W routines (if =
they are correct...) from the user space?
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
#include <linux/version.h>
#include <asm/io.h>
static struct mtd_info *boot_flash;
static struct mtd_info *oper_flash;
/*************************************************/
/* Mapping infos */
/*************************************************/
/* Map infos for the boot flash */
static struct map_info myboard_flash_boot_map =3D {
.name =3D "MYBOARD boot flash",
.size =3D BOARD_BOOT_FLASH_SIZE,
.buswidth =3D 1,
.read8 =3D myboard_flash_read8,
.read16 =3D myboard_flash_read16,
.read32 =3D myboard_flash_read32,
.copy_from =3D myboard_flash_copy_from,
.write8 =3D myboard_flash_write8,
.write16 =3D myboard_flash_write16,
.write32 =3D myboard_flash_write32,
.copy_to =3D myboard_flash_copy_to
};
/* Map infos for the operationnal flash */
static struct map_info myboard_flash_oper_map =3D {
.name =3D "MYBOARD oper flash",
.size =3D BOARD_OPER_FLASH_SIZE,
.buswidth =3D 2,
.read8 =3D myboard_flash_read8,
.read16 =3D myboard_flash_read16,
.read32 =3D myboard_flash_read32,
.copy_from =3D myboard_flash_copy_from,
.write8 =3D myboard_flash_write8,
.write16 =3D myboard_flash_write16,
.write32 =3D myboard_flash_write32,
.copy_to =3D myboard_flash_copy_to =20
};
=20
/*************************************************/
/* Partitionning infos */
/*************************************************/
/* Boot flash partionning infos */
static struct mtd_partition myboard_flash_boot_partitions[] =3D {
{
.name =3D "Boot flash partition",
.offset =3D 0x0,
.size =3D BOARD_BOOT_FLASH_SIZE,
}
};
/* Oper flash partionning infos */
static struct mtd_partition myboard_flash_oper_partitions[] =3D {
{
.name =3D "Oper flash partition", =20
.offset =3D 0x0,
.size =3D BOARD_OPER_FLASH_SIZE, =20
}
};
/**************************************************/
/* Read/Write routines */
/**************************************************/
__u8 myboard_flash_read8(struct map_info *map, unsigned long ofs)
{
return __raw_readb(map->map_priv_1 + ofs);
}
__u16 myboard_flash_read16(struct map_info *map, unsigned long ofs)
{
return __raw_readw(map->map_priv_1 + ofs);
}
__u32 myboard_flash_read32(struct map_info *map, unsigned long ofs)
{
return __raw_readl(map->map_priv_1 + ofs);
}
void myboard_flash_copy_from(struct map_info *map, void *to, unsigned =
long from, ssize_t len)
{
memcpy_fromio(to, map->map_priv_1 + from, len);
}
void myboard_flash_write8(struct map_info *map, __u8 d, unsigned long =
adr)
{
__raw_writeb(d, map->map_priv_1 + adr);
mb();
}
void myboard_flash_write16(struct map_info *map, __u16 d, unsigned long =
adr)
{
__raw_writew(d, map->map_priv_1 + adr);
mb();
}
void myboard_flash_write32(struct map_info *map, __u32 d, unsigned long =
adr)
{
__raw_writel(d, map->map_priv_1 + adr);
mb();
}
/**********************************************/
/* Module Init */
/**********************************************/
int __init init_myboard_flash(void) map_info
{
/*
* Boot flash init
*/
=20
printk(KERN_NOTICE "myboard boot flash: %x at %x\n", =
BOARD_BOOT_FLASH_SIZE, MYBOARD_FLASH_BOOT_BASE);
/* Obtain a virtual address for the physic one given ibn order to =
perform R/W operations */
myboard_flash_boot_map.map_priv_1 =3D (unsigned =
long)ioremap(MYBOARD_FLASH_BOOT_BASE, BOARD_BOOT_FLASH_SIZE);
if (!myboard_flash_boot_map.map_priv_1)
{
printk("Failed to ioremap for boot flash!!\n");
return -EIO;
}
=20
boot_flash =3D do_map_probe("cfi_probe", &myboard_flash_boot_map);
if (boot_flash)
{
boot_flash->module =3D THIS_MODULE;
boot_flash->erasesize =3D 0x10000;
}
else
{
printk("map probe failed for boot flash!!\n");
return -ENXIO;
}
=20
/*
* Oper flash init
*/
printk(KERN_NOTICE "myboard oper flash: %x at %x\n", =
BOARD_OPER_FLASH_SIZE, MYBOARD_FLASH_OPER_BASE);
/* Obtain a virtual address for the physic one given ibn order to =
perform R/W operations */
myboard_flash_boot_map.map_priv_1 =3D (unsigned =
long)ioremap(MYBOARD_FLASH_OPER_BASE, BOARD_OPER_FLASH_SIZE);
if (!myboard_flash_oper_map.map_priv_1)
{
printk("Failed to ioremap for oper flash!!\n");
return -EIO;
}
oper_flash =3D do_map_probe("cfi_probe", &myboard_flash_oper_map);
if (oper_flash)
{
oper_flash->module =3D THIS_MODULE;
oper_flash->erasesize =3D 0x10000;
}
else
{
printk("map probe failed for oper flash!!\n"); =20
return -ENXIO;
}
/*
* Create partitions
*/
=20
if(boot_flash && oper_flash)
{
=
add_mtd_partitions(boot_flash,myboard_flash_boot_partitions,sizeof(myboar=
d_flash_boot_partitions)/sizeof(struct mtd_partition));
=
add_mtd_partitions(oper_flash,myboard_flash_oper_partitions,sizeof(myboar=
d_flash_oper_partitions)/sizeof(struct mtd_partition));
return 0;=20
}
else
{
/* Free the obtained virtual addresses */
iounmap((void *)myboard_flash_boot_map.map_priv_1);
iounmap((void *)myboard_flash_oper_map.map_priv_1);
return -ENXIO;
}
}
/**********************************************/
/* Module Cleanup */
/**********************************************/
static void __exit cleanup_myboard_flash(void)
{
/*
* Delete partitions
*/
=20
if (boot_flash)
{
del_mtd_partitions(boot_flash);
map_destroy(boot_flash);
}
if (oper_flash)
{
del_mtd_partitions(oper_flash);
map_destroy(oper_flash);
}
=20
/*
* Free Free the obtained virtual addresses=20
*/
=20
if (myboard_flash_boot_map.map_priv_1)
{
iounmap((void *)myboard_flash_boot_map.map_priv_1);
myboard_flash_boot_map.map_priv_1 =3D 0;
}
if (myboard_flash_oper_map.map_priv_1)
{
iounmap((void *)myboard_flash_oper_map.map_priv_1);
myboard_flash_oper_map.map_priv_1 =3D 0;
}
}
=20
module_init(init_myboard_flash);
module_exit(cleanup_myboard_flash);
-------- Message d'origine--------
De: Josh Boyer [mailto:jwboyer@jdub.homelinux.org]
Date: ven. 01/04/2005 01:34
=C0: Garcia J=E9r=E9mie
Cc: linuxppc-dev@ozlabs.org
Objet : Re: How to read/write in flash memories (MTD)?
=20
On Thu, 2005-03-31 at 11:59 +0200, Garcia J=E9r=E9mie wrote:
> L&G,
> Although I'm a newbie in linux kernel development, I'm in charge of =
adapting a Montavista LSP to fit our hardware. In our platform, we use 2 =
AMD flash memories (AM29LV) in which one we would like to process =
read/write operations. So I'm looking for a way to do that. I saw that =
at compilation time, there is MTD item which seems to be created for =
that. But I guess activate that will not be enough to reach my =
objective.
You need to enable MTD with the appropriate chip drivers and either the
MTD character device or the MTD block device (or both). These will
create /dev/mtdX and /dev/mtdblockX respectively. If you are using
devfs or sysfs + udev, they should show up in /dev. Otherwise, you'll
need to use mknod to create them.
> Indeed, we are developping an application (in the user-space) which =
will initiate operation on the 2 flash memories. So, how can I access =
them from my application?
> Please help me cause I'm getting lost in the linux sources....
I'm not sure what kind of operations you mean, but the block and char
devices allow read/write operation. If you are looking for a filesystem
to run on these devices, take a look at JFFS2. Cramfs or squashfs can
also be used, but they are read-only.
josh
next reply other threads:[~2005-04-01 8:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-01 8:40 Garcia Jérémie [this message]
-- strict thread matches above, loose matches on Subject: below --
2005-04-04 14:05 RE : How to read/write in flash memories (MTD)? Fillod Stephane
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=D4FDDD1349B5AC46B68FC26AD8AF42D6226B19@exnet.3il.fr \
--to=garciaj@3il.fr \
--cc=jwboyer@jdub.homelinux.org \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox