码迷,mamicode.com
首页 > 其他好文 > 详细

文件系统与存储:MBR/EBR类型分区建立

时间:2015-04-24 16:18:19      阅读:812      评论:0      收藏:0      [点我收藏+]

标签:文件系统   分区   mbr   ebr   

1 linux启动的几个阶段:

对应关系

阶段1

 阶段2

  阶段3

 

Boise(引导从u盘,硬盘,cdrom等启动)

Grub

Kernel

系统

preloader(完成下载+启动引导)

Lk

 kernel

Systermimg

 

android智能机上 分区表再各个阶段的作用:

技术分享

 

技术分享

注意:Dumchar是debug信息用(用户模式读写某分区镜像等),分区表的建立等由内核block子系统来完成。dumchar调试如下:

 

Dumchar_info的分区信息在哪里创建:???

/dev/bootimg

 /dev/otp

/dev/nvram

 

dumchar_probe () ---

{

for (l = 0; l<PART_NUM; l++){

if(!strcmp(dumchar_devices[l].dumname,"otp")){

dumchar_device[l]= device_create(dumchar_class, NULL, MKDEV(major, l),NULL,"otp_bak");

}else{

dumchar_device[l]= device_create(dumchar_class, NULL,MKDEV(major, l),NULL, dumchar_devices[l].dumname);

}

}

 

。。。。。

}

而且绑定了dumchar_fops:

structfile_operations dumchar_fops = {

.owner=     THIS_MODULE,

.llseek=    dumchar_llseek,

.read =             dumchar_read,

.write =     dumchar_write,

.unlocked_ioctl=     dumchar_ioctl,

.open=          dumchar_open,

.release=   dumchar_release,

};

所以可以读写分区。获取分区的方法:

1.flashtool ---根据scat读取分区

2.adb 获取:

Adb shell dd if=/dev/bootimg of=/sdcard/boot.img bs=6291456 count=1  

  -----获取bootimg分区  bs=6291456 (mtk一般是6MB)。这里是把整个bootimage分区读出,也是可以的,正确的读法是根据

   ---------然后可以使用split_bootimg.pl 脚本bootimg中提取出roofs

Adb  pull /dev/bootimg 就是bootimg分区开始 读取flash

Adb  pull /dev/mbr 就是mbr分区开始 读取flash

 

 

2 分析MBR

技术分享

主引导记录最开头是第一阶段引导代码。其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后将控制权交给硬盘上的引导程序(如GNUGRUB)。它不依赖任何操作系统,而且启动代码也是可以改变的,从而能够实现多系统引导

------这里为00,应为不需要操作系统引导,只是单系统,所以我们是可以做一个手机多个操作系统的。

 

3 内核什么时候读取MBR的分区表和建立block设备的节点呢?以及其作用?

首先建立磁盘(比如一块emmc,一块sd卡,一个硬盘)的块设备节点,先了解两个知识点:

1)linux内核中支持的磁盘类型:(做分区表都是根据磁盘类型来做的分区)

