Linux文件系统以及性能分析

1 Windows File System
1.1 Windows分区知识
因为保存主分区信息的MBR(Master Boot Record)只能容纳4个分区信息,也就是说只能有4个主分区。如果你想要更多的分区,只能将其中的一个主分区再划分,再划分出来的分区叫做逻辑分区,被划分的主分区又叫扩展分区,逻辑分区信息是保存在EBR(Extended Boot Record)里的。Linux系统中规定了主分区号为sda1-sda4或者hda1-hda4,而逻辑分区只能从sda5开始。

Q:U盘被识别为/dev/sda4,而不是sda1?
A:因为U盘的这个分区写在分区表(MBR DPT,Disk Partition Table)的第四项所以是sda4(DPT每个entry的第一个字节为引导标志,0x80表示活动分区,0x00表示非活动分区),可以用命令重新写到第一项。

sudo sfdisk -d /dev/sda > sda_table
gedit sda_table
sudo sfdisk /dev/sda < sda_table
或者
dd if=/dev/sda of=./mbr.bin bs=512 count=1

1.2 MBR
MBR分为GRUB.MBR和DOS.MBR。

由于硬盘上扇区从偏移0到偏移62属于同一个磁道0,虽然DOS.MBR仅占用一个扇区,但是需要将DOS.MBR后面的偏移1到偏移62保留,所以磁盘上第一个分区的第一个扇区是从偏移63开始的。
USB-ZIP和USB-FDD会将U盘的第一个扇区格式化成DOS.PBR而不是DOS.MBR。
USB-FDD和USB-ZIP的来历:软盘的容量小,没有分区结构,所以软盘是没有MBR的,整个软盘只有一个分区,第一个扇区就是PBR。

MBR实际上也是一个bootloader,可以使用如下命令获得MBR的内容
dd if=/dev/sda of=./mbr.bin bs=512 count=1

MBR:扇区内偏移地址0 ~ 0x1BD
DPT:DOS Partition Table,扇区内偏移地址0x1BE~ 0x1FD,其中又分为4个分区表:

第一个分区表:0x1BE ~ 0x1CD
第二个分区表:0x1CE ~ 0x1DD
第三个分区表:0x1DE ~ 0x1ED
第四个分区表:0x1EE ~ 0x1FD

DPT阐述
字节偏移  说明
0       引导标志。若值为80H表示活动分区,若值为00H表示非活动分区。
1-3   本分区的起始磁头号、扇区号、柱面号。其中:磁头号--第1字节;扇区号--第2字节的低6位;柱面号—为第2字节高2位+第3字节8位
4       分区类型符:
00H——表示该分区未用(即没有指定);
01h——FAT12基本分区
04H——FAT16基本分区
06H——big FAT16基本分区;
0BH——FAT32基本分区;
05H——扩展分区;
07H——NTFS分区;
0FH——(LBA模式)扩展分区(83H为Linux分区等)
5-7   本分区的结束磁头号、扇区号、柱面号。其中:
磁头号——第1字节;
扇区号——第2字节的低6位;
柱面号——第2字节的高2位+第3字节
8-11          分区起始扇区数,指分区相对于记录该分区的分区表的扇区位置之差 (该分区表:LBA = 0x0)
12-15        本分区的总扇区数

1.3 PBR
偏移量 字节数 含义
00--02H 3  跳转到引导代码
03--0AH 8  厂商标识和DOS版本
0B--0CH 2  BPB参数信息,每个扇区的字节数
0DH 1  每个分配簇的扇区数(2的整数倍)
0E--0FH 2  保留扇区数
10H 1  FAT个数
11--12H 2  根目录登记项数(所允许的最大数值)
13--14H 2  磁盘扇区总数
15H 1  磁介质类型说明
16--17H 2  每个FAT表所占的扇区数
18--19H 2  每个磁道(柱面)的扇区数
1A--1BH 2  磁头的个数
1C--1FH 4  当前DOS分区前面的隐含扇区数
27--2AH 4  FAT16格式磁盘系列号
2B--35H 10  FAT16卷标名
36--3AH 5  FAT16磁盘格式标志

1.4 python解析MBR和PBR
1.4.1 parse_mbr.py
import hashlib
import sys
import os

# dd if=/dev/block/sda of=/data/mbr.hex bs=512 count=1

def print_usage():
    print("Usage:\n" + sys.argv[0] + " MBR file\n")

def parse_mbr():
    f = open(sys.argv[1], 'r')

    # PART 1
    print("PART 1")
    offset = 0x1be
    f.seek(offset)
    str_data = f.read(16)
    print(" ".join(hex(ord(n)) for n in str_data))
    print("boot: %r" % str_data[0])
    print("FS Type: %r" % str_data[4])

    # PART 2
    print("\nPART 2")
    offset = 0x1ce
    f.seek(offset)
    str_data = f.read(16)
    print(" ".join(hex(ord(n)) for n in str_data))
    print("boot: %r" % str_data[0])
    print("FS Type: %r" % str_data[4])

    # PART 3
    print("\nPART 3")
    offset = 0x1de
    f.seek(offset)
    str_data = f.read(16)
    print(" ".join(hex(ord(n)) for n in str_data))
    print("boot: %r" % str_data[0])
    print("FS Type: %r" % str_data[4])

    # PART 4
    print "\nPART 4"
    offset = 0x1ee
    f.seek(offset)
    str_data = f.read(16)
    print(" ".join(hex(ord(n)) for n in str_data))
    print("boot: %r" % str_data[0])
    print("FS Type: %r" % str_data[4])

