如何从外壳识别 Android 设备的分区?

Posted

技术标签:

【中文标题】如何从外壳识别 Android 设备的分区?【英文标题】:How can I identify partitions of an Android device from the shell? 【发布时间】:2015-02-22 19:43:37 【问题描述】:

我正在尝试查找哪个分区用于什么,例如/boot/recovery/system,来自adb shell。虽然这对于当前挂载的分区来说是微不足道的(使用mountdf 命令,参见例如how to identify names of the partitions),但对于当前未挂载的分区(例如/recovery 在“用户模式”)。

有一个tutorial at XDA,但它不适用于我尝试过的任何设备:

cat /proc/mtd:这是空的或不存在的 cat /proc/emmc:这是空的或不存在的 cat /proc/dumchar_info:不存在(MTK/联发科) ls -al /dev/block/platform/*/by-name: 要么不存在,要么没有想要的详细信息 parted 刚刚在 /dev/block/mmcblk1 上生成了一个 Error: Can't have a partition outside the disk!(而只是缺少 /dev/block/mmcblk0 的“名称”列)。

所以我很茫然。我知道有像DiskInfo 这样的应用程序可以显示这些详细信息,因此必须存储在设备上的某个位置。但是,在我的情况下,修改设备(通过安装应用程序)不是一种选择。

所以基本上我的问题归结为:

此信息存储在 Android 设备的什么位置?

如果可能,首选通用方法。如果不是这样,几种方法 (if..elseif..fi) 的“试错”也可以。

对于背景:一个示例用法是“我只想检索/boot 分区”(通过dd 获取它的图像)。先抓取所有分区,然后再评估是不行的——太费时了,并且产生了太多数据;)——这已经描述了意图:编写一个小工具来检索特定的磁盘映像。

【问题讨论】:

您正在寻找哪些在/proc/mounts 中找不到的信息(大小、位置、安装) @jan 如上所述,每个分区“用于”什么。例如。派生自mount,或者,正如您所说的,/proc/mounts/dev/block/mmcblk1p21 持有system 分区。但是请注意,作为mount 命令本身,它只保存当前挂载的分区。但我还需要那些 当前未安装的(例如正常启动时的recovery)。大小是次要的利益。识别对我来说很重要。 我只需要ls -l /dev/block/platform/omap/omap_hsmmc.0/by-name 来获取指向实际设备的分区名称列表。 @jan 同意——如果可能的话(请参阅我的问题:/dev/block/platform/*/by-name: 在某些设备上不存在 @Andreyua 你已经看到 from the shell 部分,以及 修改设备(通过安装应用程序) ) 不是一个选项 限制? 【参考方案1】:

由于似乎没有“独特的方法”来实现这一点,我开始结合 allover 的想法,将它们加入一个脚本(或者更确切地说是一个“脚本库”)中,让它们按顺序检查(直到取得成功),并将其集成到我的名为 Adebar 的“设备文档工具”中。有兴趣的可以在lib/partitions.lib 文件中找到它。由于 Adebar 是开源的 (GPLv2),请随意复制和使用它 - 或分叉项目并改进它。

完整的解决方案在这里发布有点长(如前所述,你可以在 Github 上获取它),但由于 SE 政策是在帖子中至少包含一般部分,所以它的作用如下:

不同的来源提供不同的细节集,因此它首先尝试“最好的”——然后向下递归,直到至少找到一些东西。

/proc/dumchar_info 给出了最详细的信息,所以首先尝试。快乐的 MTK 用户会得到这个。 /proc/mtd 是第二好的来源。 /proc/emmc 应该几乎和之前的候选人一样多,但使用起来有点棘手 /dev/block/platform/*/by-name,与……交叉核对…… /proc/partitions/proc/mounts 交叉检查至少为我们提供了挂载的分区

所以我构建的脚本基本上按此顺序遍历源,一旦能够收集详细信息就停止(例如,如果找到/proc/dumchar_info,则无需解析所有其他脚本)。所有这些都放入单独的函数中,使用完全相同的结构返回数据,甚至可以合并所有结果。

如果有人能提出更好的解决方案,我当然总是愿意接受这个想法:)

【讨论】:

非常感谢!我使用 cat /proc/mtd 找到了分区名称和设备。 很高兴我能帮上忙,@VadimStupakov!不幸的是,每个设备似乎都以不同的方式处理它,所以我们不能使用任何独特的方法来匹配它们…… 您知道/dev/block/platform/*/by-name 是否适用于某些android 版本吗?我需要得到recoveryboot 的分区名称。在我在旧设备上尝试之前,我得到了它的工作.. @SuperThomasLab 根据我的经验,它是“特定于设备的”——但我无法确定。 @Izzy 好的,感谢您的快速回复。除了by-name 目录,你知道另一种获取recovery 分区的方法吗?我在您的答案中尝试了其他目录,但大多数不存在,不列出名称或仅显示当前安装的分区(=不恢复)。【参考方案2】:

您可以通过https://***.com/a/15639867/629118 获得Linux 上的mounted-partition 信息,但如果/dev/block/platform/**/by-name 没有,我认为Linux 内核不知道bootrecovery 分区。

所以你可以使用当前挂载的信息来猜测哪个分区是bootrecovery或/dev/block/*中没有挂载的其他东西。

事实上,fastboot 只发送你要刷入的分区名称。这意味着只有fastboot的引导加载程序知道这些信息,我猜。

https://github.com/android/platform_system_core/blob/8163104b3feb575a321b194a70ecb9873a70b29d/fastboot/fastboot_protocol.txt

【讨论】:

感谢 Kazuki – 但猜测 20 多个分区(当前连接的设备上的 26 个,mmcblk1p1mmcblk1p26)太容易出错,其中只有 3 或 4 个已安装(3 个在提到的设备)——尤其是“通过脚本自动猜测”。即使跳过所有具有 2048 个或更少块的分区,该设备上也会留下 10 个分区,减去已安装的 3 个分区,可以猜测出 7 个分区。 fastboot 可以自行判断是信息必须可以自动获取的另一个证明(除非它被硬编码到设备上的对应部分中)。 fastboot 是 bootloader 的一部分,它与 Linux 系统是分开的,所以我认为您无法通过与 Linux 内核上的 adbd 通信的 adb shell 获取信息。 这是一个有效的观点。我会说 fastboot 是分开看的;在快速启动模式下启动时,“正常系统”根本不会“启动”。所以从我上一条评论中去掉那个“证据”;但由于应用程序可以找到详细信息(请参阅我的问题中的示例),它仍然必须以某种方式获得。 DiskInfo 在每台设备上总是正确的?如果是这样,您可以使用 strace 或具有 root 权限的东西来检查应用程序为获取信息所做的工作。但我对此表示怀疑。另见all-things-android.com/content/review-android-partition-layout 我不能“在每台设备上”都测试它——这正是我被告知的。我昨天已经尝试过那个给定的链接。除了“Cloudflare DDos 检查”之外,别无他法,永远不要进入真实页面。啊,刚刚通过谷歌缓存得到它:基本上我已经尝试过了。除了blkid,不幸的是,它在设备上不可用:(不过感谢您的指点!

以上是关于如何从外壳识别 Android 设备的分区?的主要内容,如果未能解决你的问题,请参考以下文章

如何识别 linux 块设备的请求队列

如何查看Android设备上的分区信息

如何从 Android Studio 手动重启 ADB

如何获取Android设备唯一识别码

linux之磁盘管理,查看识别设备,磁盘的挂载卸载分区配额管理,文件系统

Android - 如何从多个设备检测同一用户?