static int(*check_part[])(struct parsed_partitions *) = {

/*

 * Probe partition formats with tables at diskaddress 0

 * that also have an ADFS boot block at 0xdc0.

 */

#ifdefCONFIG_ACORN_PARTITION_ICS

adfspart_check_ICS,

#endif

#ifdefCONFIG_ACORN_PARTITION_POWERTEC

adfspart_check_POWERTEC,

#endif

#ifdefCONFIG_ACORN_PARTITION_EESOX

adfspart_check_EESOX,

#endif

 

/*

 * Now move on to formats that only havepartition info at

 * disk address 0xdc0.  Since these may also have stale

 * PC/BIOS partition tables, they need to comebefore

 * the msdos entry.

 */

#ifdefCONFIG_ACORN_PARTITION_CUMANA

adfspart_check_CUMANA,

#endif

#ifdefCONFIG_ACORN_PARTITION_ADFS

adfspart_check_ADFS,

#endif

 

#ifdefCONFIG_EFI_PARTITION

efi_partition,                /*this must come before msdos */

#endif

#ifdefCONFIG_SGI_PARTITION

sgi_partition,

#endif

#ifdefCONFIG_LDM_PARTITION

ldm_partition,                /*this must come before msdos */

#endif

#ifdefCONFIG_MSDOS_PARTITION

msdos_partition,---------------》手机上基本上是这种。

#endif

#ifdefCONFIG_OSF_PARTITION

osf_partition,

#endif

#ifdefCONFIG_SUN_PARTITION

sun_partition,

#endif

#ifdefCONFIG_AMIGA_PARTITION

amiga_partition,

#endif

#ifdefCONFIG_ATARI_PARTITION

atari_partition,

#endif

#ifdefCONFIG_MAC_PARTITION

mac_partition,

#endif

#ifdefCONFIG_ULTRIX_PARTITION

ultrix_partition,

#endif

#ifdefCONFIG_IBM_PARTITION

ibm_partition,

#endif

#ifdefCONFIG_KARMA_PARTITION

karma_partition,

#endif

#ifdefCONFIG_SYSV68_PARTITION

sysv68_partition,

#endif

NULL

};

2)EMMC情况下:#ls /dev/block/

 /dev/block/mmcblk0代表第一个SD磁盘

 /dev/block/mmcblk0p1 代表第一个SD卡设备的第一个分区;

brw------- root     root    179,   0 2012-08-15 18:07mmcblk0----emmc本身--MBR

brw------- root     root    179,   8 2012-08-15 18:07mmcblk0boot0---pl

brw------- root     root    179,  16 2012-08-15 18:07mmcblk0boot1---dsp

brw------- root     root    179,   1 2012-08-15 18:07mmcblk0p1-----ebr1

brw------- root     root    179,   2 2012-08-15 18:07mmcblk0p2

brw------- root     root    179,   3 2012-08-15 18:07mmcblk0p3

brw------- root     root    179,   4 2012-08-15 18:07mmcblk0p4

brw------- root     root    179,   5 2012-08-15 18:07mmcblk0p5

brw------- root     root    179,   6 2012-08-15 18:07mmcblk0p6

 

4 分区检查和建立过程:emmc设备与mtd设备为例:

目录:

1)mmc设备:对MMC驱动 =mmc_driver为例

2)MTD设备:nand flash=:

 ---------------------------------------------------------/////-----------------------------------------

1)mmc设备:对MMC驱动 =mmc_driver为例

Emmc 的基于mbrebr的分区类型的分区创建过程,主要4

Step1:   mmc设备与mmc度驱动绑定:

step2mmc注册到通用块子系统,建立 emmc系统分区disk节点和boot0/1分区节点(不是用户分区user data):

brw-------root     root     179,  0 2012-08-15 18:07 mmcblk0----emmc本身--MBR

brw-------root     root     179,  8 2012-08-15 18:07 mmcblk0boot0---pl

brw-------root     root     179, 16 2012-08-15 18:07 mmcblk0boot1---dsp

                Block.c (kernel\drivers\mmc\card):mmc_blk_probe()。

step3: 内核获取分区表:rescan_partitions()---》if (!get_capacity(disk) || !(state = check_partition()))

依次使用内核支持的磁盘类型(注意不是文件系统),来轮询disk。返回各个分区的信息(查看是否有MBR和DBR等分区信息):

for (p = 1; p < state->limit; p++)//获取如下两个关键字:各个分区大小和分区的起始扇区

            sector_t size =state->parts[p].size;分区大小

           sector_t from =state->parts[p].from;分区的起始扇区。

 

step4:绑定建立各个用户分区的/dev/block/mmcblk0pxxx节点:rescan_partitions()----》add_partition()

 

     以上4步都是在mmc_blk_probe中调起完成;

   

Step5:从应用层开始mount各个分区:

init进程,通过解析init.rc:

onfs_property:ro.mount.fs=EXT4

    write /proc/bootprof"INIT:eMMC:Mount_START"

    exec /sbin/e2fsck -p /emmc@android

    # Mount /system rw first to give thefilesystem a chance to save a checkpoint

    #mount ext4 emmc@android /system waitcommit=1,data=journal,noauto_da_alloc

