Chinaunix首页 | 论坛 | 博客
  • 博客访问: 855881
  • 博文数量: 290
  • 博客积分: 511
  • 博客等级: 下士
  • 技术积分: 1590
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-29 13:14
文章分类

全部博文(290)

文章存档

2018年(28)

2017年(19)

2016年(8)

2015年(1)

2014年(14)

2013年(12)

2012年(22)

2011年(186)

分类:

2011-12-17 14:55:06

Andrew Huang 转载请注明作者及网址

  一般的嵌入式Linux开发人员是要清晰区分不同器材的作用和名称的。比如系统,内核所有保存在Nand Flash之上,断电后仍然存在,而运行后程序是装入SDRAM或Mobile DDR之类的内存设备运行。
 但一般用户不大明白这几个芯片的区别,一般是就用ROM来指Nand Flash,RAM来指SDRAM之类设备。虽然在嵌入式编程,是专门有称作ROM的器材,比如EEPROM。这里就是大家约定俗说法吧。因此这里的Android ROM实际就是指烧录Nand Flash的各种二进制文件。
 
 另外,卖数码产品的喜欢把Nand Flash称为内存,SD卡称为外存,所以交流也只好这样了。
  
 
从分区表看,
 <>
  

  <>

一.手机的分区说明

我的HTC G8信息是 ,注意这里是Android的LINUX内核能看到分区,并不表示Flash上的所有分区,我的理解Hboot和radio分区在toolbox就看不到。
    
  1. E:\huisen\android\sdk\tools>adb shell cat /proc/mtd
  2. dev: size erasesize name
  3. mtd0: 000a0000 00020000 "misc"
  4. mtd1: 00420000 00020000 "recovery"
  5. mtd2: 002c0000 00020000 "boot"
  6. mtd3: 0fa00000 00020000 "system"
  7. mtd4: 02800000 00020000 "cache"
  8. mtd5: 0af20000 00020000 "userdata"
MISC分区   
其中misc分区信息第一篇文章有解释:
     保存设备配置信息:CID (Carrier or Region ID),USB和其它硬件设备配置信息,大约20K的样子。
  引自 
http://blog.chinaunix.net/space.php?uid=20543672&do=blog&id=94411
  可能结构是
         
0x00  CID
0x10  enter_bootloader
0x20  cold boot (DeviceWarmBoot)
0x30  goupdateloader
0x40  (NBH)
0x50  CE Serial InUse\0
0x60  Debug Cable Ena\0
0x70  CE USB InUse\0
0x80  (IMG)
0x90  ClearAutoImage \0
0xa0  *.**.***.*\0(HBoot version)

  recovery分区  
  recovery 分区即恢复分区,在正常分区被破坏后,仍可以进入这一分区进行备份和恢复.我的理解是这个分区保存一个简单的OS或底层软件,在Android的内核被破坏后可以用bootloader从这个分区引导进行操作。

boot 分区
  一般的嵌入式Linux的设备中.bootloader,内核,根文件系统被分为三个不同分区。在Android做得比较复杂,从这个手机分区和来看,这里boot分区是把内核和ramdisk file的根文件系统打包在一起了,是编译生成boot.img来烧录的。它有如下格式。
   
  1. +-----------------+
  2. | boot header     | 1 page
  3. +-----------------+
  4. | kernel          | n pages
  5. +-----------------+
  6. | ramdisk         | m pages
  7. +-----------------+
  8. | second stage    | o pages
  9. +-----------------+
  10. n = (kernel_size + page_size - 1) / page_size
  11. m = (ramdisk_size + page_size - 1) / page_size
  12. o = (second_size + page_size - 1) / page_size
  13. 0. all entities are page_size aligned in flash
  14. 1. kernel and ramdisk are required (size != 0)
  15. 2. second is optional (second_size == 0 -> no second)
这里表示boot分区有四个部分,其中前三部分是必须的,而第四部分 second stage 可选。 每部分的大小是一个flash page的倍数,不足一页的需要加入空格字符补齐成一页。

其中bootl header是一些特定的数据结构。每种手机有细微的差别。但是它是有一个统一个数据结构
参见 bootloader/legacy/include/boot/bootimg.h 中 boot_img_hdr

  1. typedef struct boot_img_hdr boot_img_hdr;

  2. #define BOOT_MAGIC "ANDROID!"
  3. #define BOOT_MAGIC_SIZE 8
  4. #define BOOT_NAME_SIZE 16
  5. #define BOOT_ARGS_SIZE 512

  6. struct boot_img_hdr
  7. {
  8.     unsigned char magic[BOOT_MAGIC_SIZE];            /*幻数,一般固定为 ANDROID! */

  9.     unsigned kernel_size; /* size in bytes */        /*内核长度                */
  10.     unsigned kernel_addr; /* physical load addr */   /*内核装入地址             */ 

  11.     unsigned ramdisk_size; /* size in bytes */       /*ramdisk 长度            */
  12.     unsigned ramdisk_addr; /* physical load addr */  /* ramdisk 装入地址        */
  13.  
  14.     unsigned second_size; /* size in bytes */        /* second stage 长度      */
  15.     unsigned second_addr; /* physical load addr */   /* second staget 装入地址  */

  16.     unsigned tags_addr; /* physical addr for kernel tags */ /*内核tags 即内核参数 物理地址 ? */
  17.     unsigned page_size; /* flash page size we assume */   /* flash页尺寸,取决于flash型号 */
  18.     unsigned unused[2]; /* future expansion: should be 0 */ /* 保留未用字段 */

  19.     unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */  /*产品名称 */
  20.     
  21.     unsigned char cmdline[BOOT_ARGS_SIZE];                   /* Linux 内核引导参数,*/

  22.     unsigned id[8]; /* timestamp / checksum / sha1 / etc */   /*检验值   */
  23. };
 
