MPC8313ERDB在Linux从NAND FLASH读取UBoot环境变量的代码分析

Yao.GUET@2014-05-19

一。故事起因

由于文件系统的增大,已经大大的超出了8MB的NOR FLASH。而不得不把内核,文件系统和设备树文件保存到NAND FLASH上。

可是由于使用的是RAMDISK,而无法保存一些个别的配置和參数,最简单的须要就是设置系统的IP了,。。

要使用统一的RAMDISK。而实现LINUX启动之后。设置成不能的參数功能,比較方便的就是从UBOOT把这些參数传递过去,这个得到了大家的认证,我们能够直接加入启动參数,然后在内核里面读出来,这样的方法比較方法。唯一不好的地方就是须要改动内核,。,

另外就把对应的參数以UBOOT环境变量的形式写到NAND FLASH中。然后在Linux里面再读出来。这种方法比較的好,不用改动内核,不用改动ltib里面的标准包就能够完毕。

。。

事实上UBOOT里面就自带有在LINUX下读写环境变量的代码。在uboot/tools/env这个文件夹下,当然。你也能够直接使用:“make env”去编译。在同文件夹会生成fw_printenv这个可运行文件,然后, 须要改动一下配置fw_env.config,然后把它放到你的文件系统里面:“/etc/fw_env.config”。再建立两个软链接就能够了,,,

这个过程比較复杂,我使用的是u-boot-1.3.0的代码。结果make env的时候是有错误的,大家能够尝试着去编译一下看。假设能一次通过就能够不用debug了~

事实上在LINUX以下读取UBOOT里面环境变量的的方法,非常easy。

就是主要的文件读取,和字符串分析,主要是要搞清楚你的NAND FLASH里面环境变量是保存在什么地方的。

以下是我依据fw_printenv写的一个小样例,能够直接编译然后读取NAND里面的环境变量。。

二。

详细实现

1. 确定UBOOT环境參数在FLASH中保存位置

由于我用的是MPC8313ERDB这个板子。所以查看UBOOT的代码"include/configs/MPC8313ERDB.h"这个定义文件有以下的定义:

#define CFG_NAND_BLOCK_SIZE     (16 << 10)      /* NAND chip block size */

/*
* Environment
*/ #if defined(CONFIG_NAND_U_BOOT)
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_SIZE CFG_NAND_BLOCK_SIZE
#define CFG_ENV_OFFSET ((1024<<10) - (CFG_NAND_BLOCK_SIZE<<1))
#elif !defined(CFG_RAMBOOT)
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000)
#define CFG_ENV_SECT_SIZE 0x10000 /* 64K(one sector) for env */
#define CFG_ENV_SIZE 0x2000

由于我这里使用的是NAND UBOOT,所以应该是前面那一项:

CFG_ENV_SIZE = 16<<10 = 0x4000 = 16k

CFG_ENV_OFFSET = (1024<<10)-(0x4000<<1) = 0xF8000

相同道理。你也能够依据你是用什么板子的,在include/configs这个文件夹去查看对应的定义。

2. 读取UBOOT MTD文件

确定了环境变量在FLASH中的偏移,就能够直接打开这个UBOOT的MTD设备文件。然后用lseek定位,再用read函数把UBOOT的环境变量读出来了。

那么这里呢。UBOOT究竟是哪个MTD设备就是因你的设备树文件不同而不同了。当然,你也能够直接在LINUX以下执行命令“cat  /proc/mtd”里面查看一下。

3. CRC校验

读出来的数据,怎么确定是正确的呢?事实上在UBOOT环境变量開始的位置。保存有4个字节32位的CRC校验。我们能够校验一下,,。

这个CRC直接拿UBOOT代码的。

crc32.h文件。这个仅仅是一个crc32函数的声明

#ifndef	_CRC32_H
#define _CRC32_H
/* */
unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
#endif

crc32.c文件,crc32函数的实现:

