先閱讀:https://grasslab.github.io/osdi/en/labs/lab8.html#background
Parse MBR 來取得各個 partition 的資訊,Parse FAT32 Boot Sector 取得 metadata
1
2
3
4
5
6
7
8
9
10
| struct mbr_partition {
unsigned char status_flag; //0x0
unsigned char partition_begin_head; //0x1
unsigned short partition_begin_sector; //0x2-0x3
unsigned char partition_type; //0x4
unsigned char partition_end_head; //0x5
unsigned short partition_end_sector; //0x6-0x7
unsigned int starting_sector; //0x8-0xB
unsigned int number_of_sector; //0xC-0xF
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| // Ref: https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Bootsector
struct fat32_boot_sector {
char jump[3]; // 0x0
char oem[8]; // 0x3
// BIOS Parameter Block
uint16_t bytes_per_logical_sector; // 0xB-0xC
uint8_t logical_sector_per_cluster; // 0xD
uint16_t n_reserved_sectors; // 0xE-0xF
uint8_t n_file_alloc_tabs; // 0x10
uint16_t n_max_root_dir_entries_16; // 0x11-0x12
uint16_t n_logical_sectors_16; // 0x13-0x14
uint8_t media_descriptor; // 0x15
uint16_t logical_sector_per_fat_16; // 0x16-0x17
// DOS3.31 BPB
uint16_t physical_sector_per_track; // 0x18-0x19
uint16_t n_heads; // 0x1A-0x1B
uint32_t n_hidden_sectors; // 0x1C-0x1F
uint32_t n_sectors_32; // 0x20-0x23
// FAT32 Extended BIOS Parameter Block
uint32_t n_sectors_per_fat_32; // 0x24-0x27
uint16_t mirror_flag; // 0x28-0x29
uint16_t version; // 0x2A-0x2B
uint32_t root_dir_start_cluster_num; // 0x2C-0x2F
uint16_t fs_info_sector_num; // 0x30-0x31
uint16_t boot_sector_bak_first_sector_num; // 0x32-0x33
uint32_t reserved[3]; // 0x34-0x3F
uint8_t physical_drive_num; // 0x40
uint8_t unused; // 0x41
uint8_t extended_boot_signature; // 0x42
uint32_t volume_id; // 0x43-0x46
uint8_t volume_label[11]; // 0x47-0x51
uint8_t fat_system_type[8]; // 0x52-0x59
} __attribute__((packed));
|
1
2
3
4
5
6
7
8
| struct fat32_metadata {
uint32_t fat_region_blk_idx;
uint32_t n_fat;
uint32_t sector_per_fat;
uint32_t data_region_blk_idx;
uint32_t first_cluster;
uint8_t sector_per_cluster;
};
|
1
| struct fat32_metadata fat32_metadata;
|
src/main.c
1
2
3
4
| void boot_init() {
...
sd_mount();
}
|
1
2
3
4
5
| struct fat32_internal {
uint32_t first_cluster;
uint32_t dirent_cluster;
uint32_t size;
};
|
掛在 sdcard 在 /sdp1 下,並同時 parse FAT32 的 metadata 並儲存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| // read MBR and mount partition
int sd_mount() {
// read MBR
char buf[BLOCK_SIZE];
readblock(0, buf);
// check boot signature
if (buf[510] != 0x55 || buf[511] != 0xAA) {
return -1;
}
// parse first partition only
struct mbr_partition p1;
memcpy(&p1, buf + 446, sizeof(struct mbr_partition));
// mount partition
readblock(p1.starting_sector, buf);
// route each filesystem
if (p1.partition_type == 0x0b) { // FAT32 with CHS addressing
// create FAT32's root directory object
char mountpoint[8] = "/sdp1";
vfs_mkdir(mountpoint);
vfs_mount("sdcard", mountpoint, "fat32");
// store metadata
struct fat32_boot_sector* boot_sector = (struct fat32_boot_sector*)buf;
fat32_metadata.data_region_blk_idx = p1.starting_sector +
boot_sector->n_sectors_per_fat_32 * boot_sector->n_file_alloc_tabs +
boot_sector->n_reserved_sectors;
fat32_metadata.fat_region_blk_idx = p1.starting_sector + boot_sector->n_reserved_sectors;
fat32_metadata.n_fat = boot_sector->n_file_alloc_tabs;
fat32_metadata.sector_per_fat = boot_sector->n_sectors_per_fat_32;
fat32_metadata.first_cluster = boot_sector->root_dir_start_cluster_num;
fat32_metadata.sector_per_cluster = boot_sector->logical_sector_per_cluster;
// get mount node
struct vnode* mount_dir;
char path_remain[128];
traversal(mountpoint, &mount_dir, path_remain);
// fill internal data of mount node
struct fat32_internal* root_internal = (struct fat32_internal*)kmalloc(sizeof(struct fat32_internal));
root_internal->first_cluster = boot_sector->root_dir_start_cluster_num;
mount_dir->internal = root_internal;
}
return 0;
}
|
跟 tmpfs 長很像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| int fat32_setup_mount(struct filesystem* fs, struct mount* mount) {
mount->fs = fs;
mount->root = fat32_create_dentry(NULL, "/", DIRECTORY);
return 0;
}
struct dentry* fat32_create_dentry(struct dentry* parent, const char* name, int type) {
struct dentry* dentry = (struct dentry*)kmalloc(sizeof(struct dentry));
strcpy(dentry->name, name);
dentry->parent = parent;
list_head_init(&dentry->list);
list_head_init(&dentry->childs);
if (parent != NULL) {
list_add(&dentry->list, &parent->childs);
}
dentry->vnode = fat32_create_vnode(dentry);
dentry->mountpoint = NULL;
dentry->type = type;
return dentry;
}
struct vnode* fat32_create_vnode(struct dentry* dentry) {
struct vnode* vnode = (struct vnode*)kmalloc(sizeof(struct vnode));
vnode->dentry = dentry;
vnode->f_ops = fat32_f_ops;
vnode->v_ops = fat32_v_ops;
return vnode;
}
|