这里的内核tags,应该就是指内核命令行参数,在头文件里有如下注释注明了,bootloader在引导LINUX 内核时,将会把寄存器r2保存tags addr,而在ARM-LINUX定义里 r1是机器码,而r2就是引志命令行参数的偏移量,

** 4. prepare tags at tag_addr. kernel_args[] is ** appended to the kernel commandline in the tags. ** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
而kernel 和ramdisk则是LINUX标准的zImage和zip格式,这里略掉其说明
文件系统分区. Linux必须有一个根文件系统分区,可以为多种格式,这里用的是可读的ramdisk 格式,它启动分隔一部分内存,
挂载到/目录下。 然后再用分三个不同权限分区来装载不同子目录.这里二个子目录是 /system ,/userdata 并且内容是完全只读的它将必须用root用户 这种设计结构的出发点是这样考虑,内核和根文件系统的由手机制造商控制,不让用户修改,而且system的分区保存重要的系统命令和框架程序。由官方来升级,对于用户是只读的。而且userdata目录才是用户自行管理的,比如下载的应用。 而启动时最重要的root用户并未对用户公开,应用程序都是用普通用户的如 app_xx这样的帐号来运行。这样可以有效保护/system的程序。 但是第三方的自制rom往往要修改/system的内容,因此刷机时要通过破解方法来取得root用户权限。
system 分区 这里是挂载到/system目录下的分区,是一个yaffs2的文件系统,用普通的adb 命令是无法操作这个目录的。这里有 /system/bin 和 /system/sbin 保存很多系统命令。它是由编译出来的system.img来烧入。
userdata 分区
它也是一个yaffs2文件系统,它将挂载到 /data 目录下, 它是由编译出来的userdata.img来烧入。cache 分区 它也是一个yaffs2文件系统,它将挂载到 /cache 目录下,看一般解释,这里主要用升级的缓存,内容
由运行而定.
  1. E:\huisen\android\sdk\tools>adb shell cat /proc/mounts
  2. rootfs / rootfs ro,relatime 0 0 #根文件系统的格式,只读
  3. tmpfs /dev tmpfs rw,relatime,mode=755 0 0
  4. devpts /dev/pts devpts rw,relatime,mode=600 0 0
  5. proc /proc proc rw,relatime 0 0
  6. sysfs /sys sysfs rw,relatime 0 0
  7. none /acct cgroup rw,relatime,cpuacct 0 0
  8. tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0
  9. none /dev/cpuctl cgroup rw,relatime,cpu 0 0
  10. /dev/block/mtdblock3 /system yaffs2 ro,relatime 0 0 #system分区,只读
  11. /dev/block/mtdblock5 /data yaffs2 rw,nosuid,nodev,relatime 0 0 #data分区,可读写
  12. /dev/block/mtdblock4 /cache yaffs2 rw,nosuid,nodev,relatime 0 0 #cache分区,可读写

其它隐藏分区:
  HBOOT 这里没有看,保存的bootloader HBOOT,从源码看不是u-boot的变种。
 
  Radio 分区保存是基带芯片的固件代码,Linux不认识其格式,在手机启动时装入特定内存中用于驱动芯片。所有与电信网络交互就是靠它了,一般往往用专用开发环境来开发。

  这里启动画面,如splash分区也没看到。

  SD卡分区
    一般默认的是挂载在/sdcard目录,从我的机器看,好象没有挂上。
 
  
E:\huisen\android\sdk\tools>adb shell ls -l /sdcard
lrwxrwxrwx root     root              2011-08-23 14:22 sdcard -> /mnt/sdcard 

  SD卡扩展分区
    它的目录名是 /sd-ext ,它不是一个标准的Android分区,是运行APP2D软件扩展出来分区。目的是为了多扩展一个安装程序空间,这个对于Flash空间(或者说ROM空间)不够,又喜欢安装软件的人是有用应用。

二.各分区详细分析

  各个分区的内容,可以用cat命令直接导出,用一般的二进制的软件来分析,我一般用WinHex,并且自己写了几个模板。

  导出分区内容,如果用adb 导出,必须有root权限,
阅读(4779) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~