关键词:eMMC boot、PARTITION_CONFIG、force_ro等。

1. eMMC的分区

大部分eMMC都有类似如下的分区,其中BOOT、RPMB和UDA一般是默认存在的,gpp分区需要手动创建。

BOOT主要是为了支持从eMMC启动系统而设计的;RPMB即Replay Protected Memory Block简称,通常用来保存安全线管的数据;GPP主要用于存储系统或者用户数据。

UDA通常会进行再分区,然后根据不同目的存放相关数据,或者格式化成不同文件系统。

2. Linux下读写boot分区

因为boot分区中一般存放的是bootloader或者相关配置参数,这些参数一般是不允许修改的,所以默认情况下是能读boot分区,不能写。

2.1 使能读写

如果需要些则需要,修改/sys/block/mmcblk0boot1/force_ro。

使能写:

echo 0 > /sys/block/mmcblk0boot1/force_ro

关闭写:

echo 1 > /sys/block/mmcblk0boot1/force_ro

在重启之后,force_ro会恢复为1。

2.2 内核force_ro实现

下面来看看force_ro是如何起作用的?

eMMC在被初始化的时候,调用mmc_blk_probe(),这里面会在每个设备下创建force_ro sysfs节点。

static int mmc_blk_probe(struct mmc_card *card)

{

...

if (mmc_add_disk(md))

goto out;

...

}

static int mmc_add_disk(struct mmc_blk_data *md)

{

int ret;

struct mmc_card *card = md->queue.card;

device_add_disk(md->parent, md->disk);

md->force_ro.show = force_ro_show;

md->force_ro.store = force_ro_store;----------------------------------------------设置分区是否只读,0可读写;1只读。

sysfs_attr_init(&md->force_ro.attr);

md->force_ro.attr.name = "force_ro";

md->force_ro.attr.mode = S_IRUGO | S_IWUSR;

ret = device_create_file(disk_to_dev(md->disk), &md->force_ro);

if (ret)

goto force_ro_fail;

if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&

card->ext_csd.boot_ro_lockable) {

umode_t mode;

if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)

mode = S_IRUGO;

else

mode = S_IRUGO | S_IWUSR;

md->power_ro_lock.show = power_ro_lock_show;

md->power_ro_lock.store = power_ro_lock_store;

sysfs_attr_init(&md->power_ro_lock.attr);

md->power_ro_lock.attr.mode = mode;

md->power_ro_lock.attr.name =

"ro_lock_until_next_power_on";

ret = device_create_file(disk_to_dev(md->disk),

&md->power_ro_lock);

if (ret)

goto power_ro_lock_fail;

}

return ret;

power_ro_lock_fail:

device_remove_file(disk_to_dev(md->disk), &md->force_ro);

force_ro_fail:

del_gendisk(md->disk);

return ret;

}

static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,

char *buf)

{

int ret;

struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));

ret = snprintf(buf, PAGE_SIZE, "%d/n",

get_disk_ro(dev_to_disk(dev)) ^

md->read_only);

mmc_blk_put(md);

return ret;

}

static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,

const char *buf, size_t count)

{

int ret;

char *end;

struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));

unsigned long set = simple_strtoul(buf, &end, 0);

if (end == buf) {

ret = -EINVAL;

goto out;

}

set_disk_ro(dev_to_disk(dev), set || md->read_only);

ret = count;

out:

mmc_blk_put(md);

return ret;

}

2.3 读写boot分区操作

在force_ro为1的情况下,写boot分区返回Operation not permitted。

echo updt | dd of=/dev/mmcblk0boot1 bs=4 count=1 seek=0 && sync

dd: writing '/dev/mmcblk0boot1': Operation not permitted

1+0 records in

0+0 records out

然后打开force_ro=0:

echo 0 > /sys/block/mmcblk0boot1/force_ro && echo updt | dd of=/dev/mmcblk0boot1 bs=4 count=1 seek=0 && sync

