三星公司uboot模式下更改分区(EMMC)大小fdisk命令

本文介绍三星平台下通过Uboot的fdisk命令调整EMMC分区的方法。涉及代码修改、分区格式化、系统烧录等步骤,并详细解析了fdisk命令的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三星公司uboot模式下更改分区(EMMC)大小fdisk命令

一、分区

三星平台一般把它分为四个区:

(1)、fat分区,作为sd卡用;

(2)、系统分区,相当为电脑c 盘,用来安装android系统;

(3)、userdata分区;

(4)、cache分区。

二、分区更改操作过程

1,  更改uboot中代码/common/cmd_mmc_fdisk.c

在这个文件中我们可以看到对四个分区大小的定义:

#define		BLOCK_SIZE			512
#define		BLOCK_END			0xFFFFFFFF
#define		_10MB				(10*1024*1024)
#define		_100MB				(100*1024*1024)
#define		_300MB				(300*1024*1024)
#define		_8_4GB				(1023*254*63)
#define		_1GB				(1024*1024*1024)
#define		DISK_START			RAW_AREA_SIZE//mj (16*1024*1024) //same as raw area size

#define		SYSTEM_PART_SIZE		_1GB //_300MB
#define		USER_DATA_PART_SIZE		_1GB //_300MB //_1GB
#define		CACHE_PART_SIZE			_300MB

#define		CHS_MODE			0
#define		LBA_MODE			!(CHS_MODE)
2、重新分区 fdisk -c 0 命令

3、分区格式法

3.1、输入如下命令 fatformat mmc 0:1


3.2、输入如下命令fatformat mmc 0:2


3.3、输入如下命令fatformat mmc 0:3


3.4、输入如下命令fatformat mmc 0:4


3.5在超级终端中输入“fastboot”


4、把整个系统重新烧录

在PC机上运行“USB_fastboot_tool”-->“platform-tools”文件夹中的文件
“cmd.exe”(cmd.exe可执行文件是Windows自带的命令行工具,光盘里面的是Win7下
的,如果提示版本不兼容,请使用你自己系统里面的cmd.exe工具)

[html]  view plain  copy
  1. fastboot.exe flash bootloader u-boot-iTOP-4412.bin
  2. fastboot.exe flash kernel zImage
  3. fastboot.exe flash ramdisk ramdisk-uboot.img 
  4. fastboot.exe flash system system.img  