/*
* This file is derived from crc32.c from the zlib-1.1.3 distribution
* by Jean-loup Gailly and Mark Adler.
*/ /* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/ /* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
static const unsigned long crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
}; #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf); /* ========================================================================= */
unsigned long crc32(unsigned int crc,
const unsigned char *buf,
unsigned int len)
{
crc = crc ^ 0xffffffffL;
while (len >= 8)
{
DO8(buf);
len -= 8;
}
if (len) do {
DO1(buf);
} while (--len);
return crc ^ 0xffffffffL;
}

4. 代码文件

read_config.c文件

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "crc32.h" #define MTD_PATH "/dev/mtdblock1"
#define MTD_OFFSET 0xF8000
#define MTD_ENV_SIZE 0x4000 unsigned char *envmatch(unsigned char * s1, unsigned char * s2); int main(int argc, char **argv)
{
int fd;
int i, len;
unsigned char *buf, *p, *env;
unsigned long crc, crc_calc; if ((fd = open(MTD_PATH, O_RDONLY))<0) {
fprintf(stderr, "Can't open %s : %s\n",
MTD_PATH, strerror(errno));
return (-1);
} if (lseek(fd, MTD_OFFSET, SEEK_SET) < 0) {
fprintf(stderr, "Can't locate offset: %s \n",
strerror(errno));
close(fd);
return (-1);
} if ((buf = malloc(MTD_ENV_SIZE)) == NULL) {
fprintf(stderr, "Can't alloc mem. %s\n",
strerror(errno));
close(fd);
return (-1);
}
if ((len = read(fd, buf, MTD_ENV_SIZE)) != MTD_ENV_SIZE) {
fprintf(stderr, "Read MTD failed! %s\n",
strerror(errno));
close(fd);
free(buf);
return (-1);
} memcpy(&crc, buf, 4);
if (crc32(0, buf+sizeof(long), MTD_ENV_SIZE-sizeof(long)) != crc) {
fprintf(stderr, "Data crc error!\n");
free(buf);
close(fd);
return (-1);
} for (env = buf+sizeof(long); *env; env=p+1) {
for (p = env; *p; p++) {
if (p >= buf + MTD_ENV_SIZE) {
fprintf (stderr, "## Error: "
"environment not terminated\n");
return;
}
}
if (argc == 2) {
if (envmatch(argv[1], env)>0) {
for (p=env; *p!='='; p++)
;
printf("%s\n", ++p);
break;
} else
continue;
} else {
printf("%s\n", env);
}
} free(buf);
close(fd);
return 0;
} /*
* s1 is either a simple 'name', or a 'name=value' pair.
* s2 is a 'name=value' pair.
* If the names match, return the value of s2, else NULL.
*/ unsigned char *envmatch (unsigned char * s1, unsigned char * s2)
{ while (*s1 == *s2++)
if (*s1++ == '=')
return (s2);
if (*s1 == '\0' && *(s2 - 1) == '=')
return (s2);
return (NULL);
}

Makefile文件。这个因为基本是Makefile盲,大家凑合着用吧哈。改动各自的CROSS_COMPILE就能够了。

CROSS_COMPILE ?= powerpc-e300c3-linux-gnu-
read_config:read_config.c crc32.o crc32.h
$(CROSS_COMPILE)gcc $^ -o $@ crc32.o:crc32.c
$(CROSS_COMPILE)gcc $^ -c -o $@
clean:
rm -f read_config crc32.o