……..

   //////////////----------------------------------------------------------------------------------////////////////////////////

下面细节分析各个步骤:

Step1:mmc设备与mmc度驱动绑定:

 

mmc设备与mmc度驱动如何绑定?步骤分为:

步骤1)首先是emmc的设备先挂载,也就是emmc的控制器先初始化设备:

然后在挂载mmc设备驱动时,执行驱动程序中的xx_mmc_probe(),检测host设备中挂载的sd设备。此时probe函数会创建一个host设备,然后开启一个延时任务mmc_rescan()。

驱动挂载成功后,mmc_rescan()函数被执行,然后对卡进行初始化(步骤后面详细讲述)。

假如扫描到总线上挂有有效的设备,就调用相对应的函数把设备装到系统中,mmc_attach_sdio()、mmc_attach_sd()、mmc_attach_mmc()这三个函数分别是装载sdio设备,sd卡和mmc卡的。

在sd卡中,驱动循环发送ACMD41、CMD55给卡,读取OCR寄存器,成功后,依次发送CMD2(读CID)、CMD3(得到RCA)、CMD9(读CSD)、CMD7(选择卡)。后面还有几个命令分别是ACMD41&CMD51,使用CMD6切换一些功能,如切换到高速模式。

经过上述步骤,已经确定当前插入的卡是一张有效、可识别的存储卡。然后调用mmc_add_card()把存储卡加到系统中。正式与系统驱动连接在一起。

步骤2mmc驱动程序去probe设备(也就是完成mmc设备上的分区初始化):

卡设备加到系统中后,通知mmc块设备驱动。块设备驱动此时调用probe函数,即mmc_blk_probe()函数,mmc_blk_probe()首先分配一个新的mmc_blk_data结构变量,然后调用mmc_init_queue,初始化blk队列。然后建立一个线程mmc_queue_thread()。

 

例如mtk的流程:

比如SD卡(or emmcflash)在识别到之后:

1)添加设备(就是step1的流程):mmc_add_card()----->device_add(&card->dev);----->bus_probe_device()---->device_attach()--:参数card传到mmc bus,这样当mmc驱动 mmc_blk_probe()的就能probe这个mmc设备。

 

2)与MMC驱动绑定:mmc_driver:

Block.c(kernel\drivers\mmc\card):        .probe                =mmc_blk_probe,:

mmc块设备驱动:mmc_blk_probe(struct mmc_card *card)---->mmc_add_disk()

---》通用块设备子系统:add_disk()---》register_disk()//注册到通用块子系统中

----->blkdev_get()------》__blkdev_get()----》

---->rescan_partitions()--->check_partition()查看是否有MBR和DBR等分区信息.

 

磁盘与驱动绑定后,就进入mmc_blk_probe();

 

step2mmc注册到通用块子系统,建立 emmc的系统分区:disk节点和boot0/1分区节点(非用户分区user data):

 emmc的系统分区:disk节点和boot0/1分区节点:/dev/block/mmcblk0boot0/boot1

brw-------root     root     179,  0 2012-08-15 18:07 mmcblk0----emmc本身--MBR

brw-------root     root     179,  8 2012-08-15 18:07 mmcblk0boot0---pl

brw-------root     root     179, 16 2012-08-15 18:07 mmcblk0boot1---dsp

 

代码分析:建立emmc磁盘分区节点的代码:注意只是创建节点文件,但是还没有绑定分区的信息(扇区起始,大小);

Block.c (kernel\drivers\mmc\card):

staticint mmc_blk_probe(struct mmc_card *card)//分析

这里主要两个步骤:

步骤1:根据card(也就是emmc磁盘)参数,分配好 磁盘的节点文件 磁盘的分区的节点文件

步骤2:增加(绑定)磁盘到 步骤1创建好的节点文件。

{

….

md= mmc_blk_alloc(card);//分配disk节点/dev/block/mmcblk0----》分配函数mmc_blk_alloc_req(){

….

snprintf(md->disk->disk_name,sizeof(md->disk->disk_name),

                                                 "mmcblk%d%s",md->name_idx, subname ? subname : "");

...                                

}

