linux分区表与uboot,Linux和Uboot下eMMC boot分区读写
关键词: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分区读写相关推荐
- linux 查看emmc分区表_Linux和Uboot下eMMC boot分区读写
关键词:eMMC boot.PARTITION_CONFIG.force_ro等. 1. eMMC的分区 大部分eMMC都有类似如下的分区,其中BOOT.RPMB和UDA一般是默认存在的,gpp分区需 ...
- linux boot分区作用,Linux和Uboot下eMMC boot分区读写
关键词:eMMC boot.PARTITION_CONFIG.force_ro等. 1. eMMC的分区 大部分eMMC都有类似如下的分区,其中BOOT.RPMB和UDA一般是默认存在的,gpp分区需 ...
- emmc linux 识别分区_Linux和Uboot下eMMC boot分区读写
关键词:eMMC boot.PARTITION_CONFIG.force_ro等. 1. eMMC的分区 大部分eMMC都有类似如下的分区,其中BOOT.RPMB和UDA一般是默认存在的,gpp分区需 ...
- 解决Ubuntu 16.04下提示boot分区空间不足的办法
原文地址: http://www.jb51.net/article/106976.htm https://www.linuxidc.com/Linux/2015-09/123227.htm 因为lin ...
- windows读写linux文件,【转载】在Windows下使用Ext2Fsd极速读写Linux硬盘
经试验这个工具非常好用!win7也可以使用,挂载Linux硬盘的写入速度在有其它操作(如上网.开文件夹等)的时候也能达到20~30M/s.以前拷数据都要找同学的Linux系统搭临时的服务器挂硬盘.远程 ...
- soc eds能 编译linux,【转】在SoCEDS环境下编译和更新preloader和uboot程序的方法
[转]在SoCEDS环境下编译和更新preloader和uboot程序的方法 [复制链接] 在SoCEDS环境下编译和更新preloader和uboot程序的方法 前面有介绍preloader在HPS ...
- linux系统下编译fpga工程,【工程师分享】整合Xilinx PetaLinux工程编译和Open Source U- Boot/Linux编译...
5.1. 保留Linux和UBoot源代码 缺省情况下,PetaLinux在编译完成后会删除源代码,以节省硬盘空间.在project-spec/meta-user/conf/petalinuxbsp. ...
- 华山服务器安装linux系统,RHEL7/Centos7下使用QEMU搭建u-boot+Linux+NFS嵌入式开发环境(2018...
目录 1交叉编译环境搭建 交叉编译器下载链接: 1.1交叉编译器下载 将其下载到/usr目录下并解压. 解压命令: tar -xvf gcc-linaro-7.2.1-2017.11-i686_arm ...
- Linux系统移植:官板 uboot 修改(下)
文章目录 Linux系统移植:官板 uboot 修改(下) 一.LCD 驱动修改 二.网口驱动修改 2.1 PHY 地址修改 2.2 删除 uboot 中 74LV595 的驱动代码 2.3 添加 I ...
最新文章
- x264代码剖析(一):图文详解x264在Windows平台上的搭建
- JS中的内置对象 --- Math、Date、Array、String
- 日记 [2008年03月23日]不编译内核给iptables增加模块
- 关于Windows 1803版本内核隔离打开后无法关闭的解决方案
- Dubbo分析之Registry层
- 配置LACP模式链路聚合
- 64位Windows2003下如何正确发布VesnData.Net(VDN)
- AD15的PCB设计流程及基本设置
- FPGA经典设计:再读正点原子SDRAM控制器
- 良好的Coding习惯,从P3C开始--阿里P3C代码规范扫描插件
- Scrum敏捷开发流程
- Android之视频裁剪
- 自主招生计算机系面试,各大高校自主招生“扎堆”六月 北大自主招生面试考题公布...
- 什么是 IP 冲突以及如何解决?
- Linux-菜鸟入门自学 (二)
- 辉芒微IO单片机FT60F11F-MRB
- java8新特性学习笔记(Lambda,stream(),filter(),collect(),map())
- java-十六进制转八进制
- 更改HTML提交按钮的名字
- 百度人脸识别搜索是怎么实现的
热门文章
- SAP Spartacus layout设计原理
- 使用ConfigModule.withConfig替换SAP Spartacus标准Component
- com.sap.ui5.resource.ResourceServlet的工作原理介绍
- 如何将bing搜索页面以HTML Mashup的方式嵌入到SAP C4C页面
- year range in CRM Fiori Sales Pipeline
- Oracle要对Java收费了,SAP基于Java技术栈的那些产品的客户怎么办
- SAP S/4HANA product search generated SQL statement的生产原理介绍
- 如何查看某个js 变量 runtime 类型
- 快速找到message toast弹出的application代码位置
- 控件setVisible为false会导致控件被移除