三、fdisk 命令分析

  1. int do_fdisk(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  
  2. {  
  3.     if ( argc == 3 || argc ==6 )  
  4.     {  
  5.         if ( strcmp(argv[1], "-c") == 0 )  
  6.             return create_mmc_fdisk(argc, argv);  //格式化分区          else if ( strcmp(argv[1], "-p") == 0 )  
  7.             return print_mmc_part_info(argc, argv); //打印出分区的信息  
  8.     }  
  9.     else //如果不满足argc条件,打印出帮助信息  
  10.     { 
  11.         printf("Usage:\nfdisk <-p> <device_num>\n");  
  12.         printf("fdisk <-c> <device_num> [<sys. part size(MB)> <user data part size> <cache part size>]\n");  
  13.     }  
  14.     return 0;  

2、do_fdisk的实现函数

   我们平时用的fdisk -c 0 格式化inand ,fdisk -p 0 查看分区信息,在这里可以看到对这两条命令的解析:

[cpp]  view plain  copy
  1. int do_fdisk(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  
  2. {  
  3.     if ( argc == 3 || argc ==6 )  
  4.     {  
  5.         if ( strcmp(argv[1], "-c") == 0 )  
  6.             return create_mmc_fdisk(argc, argv);  //格式化分区  
  7.         else if ( strcmp(argv[1], "-p") == 0 )  
  8.             return print_mmc_part_info(argc, argv); //打印出分区的信息  
  9.     }  
  10.     else //如果不满足argc条件,打印出帮助信息  
  11.     {  
  12.         printf("Usage:\nfdisk <-p> <device_num>\n");  
  13.         printf("fdisk <-c> <device_num> [<sys. part size(MB)> <user data part size> <cache part size>]\n");  
  14.     }  
  15.     return 0;  

3、如果为fdisk -c 0进,进入 create_mmc_fdisk,我们再分析这个函数

[cpp]  view plain  copy
  1. int create_mmc_fdisk(int argc, char *argv[])  
  2. {  
  3.     int     rv;  
  4.     int     total_block_count;  
  5.     unsigned char   mbr[512];  
  6.     memset(mbr, 0x00, 512);   
  7. total_block_count = get_mmc_block_count(argv[2]); //获得块信息,以512 为单位  
  8.     if (total_block_count < 0)  
  9.         return -1;  
  10.     //格式化INAND  
  11.     make_mmc_partition(total_block_count, mbr, (argc==6?1:0), argv);  
  12.   
  13.     rv = put_mmc_mbr(mbr, argv[2]);  
  14.     if (rv != 0)  
  15.         return -1;  
  16.           
  17.     printf("fdisk is completed\n");  //分区成功,打印信息  
  18.   
  19.     argv[1][1] = 'p';  
  20.     print_mmc_part_info(argc, argv);  //和fdisk –p 0 作用一样,打印出分区信息  
  21.     return 0;  
  22. }  

4、我们看下格式化函数make_mmc_partition是怎么实现的吧。

这里面有两上参考比较重要:block_start 、block_offset;每个区块的开始和大小(偏移量),我们画个图来更好的表示这个吧。

在这里我们可以看到

#define		SYSTEM_PART_SIZE		_1GB //_300MB
#define		USER_DATA_PART_SIZE		_1GB //_300MB //_1GB
#define		CACHE_PART_SIZE			_300MB

这几宏的应用,block_start= calc_unit(CFG_PARTITION_START, sdInfo),计算分区大小

[cpp]  view plain  copy
  1. int make_mmc_partition(int total_block_count, unsigned char *mbr, int flag, char *argv[])  
  2. {  
  3.     int     block_start = 0, block_offset;  
  4.   
  5.     SDInfo      sdInfo;  
  6.     PartitionInfo   partInfo[4];  
  7.     memset((unsigned char *)&sdInfo, 0x00, sizeof(SDInfo));  
  8.     get_SDInfo(total_block_count, &sdInfo);  
  9.   
  10. ///////////////////////////////////////////////////////////  
  11.     block_start = calc_unit(CFG_PARTITION_START, sdInfo); //得到第一分区的开始地址  
  12.     if (flag)  
  13.         block_offset = calc_unit((unsigned long long)simple_strtoul(argv[3], NULL, 0)*1024*1024, sdInfo);  
  14.     else  
  15.         block_offset = calc_unit(SYSTEM_PART_SIZE, sdInfo);//计算分区大小,这里面的值是不是很熟悉,就是我们开始改那些地方,这个是系统分区的  
  16.   
  17.     partInfo[0].bootable    = 0x00;  
  18.     partInfo[0].partitionId = 0x83;  
  19.   
  20.     make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[0]);//开始分区  
  21.   
  22. ///////////////////////////////////////////////////////////   
  23.     block_start += block_offset;//更改下一个分析的开始地址,这样可以保证分区连续  
  24.     if (flag)  
  25.         block_offset = calc_unit((unsigned long long)simple_strtoul(argv[4], NULL, 0)*1024*1024, sdInfo);  
  26.     else  
  27.         block_offset = calc_unit(USER_DATA_PART_SIZE, sdInfo);  
  28.       
  29.     partInfo[1].bootable    = 0x00;  
  30.     partInfo[1].partitionId = 0x83;  
  31.   
  32.     make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[1]);  
  33.   
  34. ///////////////////////////////////////////////////////////   
  35.     block_start += block_offset;  
  36.     if (flag)  
  37.         block_offset = calc_unit((unsigned long long)simple_strtoul(argv[5], NULL, 0)*1024*1024, sdInfo);  
  38.     else  
  39.         block_offset = calc_unit(CACHE_PART_SIZE, sdInfo);  
  40.   
  41.     partInfo[2].bootable    = 0x00;  
  42.     partInfo[2].partitionId = 0x83;  
  43.   
  44.     make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[2]);  
  45.   
  46. ///////////////////////////////////////////////////////////   
  47.     block_start += block_offset;  
  48.     block_offset = BLOCK_END;  
  49.   
  50.     partInfo[3].bootable    = 0x00;  
  51.     partInfo[3].partitionId = 0x0C;  
  52.   
  53.     make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[3]);  
  54.   
  55. ///////////////////////////////////////////////////////////   
  56.     memset(mbr, 0x00, sizeof(mbr));  
  57.     mbr[510] = 0x55; mbr[511] = 0xAA;  
  58.       
  59.     encode_partitionInfo(partInfo[0], &mbr[0x1CE]);  
  60.     encode_partitionInfo(partInfo[1], &mbr[0x1DE]);  
  61.     encode_partitionInfo(partInfo[2], &mbr[0x1EE]);  
  62.     encode_partitionInfo(partInfo[3], &mbr[0x1BE]);  
  63.       
  64.     return 0;  
  65. }  