...

 

if (mmc_blk_alloc_parts(card, md))//分配disk的分区的节点:/dev/block/mmcblk0boot0/boot1

…..

            if (mmc_add_disk(md))//增加disk 到节点:/dev/block/mmcblk0  同时会调起到 step3:step4 完成用户分区的节点/dev/block/mmcblk0pxx节点建立

gotoout;

 

list_for_each_entry(part_md,&md->part, part) {   循环增加disk的分区到各自节点:一般是两个part节点,/dev/block/mmcblk0boot0 boot1

if(mmc_add_disk(part_md))

gotoout;

}

 

…..

}

 

建立 emmc的系统分区:disk节点和boot0/1分区节点(不是用户分区user data

static structmmc_blk_data *mmc_blk_alloc_req(structmmc_card *card,

      struct device *parent,

      sector_t size,

      bool default_ro,

      const char *subname,

      int area_type)

{

…..

snprintf(md->disk->disk_name,sizeof(md->disk->disk_name),

 "mmcblk%d%s",md->name_idx, subname ? subname : "");

………

 

)

问题:参数card 从何而来?

因为参数card里面的card->part[idx] 决定步骤2中创建节点的分区参数。sd卡是:sd.c@mmc_sd_init_card(),这里mmc为例,

mmc_attach_mmc()---->mmc_init_card()--->mmc_alloc_card()构造新的card参数。

   mmc_get_ext_csd(){获取extcsd参数

mmc_send_ext_csd()---》mmc_send_cxd_data()

{

...

sg_init_one(&sg,data_buf, len);初始化scatterlist缓冲。“在SD/MMC代码中,在发起request的时候,都是通过scatterlist来发送数据的,定义在mmc_data里面”

...

mmc_set_data_timeout()发送MMC_SEND_EXT_CSD

}

 

sd控制器驱动处理:MMC_SEND_EXT_CSD命令:

Sd.c  msdc_do_request ()

{

 

if(cmd->opcode == MMC_SEND_EXT_CSD) {

 

msdc_get_data(ext_csd,data,host->dma_xfer);

通过sg库函数。ext_csd信息放到scatterlist 缓冲

staticint msdc_get_data(u8 *dst, struct mmc_data *data, int dma_xfer)

{

intleft;

u8*ptr;

structscatterlist *sg = data->sg;

intnum = data->sg_len;

while(num) {

left= msdc_sg_len(sg,dma_xfer);

ptr= (u8 *) sg_virt(sg);

memcpy(dst,ptr, left);

sg= sg_next(sg);

dst+= left;

num--;

}

return0;

}

 

}

  然后使用ext CSD: mmc_read_ext_csd()---->

    for (idx = 0; idx <MMC_NUM_BOOT_PARTITION; idx++) {

part_size= ext_csd[EXT_CSD_BOOT_MULT] << 17;

mmc_part_add(card, part_size,

EXT_CSD_PART_CONFIG_ACC_BOOT0+ idx,

"boot%d", idx, true,--------------------》用的是boot%d

MMC_BLK_DATA_AREA_BOOT);

}

利用ext csd参数 构造出一个card

   static inline void mmc_part_add(struct mmc_card *card, unsigned int size,

unsignedint part_cfg, char *name, int idx, bool ro,

intarea_type)

{

card->part[card->nr_parts].size = size;

card->part[card->nr_parts].part_cfg = part_cfg;

sprintf(card->part[card->nr_parts].name, name, idx);

card->part[card->nr_parts].force_ro = ro;

card->part[card->nr_parts].area_type= area_type;

card->nr_parts++;

}

也就是card->part来自ext_csd.   ext_csd存放的是什么呢?就是emmc系统分区‘,不是user分区,如下:

4 Default Areas ofMemory Device

–2 x Boot Area Partitions for Booting(可以使128k4mb 8mb不等)

–1 x Replay Protected Memory Block Area Partition-----RPMB

–1 x User Data Area

 

技术分享

 

 

step3: 内核获取分区表:rescan_partitions()---》if (!get_capacity(disk) || !(state = check_partition()))

 

调用流程:

mmc块设备驱动:mmc_blk_probe----->mmc_add_disk()

                                  Genhd.c(trunk\kernel-3.10\block):void add_disk(structgendisk *disk)

---》通用块设备子系统:add_disk()---》register_disk()//注册到通用块子系统中

----->blkdev_get()----------__blkdev_get()----》

---->rescan_partitions()--->:

每个磁盘有几个分区,每个分区的起始扇区是多少,每个分区的扇区个数是多少是怎么来的?

答案--check_partition()依次使用内核支持的磁盘类型(注意不是文件系统),来轮询disk。返回各个分区的信息(查看是否有MBR和DBR等分区信息):

for (p = 1; p < state->limit;p++)//获取如下两个关键字:分区的扇区大小和分区的起始扇区

            sector_tsize = state->parts[p].size;分区大小

                          sector_t from =state->parts[p].from;分区的起始扇区。

3.1 轮询disk:

while (!res&& check_part[i]) {

memset(state->parts,0, state->limit * sizeof(state->parts[0]));

res= check_part[i++](state);

 

3.2  对于msdoc系统:check_partition 会调起 msdos_partition:

 分析:

int msdos_partition(structparsed_partitions *state)

{

sector_tsector_size = bdev_logical_block_size(state->bdev) / 512;

Sectorsect;

unsignedchar *data;

structpartition *p;

structfat_boot_sector *fb;

intslot;

 

data = read_part_sector(state, 0, &sect);//读取逻辑0号扇区-也就是512个字节

if(!data)

return-1;

if(!msdos_magic_present(data + 510)) {

put_dev_sector(sect);

return0;

}

 

if(aix_magic_present(state, data)) {

put_dev_sector(sect);

strlcat(state->pp_buf," [AIX]", PAGE_SIZE);

return0;

}

 

/*

 * Now that the 55aa signature is present, thisis probably

 * either the boot sector of a FAT filesystemor a DOS-type

 * partition table. Reject this in case theboot indicator

 * is not 0 or 0x80.

 */

//占用512个字节的MBR中,偏移地址01BEH--01FDH的64个字节,为4个分区项内容(分区信息表),所以这里+0x1be

p = (struct partition *) (data + 0x1be);

for(slot = 1; slot <= 4; slot++, p++) {

if(p->boot_ind != 0 && p->boot_ind != 0x80) {

/*

 * Even without a valid boot inidicator value

 * its still possible this is valid FATfilesystem

 * without a partition table.

 */

fb= (struct fat_boot_sector *) data;

if(slot == 1 && fb->reserved && fb->fats

&&fat_valid_media(fb->media)) {

strlcat(state->pp_buf,"\n", PAGE_SIZE);

…….

……..

for (slot = 1 ; slot <= 4 ; slot++, p++) {//获取如下两个关键字:分区大小和分区的起始扇区

sector_t start = start_sect(p)*sector_size;

sector_t size = nr_sects(p)*sector_size;

if(!size)

continue;

if (is_extended_partition(p)) {-----处理扩展分区,EBR1 EBR2

查看 mbr 信息:例如

$ file MBR

MBR: x86 boot sector;

partition 1: ID=0x5,starthead 0, startsector 32, 4294967295 sectors;//ID=0x05 表示扩展 Dos 分区--------->跳转到 EBR1

partition 2: ID=0x83,starthead 0, startsector 44096, 10240 sectors; //0x83 表示该分区是 EXT2 类型,size=5MBSEC_RO

partition 3: ID=0x83,starthead 0, startsector 67392, 786432 sectors; ////0x83 表示该分区是 EXT2类型,size=384MB ANDROID

partition 4: ID=0x83,starthead 0, startsector 855872, 878592 sectors, code offset 0x0////0x83EXT2类型.size=429MB CACHE

------ID表示 Partition Type 也就是分区文件系统类型

分区类型定义在:genhd.h

/*

 * prevent someone doing mkfs or mkswap on an

 * extended partition, but leave room for LILO

 * FIXME: this uses one logical sector for >512b

 * sector, although it may not beenough/proper.

 */

sector_tn = 2;

n= min(size, max(sector_size, n));

put_partition(state, slot, start, n);--》读取该扩展分区,同样读取逻辑扇区0 512个字节

……………

 

 

 

什么作用?利用mbr里面的分区信息:用户在访问用户分区的时候,提供偏移地址?

有些平台需要,比如82 使用的是线性地址。92用的是逻辑地址。如下82的错:

由于MBR分区必须要处于Userarea,因此这时就会出现访问地址的offset计算错误。通常在开机uart kernel log中会看到类似如下的错误提示:

[   3.309425] (2)[62:mmcqd/0][MSDC] msdc0 -> Address offset in USERREGION(Capacity 14912 MB) is 0xffffe400 <- msdc_cal_offset() : L<3104>PID<mmcqd/0><0x3e>

[    3.309449] (2)[62:mmcqd/0][MSDC] msdc0-> XXX Address offset error(-7168),please check MBR start address!! <-msdc_cal_offset() : L<3106> PID<mmcqd/0><0x3e>

 

分区信息和块设备节点建立之后,各个分区的文件系统都不一样(ext ,fat等),如何mount时候如何区分呢?根据mount的参数(文件系统类型)

   DBR(也就是superblock(超级块)):

DBR(DOS BOOT RECORD,DOS引导记录),位于柱面0,磁头1,扇区1,即逻辑扇区0。DBR分为两部分:DOS引导程序和BPB(BIOS参数块)。其中DOS引导程序完成DOS系统文件(IO.SYS,MSDOS.SYS)的定位与装载,而BPB用来描述本DOS分区的磁盘信息,BPB位于DBR偏移0BH处,共13字节。它包含逻辑格式化时使用的参数,可供DOS计算磁盘上的文件分配表,目录区和数据区的起始地址,BPB之后三个字提供物理格式化(低格)时采用的一些参数。引导程序或设备驱动程序根据这些信息将磁盘逻辑地址(DOS扇区号)转换成物理地址(绝对扇区号)。

 

由此可见,DBR是DOS系统的专用名词,相当于类unix操作系统中的superblock(超级块)(ext2,ext3,ext4等类unix操作系统专有的文件系统格式)

故,如果我们不使用FAT等基于DOS的文件系统格式是不需要使用DBR的。在此处,是个干扰项。

superblock(超级块):包含对整个文件系统的描述,包含mount需要的信息。(对于那些MBR(与文件系统无关),DBR信息(文件系统类型有关));

vfs_kern_mount函数---->type->get_sb()

//例如对于ext2文件系统来说,get_sb()方法其实是ext2_get_sb();

//对yaffs2类型的文件系统,该函数是: yaffs2_read_super()

//对应FAT文件系统get_sb实际上是msdos_get_sb()。

 

step4:绑定建立各个分区的/dev/block/mmcblk0pxx节点:

int rescan_partitions(struct gendisk *disk, struct block_device*bdev)

{

…..

/* add partitions */根据获取到的分区表

for (p = 1; p < state->limit; p++) {

sector_tsize, from;

structpartition_meta_info *info = NULL;

….

part= add_partition(disk, p, from, size,

     state->parts[p].flags,

     &state->parts[p].info);

…...

}

…..

----

add_partition()

              {

///.建立节点:/dev/block/mmcblk0pxx

dname= dev_name(ddev);

printk("add_partition dname=%s partno=%d\n",dname,partno);

if(isdigit(dname[strlen(dname) - 1]))

dev_set_name(pdev, "%sp%d", dname,partno);设置分区名称:/dev/block/mmcblk0pxx

else

dev_set_name(pdev, "%s%d", dname,partno);设置disk节点:/dev/block/mmcblk0

 

device_initialize(pdev);

pdev->class= &block_class;

pdev->type= &part_type;

pdev->parent= ddev;

……...

    }

 

Step5:从应用层开始mount各个分区:

分区和block设备节点建立之后,谁来mount

init进程,通过解析init.rc:

onfs_property:ro.mount.fs=EXT4

    write /proc/bootprof"INIT:eMMC:Mount_START"

    exec /sbin/e2fsck -p /emmc@android

    # Mount /system rw first to give thefilesystem a chance to save a checkpoint

    #mount ext4 emmc@android /system waitcommit=1,data=journal,noauto_da_alloc

    mount ext4 /emmc@android /system waitcommit=1,noauto_da_alloc

 

    # RIL need to do this before the folder/system changed to read only

    chown radio system /system/etc/ril

    chmod 0770 /system/etc/ril

    chmod 0444 /system/etc/ril/oper.lis

    # Wifi thermal need to chmod before systemis changed to read only

    chown root system /system/etc/throttle.sh

    chmod 0750 /system/etc/throttle.sh

    mount ext4 /emmc@android /system noatime roremount wait

    exec /sbin/e2fsck -pfD /emmc@usrdata

    exec /sbin/tune2fs -O has_journal/emmc@usrdata

    exec /system/bin/ext4_resize

    mount ext4 /emmc@usrdata /data noatimenosuid nodev wait noauto_da_alloc,discard

    exec /sbin/e2fsck -p /emmc@cache

    exec /sbin/tune2fs -O has_journal/emmc@cache

    mount ext4 /emmc@cache /cache noatimenosuid nodev wait noauto_da_alloc,discard

    # mount cip partitions

    exec /sbin/e2fsck -p /emmc@custom

mountext4 /emmc@custom /custom

    write /proc/bootprof"INIT:eMMC:Mount_END"

 

 

Emmc FAT分区和外置SD  是由voldmount的。

 

 ---------------------------------------------------------/////-----------------------------------------

2)MTD设备:nand flash=:

1)MTD驱动层:

mediatek/platform/mt6577/kernel/drivers/nand/nand.c

mtd_device_register(mtd,g_exist_Partition, part_num);------>

------->add_mtd_partitions(structmtd_info *mtd)---->not->add(mtd);

2)FTL和NFTL(for nand flash)层

mtdblock.c已经注册register_mtd_blktrans();

staticstruct mtd_notifier blktrans_notifier = {

.add= blktrans_notify_add,

.remove= blktrans_notify_remove,

};

not->add(mtd);---blktrans_notify_add()--------》mtdblock_add_mtd()-----》mtdblock_add_mtd()

---->add_mtd_blktrans_dev()------->register_disk()通用层,略, 后面同以上sd卡

Nand flash就没有MBRebr相关的概念了

 

如何mount

只要ubi_attach_mtd然后mount即可。

1)首先init.rc

on fs_property:ro.mount.fs=UBIFS

    write/proc/bootprof "INIT:NAND:Mount_START"

    mount ubifsubi@system /system

 

    # Wifi thermal needto chmod before system is changed to read only

    chown root system/system/etc/throttle.sh

    chmod 0750/system/etc/throttle.sh

 

    mount ubifsubi@system /system ro remount

    mount ubifsubi@userdata /data nosuid nodev

    mount ubifsubi@cache /cache nosuid nodev

    write/proc/bootprof "INIT:NAND:Mount_END"

 

2其次:

Do_mount () 函数定义在builtins.c

{

elseif (!strncmp(source, "ubi@", 4)) {

       n = ubi_attach_mtd(source + 4);//绑定mtd分区关联到ubi

        if (n < 0) {

            return -1;

        }

 

        sprintf(tmp, "/dev/ubi%d_0",n);

 

        if (wait)

            wait_for_file(tmp,COMMAND_RETRY_TIMEOUT);

       if (mount(tmp, target, type, flags, options) <0) {//mount ubi分区

            ubi_detach_dev(n);

            return -1;

        }

        goto exit_success;

 

}

文件系统与存储:MBR/EBR类型分区建立

标签:文件系统   分区   mbr   ebr   

原文地址:http://blog.csdn.net/honour2sword/article/details/45247713

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!