[controlador de Linux]-----NOR FLASH

1. Marco NOR FLASH

Insertar descripción de la imagen aquí

1.1La diferencia entre NAND y NOR

NI NAND
interfaz Como un carnero, muchos alfileres. Menos pines, multiplexación
capacidad Pequeño grande
leer Simple complejo
Escribir emitir instrucciones especiales Mismo
precio caro Barato
defecto Sin inversión de bits, bloque defectuoso Bits volteados, bloques malos
CHIP Poder No poder

Especificaciones de 1.2NOR FLASH

NOR FLASH tiene dos formas estándar: modo jedec y cfi
**estándar jedec:** El antiguo NORFLASH admitirá el estándar "jedec". Al leer la ID y compararla con la matriz, la matriz registra la información del chip NORFLASH.
Insertar descripción de la imagen aquíLa antigua especificación NORFLASH tenía que leer el ID y compararlo con la matriz de estructura "jedec_table[]" en el kernel. Si no hay información NORFLASH en los datos, la matriz debe modificarse. El método es muy problemático/ * *especificación cfi
: **El nuevo NORFLASH debería ser compatible con la interfaz flash universal "cfi". Es decir, el propio NORFLASH contiene esta información de atributos (como capacidad, voltaje). Puede obtener esta información de atributos enviando comandos relevantes a las direcciones relevantes.

2. Marco del controlador NOR FLASH

Hay una capa de protocolo en NOR, que emite "comandos de desbloqueo", etc., que también lo realiza el kernel. NOR se puede leer como un recuerdo. La diferencia de memoria entre las dos placas de desarrollo es la dirección de memoria y el ancho de bits.
Operación del hardware NOR: diferentes partes (dirección base, ancho de bits). Por ejemplo, en la "capa de protocolo NOR", usted sabe escribir "ciertos datos" en "una determinada dirección" para "identificar, borrar y programar". "Cierta dirección" debe ser proporcionada por usted mismo.
Puede escribir un controlador universal y la "dirección base" y el "ancho de bits" se implementan directamente configurando el kernel a través de "make menuconfig". linux-2.6.22.6\drivers\mtd\maps\Physmap.c Este es el controlador NORFLASH que viene con el kernel (la capa más baja, la capa relacionada con el hardware). La capa "MTD" no importa si es "NAND " o "NOR" a continuación, porque todos proporcionarán la "estructura mtd_info" a la "capa MTD

2.1 Operación del hardware NORFLASH:

1. Estructura de asignación: estructura map_info (información de mapeo del mapa);
2. Estructura de configuración: dirección base física (phys), tamaño (tamaño), ancho de bits (ancho de banco), dirección base virtual (virt). El kernel ve diferentes placas de desarrollo. diferencia mínima de NOR
3. Uso: (llame a la función proporcionada por la capa de protocolo NOR FLASH para identificar) use la función proporcionada por la estructura mtd_info para identificar, etc.,
4. add_mtd_partitions más información de partición.

2.2 función de inicio

static int s3c_nor_init(void)
{
    
    
    /* 1. 分配map_info结构体 */
    s3c_nor_map = kzalloc(sizeof(struct map_info),GFP_KERNEL);
    if (!s3c_nor_map)
        return -ENOMEM;
    /* 2. 设置: 物理基地址(phys), 大小(size), 位宽(bankwidth), 虚拟基地址(virt) */
    s3c_nor_map->name = "s3c_nor";
    s3c_nor_map->phys = 0;
    s3c_nor_map->size = S3C_NOR_SIZE;   /* >= NOR的真正大小 */
    s3c_nor_map->bankwidth = 2;
    s3c_nor_map->virt = ioremap(s3c_nor_map->phys, s3c_nor_map->size);
    
    simple_map_init(s3c_nor_map);

    /* 3. 使用: 调用NOR FLASH协议层提供的函数来识别 */
    printk("use cfi_probe\n");
    s3c_nor_mtd = do_map_probe("cfi_probe",s3c_nor_map);
    if (!s3c_nor_mtd)
    {
    
    
        printk("use jedec_probe\n");
        s3c_nor_mtd = do_map_probe("jedec_probe", s3c_nor_map);
    }
    if (!s3c_nor_mtd)
    {
    
    
        iounmap(s3c_nor_map->virt);
        kfree(s3c_nor_map);
        return -EIO;
    }

    /* 4. add_mtd_partitions */
    add_mtd_partitions(s3c_nor_mtd,s3c_nor_parts,2);
    return 0;
}

El proceso de identificación de NOR FLASH do_map_probe() devuelve una estructura mtd_info.do_map_probe es una función proporcionada por la capa de protocolo NOR FLASH.

do_map_probe("cfi_probe", s3c_nor_map);
    drv = get_mtd_chip_driver(name)
    ret = drv->probe(map); // cfi_probe.c
        cfi_probe
            mtd_do_chip_probe(map, &cfi_chip_probe);
                cfi = genprobe_ident_chips(map, cp);
                    genprobe_new_chip(map, cp, &cfi)
                        cp->probe_chip(map, 0, NULL, cfi)
                            cfi_probe_chip
                             // 进入CFI模式
                             cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
                            // 看是否能读出"QRY"
                            qry_present(map,base,cfi)
                            .....

do_map_probe("jedec_probe", s3c_nor_map);
     drv = get_mtd_chip_driver(name)
     ret = drv->probe(map);  // jedec_probe
         jedec_probe
             mtd_do_chip_probe(map, &jedec_chip_probe);
                 genprobe_ident_chips(map, cp);
                     genprobe_new_chip(map, cp, &cfi)
                         cp->probe_chip(map, 0, NULL, cfi)
                             jedec_probe_chip
                                 // 解锁
                                cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
                                cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
                                
                                // 读ID命令
                                cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);                                      
                            
                                // 得到厂家ID,设备ID
                                cfi->mfr = jedec_read_mfr(map, base, cfi);
                                cfi->id = jedec_read_id(map, base, cfi);
                                        
                                // 和数组比较
                                jedec_table       

Agregue información de partición:
Ni flash tiene particiones correspondientes como nand flash. Agregue las particiones correspondientes a través de add_mtd_partitions en la función.

static struct mtd_partition s3c_nor_parts[] = {
    
    
    [0] = {
    
    
        .name   = "bootloader_nor",
        .size   = 0x00040000,
        .offset = 0,
    },
    [1] = {
    
    
        .name   = "root_nor",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
    }
};

2.3 función de salida

static void s3c_nor_exit(void)
{
    
    
    del_mtd_partitions(s3c_nor_mtd);
    iounmap(s3c_nor_map->virt);
    kfree(s3c_nor_map);
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45281868/article/details/128059537
Recomendado
Clasificación