通过hexdump验证一下:

hexdump -v -n 4 -s 0 /dev/mmcblk0boot1

0000000 7075 7464

0000004

3. uboot下读写boot分区

uboot下操作boot分区需要打开CONFIG_SUPPORT_EMMC_BOOT。

在Linux下/dev/mmcblk0boot1就表示切换到boot分区了,在uboot下需要先切换到boot分区。

3.1 PARTITION_CONFIG寄存器

由于默认分区是UDA,而eMMC每个分区都是独立编址的。所以要使用boot分区需要切换分区。

PARTITION_CONFIG寄存器,通过EXT_CSD_PART_CONF命令来设置。

根据下面的寄存解释,BOOT_ACK设置为0x0,;BOOT_PARTITION_ENABLE设置为0x2;PARTITION_ACCESS设置为0x2。

3.2 读取boot分区

uboot中读取boot分区,首先需要将分区切换到boot分区,然后读写分区,最后将分区切换回原来分区。

static int do_mmc_bootmode(cmd_tbl_t *cmdtp, int flag,

int argc, char * const argv[])

{

struct mmc *mmc;

int ret = BOOTMODE_NORMAL;

u32 blk, cnt, n;

void *addr;

char original_part;

addr = (void *)malloc(512);

blk = BOOTMODE_BLK_NUM;

cnt = BOOTMODE_BLK_COUNT;

mmc = init_mmc_device(curr_device, false);

if (!mmc)

{

free(addr);

return CMD_RET_FAILURE;

}

/* Switch to the Boot 2 partition */

original_part = mmc->block_dev.hwpart;

blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_BOOT2);

mmc_set_part_conf(mmc, 0, MMC_PART_BOOT2, 2);------------------------------------------切换到eMMC boot1分区。

n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);----------------------------------读取一个block。

if(n != cnt)

{

free(addr);

return CMD_RET_FAILURE;

}

/* flush cache after read */

flush_cache((ulong)addr, cnt * 512); /* FIXME */

if(*(unsigned int *)addr == BOOTMODE_UPDATE_MAGIC)

{

ret = BOOTMODE_UPDATE;

}

else

{

ret = BOOTMODE_NORMAL;

}

#if 0

for(int i = 0; i < 512/16; i++)

printf("%08x %08x %08x %08x/n", *((int *)addr+i*4), *((int *)addr+i*4+1), *((int *)addr+i*4+2), *((int *)addr+i*4+3));

#endif

/* Switch to original partition. */

blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part);----------------------切换到默认分区。

free(addr);

return ret;

}

至此可以在Linux和Uboot下对boot分区进行操作,进行bootloader烧写或者进行重要数据更新。

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址:https://www.linuxidc.com/Linux/2019-04/158316.htm

TAG:

除非注明,文章均由 Linux系统学习 整理发布,欢迎转载。如有版权争议,请联系删除。