MPC8313ERDB在Linux从NAND FLASH读取UBoot环境变量的代码分析的更多相关文章

  1. 在Linux里读取UBOOT环境变量

    转载:http://falloutmx.blog.163.com/blog/static/39236020201211145010154/ 可以通过mtd方式读取,也可以用ioremap方式.不过这些 ...

  2. 如何编写linux下nand flash驱动-3

    [读(read)操作过程详解] 以最简单的read操作为例,解释如何理解时序图,以及将时序图 中的要求,转化为代码. 解释时序图之前,让我们先要搞清楚,我们要做的事情:那就是,要从nand flash ...

  3. 如何编写linux下nand flash驱动-2

    [Nand Flash引脚(Pin)的说明] 图3.Nand Flash引脚功能说明 上图是常见的Nand Flash所拥有的引脚(Pin)所对应的功能,简单翻译如下: 1.       I/O0 ~ ...

  4. 如何编写linux下nand flash驱动-4

    2.       软件方面 如果想要在Linux下编写Nand Flash驱动,那么就先要搞清楚Linux下,关于此部分的整个框架.弄明白,系统是如何管理你的nand flash的,以及,系统都帮你做 ...

  5. uboot环境变量(设置bootargs向linux内核传递正确的参数)

    这是我uboot的环境变量设置,在该设置下可以运行initram内核(从内存下载到nandflash再运行),但是运行nfs根文件系统的时候一直出错,各种错误.查看了很多资料后猜想应该是uboot传递 ...

  6. Linux系统——访问U-BOOT环境变量

    Linux系统下访问U-BOOT环境变量 移植过U-BOOT的人,都知道:在U-BOOT中存有ENV.但U-BOOT在引导内核启动之后,U-BOOT的生命周期就结束了.那么启动LINUX内核之后,U- ...

  7. I.MX6 Linux U-boot 环境变量解析

    /********************************************************************************** * I.MX6 Linux U- ...

  8. openwrt设置uboot环境变量在flash上的存储地址

    1.分析如下 ubootenv_add_app_config ubootenv_add_uci_config "/dev/mtd1" "0x40000" &qu ...

  9. uboot环境变量实现分析

    u-boot的环境变量用来存储一些经常使用的参数变量,uboot希望将环境变量存储在静态存储器中(如nand nor eeprom mmc). 其中有一些也是大家经常使用,有一些是使用人员自己定义的, ...

随机推荐

  1. 原来的debussy可以在win7的64位系统下运行吗

    可以的,首先下载两个DLL:msvcr71.dll和msvcp71.dll,然后破解一下就可以了. https://zhidao.baidu.com/question/2419893614880017 ...

  2. 【Android】21.3 动画

    分类:C#.Android.VS2015: 创建日期:2016-03-21 一.简介 Android 提供了以下三种创建动画的方式: Drawable Animations – 画板动画,也叫帧动画( ...

  3. hdu 5289 Assignment(给一个数组,求有多少个区间,满足区间内的最大值和最小值之差小于k)

    1.区间是一段的,不是断开的哟 2.代码是看着标程写的 3.枚举左端点,二分右端点流程: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L ...

  4. 每日英语:Some Chinese Students Stay Home to Get Ahead

    Li Shan's oldest son was the perfect candidate to join the throngs of Chinese students studying abro ...

  5. ny737 石子合并(一) 总结合并石子问题

    描述: 在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序地合并成一堆. 规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将n堆石子合并 ...

  6. 二 、在 JDK 6 and JDK 7中 substring() 方法

    在JDK6 和JDK 7 里面substring(int beginIndex, int endIndex)的方法是不同的.知道这种区别会帮助你更好用它们.为了简单期间,下面用substring() ...

  7. 给class添加id封装

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Linux Jenkins配置Git

    1.卸载Centos自带的git1.7.1:通过git –version查看系统带的版本,Centos应该自带的是git版本是1.7.1 终端输入:yum remove git 2.安装所需软件包 终 ...

  9. 加载jquery主函数的两种方式

    方式一: $(document).ready(fucntion){ var div1 = document.getElementById("div1"); alert(div1); ...

  10. php底层HashTable的实现

    本文转载自:  http://segmentfault.com/blog/tree/1190000000718519 HashTable对PHP来说是一种非常重要的数据结构.很多PHP的内部实现(变量 ...