f.close()

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print_usage()
        exit()
    parse_mbr()

1.4.2 parse_pbr.py
import hashlib
import sys
import os

# dd if=/dev/block/sda1 of=/data/pbr.hex bs=512 count=1

def print_usage():
    print("Usage:\n" + sys.argv[0] + " PBR file\n")

# http://elm-chan.org/docs/fat_e.html
def parse_pbr():
    f = open(sys.argv[1], 'rb')

    offset = 0
    f.seek(offset)
    str_data = f.read(3)
    print("Boot Code: " +
        " ".join(hex(ord(n)) for n in str_data))

    str_data = f.read(8)
    print("DOS Ver: " + str_data)

    str_data = f.read(2)
    print("Bytes per Sector: " +
        " ".join(hex(ord(n)) for n in str_data))

    str_data = f.read(1)
    print("Sectors per Cluster: " +
        " ".join(hex(ord(n)) for n in str_data))

    str_data = f.read(2)
    print("Num of Reserved Sectors: " +
        " ".join(hex(ord(n)) for n in str_data))

    str_data = f.read(1)
    print("Num of FAT: " +
        " ".join(hex(ord(n)) for n in str_data))

    str_data = f.read(2)
    print("FAT12/16 - Num of Root Dirs: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 0x13
    f.seek(offset)
    str_data = f.read(2)
    print("FAT12/16 - Num of Sectors: " +
        " ".join(hex(ord(n)) for n in str_data))

    str_data = f.read(1)
    print("Media Type: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 0x16
    f.seek(offset)
    str_data = f.read(2)
    print("FAT12/16 - Sectors per FAT: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 0x1C
    f.seek(offset)
    str_data = f.read(4)
    print("Hide Sectors before EBR: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 0x20
    f.seek(offset)
    str_data = f.read(4)
    print("Num of Huge Sectors: " +
        " ".join(hex(ord(n)) for n in str_data))

    print("\n")
    offset = 39
    f.seek(offset)
    str_data = f.read(4)
    print("FAT12/16 - Volume ID: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 43
    f.seek(offset)
    str_data = f.read(11)
    print("FAT12/16 - Label: " + str_data)

    offset = 54
    f.seek(offset)
    str_data = f.read(8)
    print("FAT12/16 - FS Type: " + str_data)

    print "\n"
    offset = 36
    f.seek(offset)
    str_data = f.read(4)
    print("FAT32 - Sectors per FAT: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 44
    f.seek(offset)
    str_data = f.read(4)
    print("FAT32 - Root Cluster: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 0x43
    f.seek(offset)
    str_data = f.read(4)
    print("FAT32 - Volume ID: " +
        " ".join(hex(ord(n)) for n in str_data))

    offset = 0x47
    f.seek(offset)
    str_data = f.read(11)
    print("FAT32 - Label: " +
        " ".join(hex(ord(n)) for n in str_data) +
        ", " + str_data)

    offset = 0x52
    f.seek(offset)
    str_data = f.read(8)
    print("FAT32 - FS Type: " +
        " ".join(hex(ord(n)) for n in str_data) +
        ", " + str_data)

    f.close()

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print_usage()
        exit()
    parse_pbr()

1.5 FAT32分配单元大小
FAT32分配单元大小 - 簇的大小,譬如16KB,命令chkdsk f:\

2 Linux文件系统
2.1 GRUB简介
GRUB镜像组成:
- GRUB.MBR(boot.img)
- 硬盘扇区offset 1 到offset 62放置GRUB的core.img
- /boot分区的boot/grub/grub.cfg

2.2 block设备性能分析工具
CONFIG_BLK_DEV_IO_TRACE
@ external/e2fsprogs/debugfs
@ external/blktrace
需要加下面的声明在blkparse.c,否则编译出错。
extern int strverscmp (const char *s1, const char *s2);

blktrace -d /dev/block/sda -o - | blkparse -i - -o /data/blk.parsed

根据扇区offset找到具体的文件:
ls -l /dev/block
debugfs -R "stats" /dev/block/sda1 |grep "Block size"

BLKNO=SECTOR_OFFSET/8
debugfs -R "icheck $BLKNO" /dev/block/sda1

GOT THE INODE NUMBER FROM THE LAST CMD: 9
debugfs -R "ncheck 9" /dev/block/sda1

2.3 iodump
iodump可以显示fullpath。

2.4 Linux command
fdisk -l /dev/block/sda
fdisk -l mbr.img
gdisk -l gpt.img

2.5 EXT4 Encryption
CE: Credential Encrypted
DE: Device Encrypted
ENOKEY: Required key not available
FBE:File-Based Encryption,加密的仅仅是文件内容和文件名,其他的信息比如文件大小,权限等都没有加密,这些内容就是filesystem metadata
Metadata分区:加密文件大小,权限等除了文件内容和文件名之外的文件信息,/metadata/vold/metadata_encryption/key

github ext4-crypt
add_key() - e4crypt add_key
keyctl_search()
keyctl_unlink()

3 Abbreviations
DPT: Disk Partition Table
EBR: Extended Boot Record
MBR: Master Boot Record
PBR: Partition Boot Record

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值