5、fidsk – p 0的实现函数也很简单

[cpp]  view plain  copy
  1. int print_mmc_part_info(int argc, char *argv[])  
  2. {  
  3.     int     rv;  
  4.   
  5.     PartitionInfo   partInfo[4];  
  6.       
  7.     rv = get_mmc_part_info(argv[2], 1, &(partInfo[0].block_start), &(partInfo[0].block_count),  
  8.             &(partInfo[0].partitionId) );  
  9.       
  10.     rv = get_mmc_part_info(argv[2], 2, &(partInfo[1].block_start), &(partInfo[1].block_count),  
  11.             &(partInfo[1].partitionId) );  
  12.   
  13.     rv = get_mmc_part_info(argv[2], 3, &(partInfo[2].block_start), &(partInfo[2].block_count),  
  14.             &(partInfo[2].partitionId) );  
  15.   
  16.     rv = get_mmc_part_info(argv[2], 4, &(partInfo[3].block_start), &(partInfo[3].block_count),  
  17.             &(partInfo[3].partitionId) );  
  18.   
  19.     printf("\n");     
  20.     printf("partion #    size(MB)     block start #    block count    partition_Id \n");  
  21.   
  22.     if ( (partInfo[0].block_start !=0) && (partInfo[0].block_count != 0) )   
  23.         printf("   1        %6d         %8d        %8d          0x%.2X \n",  
  24.             (partInfo[0].block_count / 2048), partInfo[0].block_start,  
  25.             partInfo[0].block_count, partInfo[0].partitionId);  
  26.       
  27.     if ( (partInfo[1].block_start !=0) && (partInfo[1].block_count != 0) )   
  28.         printf("   2        %6d         %8d        %8d          0x%.2X \n",  
  29.             (partInfo[1].block_count / 2048), partInfo[1].block_start,  
  30.             partInfo[1].block_count, partInfo[1].partitionId);  
  31.       
  32.     if ( (partInfo[2].block_start !=0) && (partInfo[2].block_count != 0) )   
  33.         printf("   3        %6d         %8d        %8d          0x%.2X \n",  
  34.             (partInfo[2].block_count / 2048), partInfo[2].block_start,  
  35.             partInfo[2].block_count, partInfo[2].partitionId);  
  36.   
  37.     if ( (partInfo[3].block_start !=0) && (partInfo[3].block_count != 0) )   
  38.         printf("   4        %6d         %8d        %8d          0x%.2X \n",  
  39.             (partInfo[3].block_count / 2048), partInfo[3].block_start,  
  40.             partInfo[3].block_count, partInfo[3].partitionId);  
  41.   
  42.     return 1;  
  43. }  