linux分区表与uboot,Linux和Uboot下eMMC boot分区读写相关推荐

  1. linux 查看emmc分区表_Linux和Uboot下eMMC boot分区读写

    关键词:eMMC boot.PARTITION_CONFIG.force_ro等. 1. eMMC的分区 大部分eMMC都有类似如下的分区,其中BOOT.RPMB和UDA一般是默认存在的,gpp分区需 ...

  2. linux boot分区作用,Linux和Uboot下eMMC boot分区读写

    关键词:eMMC boot.PARTITION_CONFIG.force_ro等. 1. eMMC的分区 大部分eMMC都有类似如下的分区,其中BOOT.RPMB和UDA一般是默认存在的,gpp分区需 ...

  3. emmc linux 识别分区_Linux和Uboot下eMMC boot分区读写

    关键词:eMMC boot.PARTITION_CONFIG.force_ro等. 1. eMMC的分区 大部分eMMC都有类似如下的分区,其中BOOT.RPMB和UDA一般是默认存在的,gpp分区需 ...

  4. 解决Ubuntu 16.04下提示boot分区空间不足的办法

    原文地址: http://www.jb51.net/article/106976.htm https://www.linuxidc.com/Linux/2015-09/123227.htm 因为lin ...

  5. windows读写linux文件,【转载】在Windows下使用Ext2Fsd极速读写Linux硬盘

    经试验这个工具非常好用!win7也可以使用,挂载Linux硬盘的写入速度在有其它操作(如上网.开文件夹等)的时候也能达到20~30M/s.以前拷数据都要找同学的Linux系统搭临时的服务器挂硬盘.远程 ...

  6. soc eds能 编译linux,【转】在SoCEDS环境下编译和更新preloader和uboot程序的方法

    [转]在SoCEDS环境下编译和更新preloader和uboot程序的方法 [复制链接] 在SoCEDS环境下编译和更新preloader和uboot程序的方法 前面有介绍preloader在HPS ...

  7. linux系统下编译fpga工程,【工程师分享】整合Xilinx PetaLinux工程编译和Open Source U- Boot/Linux编译...

    5.1. 保留Linux和UBoot源代码 缺省情况下,PetaLinux在编译完成后会删除源代码,以节省硬盘空间.在project-spec/meta-user/conf/petalinuxbsp. ...

  8. 华山服务器安装linux系统,RHEL7/Centos7下使用QEMU搭建u-boot+Linux+NFS嵌入式开发环境(2018...

    目录 1交叉编译环境搭建 交叉编译器下载链接: 1.1交叉编译器下载 将其下载到/usr目录下并解压. 解压命令: tar -xvf gcc-linaro-7.2.1-2017.11-i686_arm ...

  9. Linux系统移植:官板 uboot 修改(下)

    文章目录 Linux系统移植:官板 uboot 修改(下) 一.LCD 驱动修改 二.网口驱动修改 2.1 PHY 地址修改 2.2 删除 uboot 中 74LV595 的驱动代码 2.3 添加 I ...

最新文章

  1. x264代码剖析(一):图文详解x264在Windows平台上的搭建
  2. JS中的内置对象 --- Math、Date、Array、String
  3. 日记 [2008年03月23日]不编译内核给iptables增加模块
  4. 关于Windows 1803版本内核隔离打开后无法关闭的解决方案
  5. Dubbo分析之Registry层
  6. 配置LACP模式链路聚合
  7. 64位Windows2003下如何正确发布VesnData.Net(VDN)
  8. AD15的PCB设计流程及基本设置
  9. FPGA经典设计:再读正点原子SDRAM控制器
  10. 良好的Coding习惯,从P3C开始--阿里P3C代码规范扫描插件
  11. Scrum敏捷开发流程
  12. Android之视频裁剪
  13. 自主招生计算机系面试,各大高校自主招生“扎堆”六月 北大自主招生面试考题公布...
  14. 什么是 IP 冲突以及如何解决?
  15. Linux-菜鸟入门自学 (二)
  16. 辉芒微IO单片机FT60F11F-MRB
  17. java8新特性学习笔记(Lambda,stream(),filter(),collect(),map())
  18. java-十六进制转八进制
  19. 更改HTML提交按钮的名字
  20. 百度人脸识别搜索是怎么实现的

热门文章

  1. SAP Spartacus layout设计原理
  2. 使用ConfigModule.withConfig替换SAP Spartacus标准Component
  3. com.sap.ui5.resource.ResourceServlet的工作原理介绍
  4. 如何将bing搜索页面以HTML Mashup的方式嵌入到SAP C4C页面
  5. year range in CRM Fiori Sales Pipeline
  6. Oracle要对Java收费了,SAP基于Java技术栈的那些产品的客户怎么办
  7. SAP S/4HANA product search generated SQL statement的生产原理介绍
  8. 如何查看某个js 变量 runtime 类型
  9. 快速找到message toast弹出的application代码位置
  10. 控件setVisible为false会导致控件被移除