<think>好的,用户现在问的是在U-Boot中能否给eMMC分区。首先,我需要回想一下U-Boot的功能和常见操作。U-Boot主要是一个引导加载程序,它的核心任务是初始化硬件,加载操作系统内核并启动。但用户想知道是否可以在U-Boot阶段进行eMMC分区。 接下来,我应该确认U-Boot是否支持分区操作。根据之前的知识,U-Boot确实提供了一些存储命令,比如mmc part,可以查看分区表,或者mmc write用于写入数据。但是,创建分区通常需要修改分区表,比如MBR或GPT。U-Boot是否支持直接修改这些结构呢? 我记得在U-Boot中,虽然可以访问存储设备,但并没有像fdisk或gdisk这样的高级分区工具。所以,用户可能需要通过手动操作分区表,或者预先准备好分区表数据,然后通过U-Boot写入到eMMC的特定位置。例如,使用mmc write命令将预先制作好的MBR写入到eMMC的起始扇区。 另外,用户可能需要使用U-Boot的环境变量来设置启动参数,指定内核和根文件系统的分区。这时候分区的信息需要正确,否则系统无法启动。所以,虽然U-Boot本身不提供交互式分区工具,但可以通过脚本或预先配置的方式实现分区的设定。 还需要考虑不同平台的支持情况,有些厂商可能对U-Boot进行了定制,添加了更多分区管理的命令。这时候用户需要查阅具体平台的文档,确认是否有相关扩展功能。 用户可能的真实需求是什么?也许他们希望在启动阶段之前动态调整分区,或者在量产时自动化分区过程。这时候在U-Boot中实现分区可能更高效,不需要进入完整的操作系统环境。但需要确保操作的正确性,避免损坏现有数据。 最后,我应该总结U-Boot的能力,指出虽然原生不支持交互式分区,但可以通过手动操作或脚本实现,并提醒用户注意风险,建议优先在操作系统内进行分区操作,除非有特殊需求。同时,给出具体步骤和示例命令,帮助用户理解如何操作。</think>在U-Boot中**可以间接操作eMMC分区**,但需要明确其能力边界。以下是技术细节说明: --- ### **一、U-BooteMMC分区的支持特性** | 能力 | 说明 | |-----------------------|--------------------------------------------------------------------| | **查看现有分区** | 通过`mmc part`命令显示当前分区表(仅支持MBR/GPT解析) | | **原始扇区读写** | 使用`mmc write`/`mmc read`直接操作扇区,可覆盖分区表 | | **分区访问** | 通过`mmc dev`+分区号选择分区,支持按分区读写数据 | | **无交互式工具** | 不提供类似`fdisk`的交互式分区工具 | --- ### **二、实际操作流程(示例:创建MBR分区)** 1. **查看当前eMMC布局** ```bash mmc dev 0 # 选择eMMC设备 mmc part # 显示分区表 ``` 2. **手动构建MBR分区表** - 在Linux系统中用`fdisk`生成一个MBR二进制文件(假设为`mbr.bin`),包含所需分区结构 - 将该文件通过tftp加载到内存: ```bash tftp ${loadaddr} mbr.bin ``` 3. **写入MBR到eMMC** ```bash mmc write ${loadaddr} 0 1 # 将MBR写入第0个扇区(LBA 0),1个block ``` 4. **验证分区** ```bash mmc part # 应显示新分区表 ``` --- ### **三、关键限制与注意事项** 1. **风险操作** - 直接写扇区可能破坏已有数据 - 必须确保分区表二进制数据的正确性 2. **高级分区需求** | 需求 | U-Boot解决方案 | |---------------------|----------------------------------------| | GPT分区表 | 需预先制作完整GPT头并写入34个扇区 | | 分区对齐优化 | 需人工计算对齐参数 | | 文件系统创建 | 仅支持写入裸数据,需后续在OS中格式化 | 3. **典型应用场景** - 量产设备时预烧录分区表 - 紧急修复损坏的分区表 - 无操作系统环境的低级操作 --- ### **四、推荐方案对比** | 方法 | 优点 | 缺点 | |---------------------|-----------------------------|-----------------------------| | **U-Boot手动操作** | 不依赖操作系统 | 高风险,操作复杂 | | **Linux环境下操作** | 可用`fdisk/parted`等工具 | 需要先启动到操作系统 | | **预编译脚本** | 适合批量生产 | 需要提前准备分区方案 | --- ### **五、实践建议** 1. 优先在Linux系统中完成分区操作(通过`fdisk/parted`) 2. 若必须在U-Boot中操作: - 使用`mmc read`先备份原始扇区 - 用`crc32`校验分区表数据的完整性 - 通过U-Boot脚本自动化流程: ```bash # 示例脚本片段 setenv mbr_sectors 1 tftp ${loadaddr} mbr.bin mmc write ${loadaddr} 0 ${mbr_sectors} ``` 3. 对于现代eMMC设备(≥5.0版本),建议直接操作`ext_csd`寄存器配置硬件分区(需要特定驱动支持)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值