更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
disk.c 文件参考

浏览源代码.

类型定义

typedef VOID *(* StorageHookFunction) (VOID *)
 

函数

static UINT32 OsReHookFuncAddDiskRef (StorageHookFunction handler, VOID *param) __attribute__((weakref("osReHookFuncAdd")))
 
static UINT32 OsReHookFuncDelDiskRef (StorageHookFunction handler) __attribute__((weakref("osReHookFuncDel")))
 
UINT32 GetFatBlockNums (VOID)
 
VOID SetFatBlockNums (UINT32 blockNums)
 
UINT32 GetFatSectorsPerBlock (VOID)
 
VOID SetFatSectorsPerBlock (UINT32 sectorsPerBlock)
 设置FAR每块扇区数 更多...
 
INT32 los_alloc_diskid_byname (const CHAR *diskName)
 通过名称分配磁盘ID 更多...
 
INT32 los_get_diskid_byname (const CHAR *diskName)
 通过名称查询使用中(STAT_INUSED)磁盘ID 更多...
 
los_disklos_get_mmcdisk_bytype (UINT8 type)
 
VOID OsSetUsbStatus (UINT32 diskID)
 Set usb mode. 更多...
 
VOID OsClearUsbStatus (UINT32 diskID)
 Set usb mode. 更多...
 
static BOOL GetDiskUsbStatus (UINT32 diskID)
 
los_diskget_disk (INT32 id)
 Find disk driver. 更多...
 
los_partget_part (INT32 id)
 获取某个分区的描述符 更多...
 
static UINT64 GetFirstPartStart (const los_part *part)
 
static VOID DiskPartAddToDisk (los_disk *disk, los_part *part)
 磁盘增加一个分区 更多...
 
static VOID DiskPartDelFromDisk (los_disk *disk, los_part *part)
 从磁盘上删除分区 更多...
 
static los_partDiskPartAllocate (struct Vnode *dev, UINT64 start, UINT64 count)
 分配一个磁盘分区,必须要有索引节点才给分配. 更多...
 
static VOID DiskPartRelease (los_part *part)
 清空分区信息 更多...
 
static INT32 DiskAddPart (los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart)
 
static INT32 DiskDivide (los_disk *disk, struct disk_divide_info *info)
 磁盘分区 更多...
 
static CHAR GPTPartitionTypeRecognition (const CHAR *parBuf)
 GPT分区类型识别 更多...
 
static INT32 DiskPartitionMemZalloc (size_t boundary, size_t size, CHAR **gptBuf, CHAR **partitionBuf)
 磁盘分区内存申请 更多...
 
static INT32 GPTInfoGet (struct Vnode *blkDrv, CHAR *gptBuf)
 获取GPT信息,是GPT还是MBR取决于磁盘上放的内容 更多...
 
static INT32 OsGPTPartitionRecognitionSub (struct disk_divide_info *info, const CHAR *partitionBuf, UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd)
 解析GPT分区内容 更多...
 
static INT32 OsGPTPartitionRecognition (struct Vnode *blkDrv, struct disk_divide_info *info, const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount)
 识别GPT分区内容 更多...
 
static INT32 DiskGPTPartitionRecognition (struct Vnode *blkDrv, struct disk_divide_info *info)
 
static INT32 OsMBRInfoGet (struct Vnode *blkDrv, CHAR *mbrBuf)
 获取MBR信息,即特殊扇区信息,在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。 更多...
 
static INT32 OsEBRInfoGet (struct Vnode *blkDrv, const struct disk_divide_info *info, CHAR *ebrBuf, const CHAR *mbrBuf)
 
static INT32 OsPrimaryPartitionRecognition (const CHAR *mbrBuf, struct disk_divide_info *info, INT32 *extendedPos, INT32 *mbrCount)
 识别主分区 更多...
 
static INT32 OsLogicalPartitionRecognition (struct Vnode *blkDrv, struct disk_divide_info *info, UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
 识别扩展分区 更多...
 
static INT32 DiskPartitionRecognition (struct Vnode *blkDrv, struct disk_divide_info *info)
 识别磁盘分区信息 https://blog.csdn.net/Hilavergil/article/details/79270379 更多...
 
INT32 DiskPartitionRegister (los_disk *disk)
 磁盘分区注册 更多...
 
static INT32 disk_read_directly (los_disk *disk, VOID *buf, UINT64 sector, UINT32 count)
 
static INT32 disk_write_directly (los_disk *disk, const VOID *buf, UINT64 sector, UINT32 count)
 
INT32 los_disk_read (INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
 读磁盘数据 更多...
 
INT32 los_disk_write (INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count)
 将buf内容写到指定扇区, 更多...
 
INT32 los_disk_ioctl (INT32 drvID, INT32 cmd, VOID *buf)
 Get information of disk driver. 更多...
 
INT32 los_part_read (INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
 读分区上扇区内容 更多...
 
INT32 los_part_write (INT32 pt, const VOID *buf, UINT64 sector, UINT32 count)
 将数据写入指定分区的指定扇区 更多...
 
INT32 los_part_ioctl (INT32 pt, INT32 cmd, VOID *buf)
 Get information of chosen partition. 更多...
 
INT32 los_disk_cache_clear (INT32 drvID)
 Clear the bcache data 更多...
 
static VOID DiskCacheThreadInit (UINT32 diskID, OsBcache *bc)
 
static OsBcacheDiskCacheInit (UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver)
 
static VOID DiskCacheDeinit (los_disk *disk)
 
static VOID DiskStructInit (const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver, los_disk *disk)
 磁盘结构体初始化,初始化 los_disk 结构体 更多...
 
static INT32 DiskDivideAndPartitionRegister (struct disk_divide_info *info, los_disk *disk)
 磁盘分区和注册分区 更多...
 
static INT32 DiskDeinit (los_disk *disk)
 磁盘反初始化 更多...
 
static UINT32 OsDiskInitSub (const CHAR *diskName, INT32 diskID, los_disk *disk, struct geometry *diskInfo, struct Vnode *blkDriver)
 磁盘初始化 更多...
 
INT32 los_disk_init (const CHAR *diskName, const struct block_operations *bops, VOID *priv, INT32 diskID, VOID *info)
 磁盘初始化 更多...
 
INT32 los_disk_deinit (INT32 diskID)
 磁盘反初始化 更多...
 
INT32 los_disk_sync (INT32 drvID)
 磁盘同步,同步指的是缓存同步 更多...
 
INT32 los_disk_set_bcache (INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum)
 设置磁盘块缓存 更多...
 
static los_partOsPartFind (los_disk *disk, const struct Vnode *blkDriver)
 通过索引节点从磁盘中找分区信息 更多...
 
los_partlos_part_find (struct Vnode *blkDriver)
 通过索引节点找到分区信息 更多...
 
INT32 los_part_access (const CHAR *dev, mode_t mode)
 访问分区 更多...
 
INT32 SetDiskPartName (los_part *part, const CHAR *src)
 设置分区名称 更多...
 
INT32 add_mmc_partition (struct disk_divide_info *info, size_t sectorStart, size_t sectorCount)
 添加 MMC分区
MMC, 是一种闪存卡(Flash Memory Card)标准,它定义了 MMC 的架构以及访问 Flash Memory 的接口和协议。
而eMMC 则是对 MMC 的一个拓展,以满足更高标准的性能、成本、体积、稳定、易用等的需求。 更多...
 
VOID show_part (los_part *part)
 OHOS #partinfo /dev/mmcblk0p0 命令输出信息 更多...
 
ssize_t StorageBlockMmcErase (uint32_t blockId, size_t secStart, size_t secNr)
 通过磁盘ID 擦除磁盘信息 更多...
 
INT32 EraseDiskByID (UINT32 diskID, size_t startSector, UINT32 sectors)
 

变量

los_disk g_sysDisk [SYS_MAX_DISK]
 支持挂载的磁盘总数量 5个 更多...
 
los_part g_sysPart [SYS_MAX_PART]
 支持磁盘的分区总数量 5*16,每个磁盘最大分16个区 更多...
 
UINT32 g_uwFatSectorsPerBlock = CONFIG_FS_FAT_SECTOR_PER_BLOCK
 每块支持扇区数 默认64个扇区 更多...
 
UINT32 g_uwFatBlockNums = CONFIG_FS_FAT_BLOCK_NUMS
 块数量 默认28 更多...
 
spinlock_t g_diskSpinlock
 磁盘自锁锁 更多...
 
spinlock_t g_diskFatBlockSpinlock
 磁盘Fat块自旋锁 更多...
 
UINT32 g_usbMode = 0
 

详细描述

GPT和MBR是做什么的?
    在使用磁盘驱动器之前,必须对其进行分区。。MBR(主引导记录)和GPT(GUID分区表)是在驱动器上存储分区信息的两种不同方法。
    这些信息包括分区在物理磁盘上的开始和结束位置,因此您的操作系统知道哪些扇区属于每个分区,哪些分区是可引导的。
    这就是为什么在驱动器上创建分区之前必须选择MBR或GPT的原因。

    MBR于1983年首次在IBMPCDOS2.0中引入。它被称为主引导记录,因为MBR是一个特殊的引导扇区,位于驱动器的开头。
    此扇区包含已安装操作系统的引导加载程序和有关驱动器逻辑分区的信息。引导加载程序是一小部分代码,
    通常从驱动器上的另一个分区加载较大的引导加载程序。   

    GPT代表GUID划分表。这是一个正在逐步取代MBR的新标准。它与UEFI相关,UEFI用更现代的东西取代笨重的旧BIOS。
    反过来,GPT用更现代的东西取代了笨重的旧MBR分区系统。它被称为GUIDPartitionTable【全局唯一标识磁盘分区表】,
    因为驱动器上的每个分区都有一个“全局唯一标识符”,或者GUID--一个长时间的随机字符串,
    以至于地球上的每个GPT分区都有自己的唯一标识符。

    在MBR磁盘上,分区和引导数据存储在一个地方。如果该数据被覆盖或损坏,您就有麻烦了。
    相反,GPT跨磁盘存储此数据的多个副本,因此它更健壮,如果数据损坏,可以恢复。

    GPT还存储循环冗余校验(CRC)值,以检查其数据是否完整。如果数据损坏,GPT会注意到问题,
    并尝试从磁盘上的另一个位置恢复损坏的数据。MBR无法知道其数据是否已损坏--只有在引导进程失败
    或驱动器分区消失时才会看到问题。
    GUID分区表自带备份。在磁盘的首尾部分分别保存了一份相同的分区表,因此当一份损坏可以通过另一份恢复。
    而MBR磁盘分区表一旦被破坏就无法恢复,需要重新分区
    https://www.howtogeek.com/193669/whats-the-difference-between-gpt-and-mbr-when-partitioning-a-drive/
    https://www.html.cn/qa/other/20741.html
 * 

在文件 disk.c 中定义.

类型定义说明

◆ StorageHookFunction

typedef VOID *(* StorageHookFunction) (VOID *)

在文件 disk.c102 行定义.

函数说明

◆ disk_read_directly()

static INT32 disk_read_directly ( los_disk disk,
VOID *  buf,
UINT64  sector,
UINT32  count 
)
static

在文件 disk.c840 行定义.

841{
842 INT32 result = VFS_ERROR;
843 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
844 if ((bops == NULL) || (bops->read == NULL)) {
845 return VFS_ERROR;
846 }
847 if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
848 UINT32 cnt = 0;
849 UINT8 *buffer = disk->buff;
850 for (; count != 0; count -= cnt) {
851 cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
852 result = bops->read(disk->dev, buffer, sector, cnt);
853 if (result == (INT32)cnt) {
854 result = ENOERR;
855 } else {
856 break;
857 }
858 if (LOS_CopyFromKernel(buf, disk->sector_size * cnt, buffer, disk->sector_size * cnt)) {
859 result = VFS_ERROR;
860 break;
861 }
862 buf = (UINT8 *)buf + disk->sector_size * cnt;
863 sector += cnt;
864 }
865 } else {
866 result = bops->read(disk->dev, buf, sector, count);
867 if (result == count) {
868 result = ENOERR;
869 }
870 }
871
872 return result;
873}
signed int INT32
Definition: los_typedef.h:60
unsigned long VADDR_T
Definition: los_typedef.h:208
unsigned char UINT8
Definition: los_typedef.h:55
unsigned int UINT32
Definition: los_typedef.h:57
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
虚拟地址[vaddr,vaddr + len]是否在用户空间
Definition: los_vm_map.h:281
UINT32 sector_size
Definition: disk.h:185
struct Vnode * dev
Definition: disk.h:181
UINT8 * buff
Definition: disk.h:193
void * data
Definition: vnode.h:176
INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将内核数据拷贝到用户空间
Definition: user_copy.c:88
函数调用图:
这是这个函数的调用关系图:

◆ disk_write_directly()

static INT32 disk_write_directly ( los_disk disk,
const VOID *  buf,
UINT64  sector,
UINT32  count 
)
static

在文件 disk.c875 行定义.

876{
877 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
878 INT32 result = VFS_ERROR;
879 if ((bops == NULL) || (bops->read == NULL)) {
880 return VFS_ERROR;
881 }
882 if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
883 UINT32 cnt = 0;
884 UINT8 *buffer = disk->buff;
885 for (; count != 0; count -= cnt) {
886 cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
887 if (LOS_CopyToKernel(buffer, disk->sector_size * cnt, buf, disk->sector_size * cnt)) {
888 result = VFS_ERROR;
889 break;
890 }
891 result = bops->write(disk->dev, buffer, sector, cnt);
892 if (result == (INT32)cnt) {
893 result = ENOERR;
894 } else {
895 break;
896 }
897 buf = (UINT8 *)buf + disk->sector_size * cnt;
898 sector += cnt;
899 }
900 } else {
901 result = bops->write(disk->dev, buf, sector, count);
902 if (result == count) {
903 result = ENOERR;
904 }
905 }
906
907 return result;
908}
INT32 LOS_CopyToKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将用户空间的数据拷贝到内核空间
Definition: user_copy.c:101
函数调用图:
这是这个函数的调用关系图:

◆ DiskAddPart()

static INT32 DiskAddPart ( los_disk disk,
UINT64  sectorStart,
UINT64  sectorCount,
BOOL  IsValidPart 
)
static

在文件 disk.c349 行定义.

350{
351 CHAR devName[DEV_NAME_BUFF_SIZE];
352 struct Vnode *diskDev = NULL;
353 struct Vnode *partDev = NULL;
354 los_part *part = NULL;
355 INT32 ret;
356
357 if ((disk == NULL) || (disk->disk_status == STAT_UNUSED) ||
358 (disk->dev == NULL)) {
359 return VFS_ERROR;
360 }
361 //扇区判断,磁盘在创建伊始就扇区数量就固定了
362 if ((sectorCount > disk->sector_count) || ((disk->sector_count - sectorCount) < sectorStart)) {
363 PRINT_ERR("DiskAddPart failed: sector start is %llu, sector count is %llu\n", sectorStart, sectorCount);
364 return VFS_ERROR;
365 }
366 //devName = /dev/mmcblk0p2 代表的是 0号磁盘的2号分区
367
368 diskDev = disk->dev;
369 if (IsValidPart == TRUE) {//有效分区处理
370 ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%u",
371 ((disk->disk_name == NULL) ? "null" : disk->disk_name), 'p', disk->part_count);
372 if (ret < 0) {
373 return VFS_ERROR;
374 }
375 //为节点注册块设备驱动,目的是从此可以通过块操作访问私有数据
376 if (register_blockdriver(devName, ((struct drv_data *)diskDev->data)->ops,
377 RWE_RW_RW, ((struct drv_data *)diskDev->data)->priv)) {
378 PRINT_ERR("DiskAddPart : register %s fail!\n", devName);
379 return VFS_ERROR;
380 }
381
382 VnodeHold();
383 VnodeLookup(devName, &partDev, 0);//通过路径找到索引节点
384
385 part = DiskPartAllocate(partDev, sectorStart, sectorCount);//从全局分区池中分配分区项
386 VnodeDrop();
387 if (part == NULL) {
388 (VOID)unregister_blockdriver(devName);
389 return VFS_ERROR;
390 }
391 } else { //无效的分区也分配一个? @note_why
392 part = DiskPartAllocate(diskDev, sectorStart, sectorCount);
393 if (part == NULL) {
394 return VFS_ERROR;
395 }
396 }
397
398 DiskPartAddToDisk(disk, part);
399 if (disk->type == EMMC) {
400 part->type = EMMC;
401 }
402 return (INT32)part->part_id;
403}
static los_part * DiskPartAllocate(struct Vnode *dev, UINT64 start, UINT64 count)
分配一个磁盘分区,必须要有索引节点才给分配.
Definition: disk.c:303
static VOID DiskPartAddToDisk(los_disk *disk, los_part *part)
磁盘增加一个分区
Definition: disk.c:289
@ STAT_UNUSED
Definition: disk.h:171
char CHAR
Definition: los_typedef.h:63
CHAR * disk_name
Definition: disk.h:189
UINT8 type
Definition: disk.h:188
UINT32 disk_status
Definition: disk.h:178
UINT32 part_count
Definition: disk.h:179
UINT64 sector_count
Definition: disk.h:187
UINT32 part_id
Definition: disk.h:199
UINT8 type
Definition: disk.h:204
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
int VnodeDrop(void)
归还锁
Definition: vnode.c:292
int VnodeHold(void)
拿锁,封装互斥量
Definition: vnode.c:283
int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags)
通过路径查询vnode节点
Definition: vnode.c:491
函数调用图:
这是这个函数的调用关系图:

◆ DiskCacheDeinit()

static VOID DiskCacheDeinit ( los_disk disk)
static

在文件 disk.c1326 行定义.

1327{
1328 UINT32 diskID = disk->disk_id;
1329 if (GetDiskUsbStatus(diskID) == FALSE) {
1330 if (BcacheAsyncPrereadDeinit(disk->bcache) != LOS_OK) {
1331 PRINT_ERR("Blib async preread deinit failed in %s, %d\n", __FUNCTION__, __LINE__);
1332 }
1333#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1335#endif
1336 }
1337
1338 BlockCacheDeinit(disk->bcache);
1339 disk->bcache = NULL;
1340
1341 if (OsReHookFuncDelDiskRef != NULL) {
1343 }
1344}
VOID BlockCacheDeinit(OsBcache *bcache)
Definition: bcache.c:1122
INT32 OsSdSync(INT32 id)
Definition: bcache.c:956
VOID BcacheSyncThreadDeinit(const OsBcache *bc)
Definition: bcache.c:1055
UINT32 BcacheAsyncPrereadDeinit(OsBcache *bc)
Definition: bcache.c:1210
static BOOL GetDiskUsbStatus(UINT32 diskID)
Definition: disk.c:257
static UINT32 OsReHookFuncDelDiskRef(StorageHookFunction handler) __attribute__((weakref("osReHookFuncDel")))
VOID *(* StorageHookFunction)(VOID *)
Definition: disk.c:102
OsBcache * bcache
Definition: disk.h:183
UINT32 disk_id
Definition: disk.h:177
函数调用图:
这是这个函数的调用关系图:

◆ DiskCacheInit()

static OsBcache * DiskCacheInit ( UINT32  diskID,
const struct geometry *  diskInfo,
struct Vnode blkDriver 
)
static

在文件 disk.c1303 行定义.

1304{
1305#define SECTOR_SIZE 512
1306
1307 OsBcache *bc = NULL;
1308 UINT32 sectorPerBlock = diskInfo->geo_sectorsize / SECTOR_SIZE;
1309 if (sectorPerBlock != 0) {
1310 sectorPerBlock = g_uwFatSectorsPerBlock / sectorPerBlock;
1311 if (sectorPerBlock != 0) {
1312 bc = BlockCacheInit(blkDriver, diskInfo->geo_sectorsize, sectorPerBlock,
1313 g_uwFatBlockNums, diskInfo->geo_nsectors / sectorPerBlock);
1314 }
1315 }
1316
1317 if (bc == NULL) {
1318 PRINT_ERR("disk_init : disk have not init bcache cache!\n");
1319 return NULL;
1320 }
1321
1322 DiskCacheThreadInit(diskID, bc);
1323 return bc;
1324}
OsBcache * BlockCacheInit(struct Vnode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock, UINT32 blockNum, UINT64 blockCount)
Definition: bcache.c:1065
static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
Definition: disk.c:1283
UINT32 g_uwFatBlockNums
块数量 默认28
Definition: disk.c:80
UINT32 g_uwFatSectorsPerBlock
每块支持扇区数 默认64个扇区
Definition: disk.c:79
函数调用图:
这是这个函数的调用关系图:

◆ DiskCacheThreadInit()

static VOID DiskCacheThreadInit ( UINT32  diskID,
OsBcache bc 
)
static

在文件 disk.c1283 行定义.

1284{
1285 bc->prereadFun = NULL;
1286
1287 if (GetDiskUsbStatus(diskID) == FALSE) {
1288 if (BcacheAsyncPrereadInit(bc) == LOS_OK) {
1290 }
1291
1292#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1293 BcacheSyncThreadInit(bc, diskID);
1294#endif
1295 }
1296
1297 if (OsReHookFuncAddDiskRef != NULL) {
1300 }
1301}
VOID ResumeAsyncPreread(OsBcache *arg1, const OsBcacheBlock *arg2)
Definition: bcache.c:1169
VOID BcacheSyncThreadInit(OsBcache *bc, INT32 id)
块缓存同步任务初始化,开了个内核任务.
Definition: bcache.c:1037
UINT32 BcacheAsyncPrereadInit(OsBcache *bc)
Definition: bcache.c:1184
static UINT32 OsReHookFuncAddDiskRef(StorageHookFunction handler, VOID *param) __attribute__((weakref("osReHookFuncAdd")))
BcachePrereadFun prereadFun
Definition: bcache.h:109
函数调用图:
这是这个函数的调用关系图:

◆ DiskDeinit()

static INT32 DiskDeinit ( los_disk disk)
static

磁盘反初始化

在文件 disk.c1400 行定义.

1401{
1402 los_part *part = NULL;
1403 char *diskName = NULL;
1404 CHAR devName[DEV_NAME_BUFF_SIZE];
1405 INT32 ret;
1406
1407 if (LOS_ListEmpty(&disk->head) == FALSE) {
1408 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
1409 while (&part->list != &disk->head) {
1410 diskName = (disk->disk_name == NULL) ? "null" : disk->disk_name;
1411 ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%d",
1412 diskName, 'p', disk->part_count - 1);
1413 if (ret < 0) {
1414 return -ENAMETOOLONG;
1415 }
1416 DiskPartDelFromDisk(disk, part);//从磁盘删除分区
1417 (VOID)unregister_blockdriver(devName);//注销块驱动程序
1418 DiskPartRelease(part);//释放分区信息
1419
1420 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);//下一个分区内容
1421 }
1422 }
1423
1424 DISK_LOCK(&disk->disk_mutex);
1425
1426#ifdef LOSCFG_FS_FAT_CACHE
1427 DiskCacheDeinit(disk);
1428#else
1429 if (disk->buff != NULL) {
1430 free(disk->buff);
1431 }
1432#endif
1433
1434 disk->dev = NULL;
1435 DISK_UNLOCK(&disk->disk_mutex);
1436 (VOID)unregister_blockdriver(disk->disk_name);
1437 if (disk->disk_name != NULL) {
1439 disk->disk_name = NULL;
1440 }
1441 ret = pthread_mutex_destroy(&disk->disk_mutex);
1442 if (ret != 0) {
1443 PRINT_ERR("%s %d, mutex destroy failed, ret = %d\n", __FUNCTION__, __LINE__, ret);
1444 return -EFAULT;
1445 }
1446
1447 disk->disk_status = STAT_UNUSED;
1448
1449 return ENOERR;
1450}
static VOID DiskCacheDeinit(los_disk *disk)
Definition: disk.c:1326
static VOID DiskPartDelFromDisk(los_disk *disk, los_part *part)
从磁盘上删除分区
Definition: disk.c:297
static VOID DiskPartRelease(los_part *part)
清空分区信息
Definition: disk.c:330
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
int pthread_mutex_destroy(pthread_mutex_t *mutex)
销毁互斥锁
struct pthread_mutex disk_mutex
Definition: disk.h:191
LOS_DL_LIST head
Definition: disk.h:190
LOS_DL_LIST list
Definition: disk.h:215
struct LOS_DL_LIST * pstNext
Definition: los_list.h:84
函数调用图:
这是这个函数的调用关系图:

◆ DiskDivide()

static INT32 DiskDivide ( los_disk disk,
struct disk_divide_info info 
)
static

磁盘分区

在文件 disk.c405 行定义.

406{
407 UINT32 i;
408 INT32 ret;
409
410 disk->type = info->part[0].type;// 类型一般为 EMMC
411 for (i = 0; i < info->part_count; i++) {//遍历分区列表
412 if (info->sector_count < info->part[i].sector_start) {//总扇区都已经被分完
413 return VFS_ERROR;
414 }
415 if (info->part[i].sector_count > (info->sector_count - info->part[i].sector_start)) {//边界检测
416 PRINT_ERR("Part[%u] sector_start:%llu, sector_count:%llu, exceed emmc sector_count:%llu.\n", i,
417 info->part[i].sector_start, info->part[i].sector_count,
418 (info->sector_count - info->part[i].sector_start));
419 info->part[i].sector_count = info->sector_count - info->part[i].sector_start;//改变区的扇区数量
420 PRINT_ERR("Part[%u] sector_count change to %llu.\n", i, info->part[i].sector_count);
421 //增加一个分区
422 ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE);
423 if (ret == VFS_ERROR) {
424 return VFS_ERROR;
425 }
426 break;
427 }
428 ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE);
429 if (ret == VFS_ERROR) {
430 return VFS_ERROR;
431 }
432 }
433
434 return ENOERR;
435}
static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart)
Definition: disk.c:349
UINT32 part_count
Definition: disk.h:227
UINT64 sector_count
Definition: disk.h:225
struct partition_info part[MAX_DIVIDE_PART_PER_DISK+MAX_PRIMARY_PART_PER_DISK]
Definition: disk.h:232
UINT8 type
Definition: disk.h:219
UINT64 sector_count
Definition: disk.h:221
UINT64 sector_start
Definition: disk.h:220
函数调用图:
这是这个函数的调用关系图:

◆ DiskDivideAndPartitionRegister()

static INT32 DiskDivideAndPartitionRegister ( struct disk_divide_info info,
los_disk disk 
)
static

磁盘分区和注册分区

在文件 disk.c1380 行定义.

1381{
1382 INT32 ret;
1383
1384 if (info != NULL) {//有分区信息则直接分区
1385 ret = DiskDivide(disk, info);
1386 if (ret != ENOERR) {
1387 PRINT_ERR("DiskDivide failed, ret = %d\n", ret);
1388 return ret;
1389 }
1390 } else {//木有分区信息,则先注册分区
1391 ret = DiskPartitionRegister(disk);
1392 if (ret != ENOERR) {
1393 PRINT_ERR("DiskPartitionRegister failed, ret = %d\n", ret);
1394 return ret;
1395 }
1396 }
1397 return ENOERR;
1398}
INT32 DiskPartitionRegister(los_disk *disk)
磁盘分区注册
Definition: disk.c:786
static INT32 DiskDivide(los_disk *disk, struct disk_divide_info *info)
磁盘分区
Definition: disk.c:405
函数调用图:
这是这个函数的调用关系图:

◆ DiskGPTPartitionRecognition()

static INT32 DiskGPTPartitionRecognition ( struct Vnode blkDrv,
struct disk_divide_info info 
)
static

在文件 disk.c567 行定义.

568{
569 CHAR *gptBuf = NULL;
570 CHAR *partitionBuf = NULL;
571 UINT32 tableNum, i, index;
572 UINT32 partitionCount = 0;
573 INT32 ret;
574
575 ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &gptBuf, &partitionBuf);
576 if (ret != ENOERR) {
577 return ret;
578 }
579
580 ret = GPTInfoGet(blkDrv, gptBuf);//获取GDT类型的引导扇区信息
581 if (ret < 0) {
582 goto OUT_WITH_MEM;
583 }
584
585 tableNum = LD_DWORD_DISK(&gptBuf[TABLE_NUM_OFFSET]);
586 if (tableNum > TABLE_MAX_NUM) {
587 tableNum = TABLE_MAX_NUM;
588 }
589
590 index = (tableNum % PAR_ENTRY_NUM_PER_SECTOR) ? ((tableNum / PAR_ENTRY_NUM_PER_SECTOR) + 1) :
591 (tableNum / PAR_ENTRY_NUM_PER_SECTOR);
592
593 for (i = 0; i < index; i++) {
594 (VOID)memset_s(gptBuf, info->sector_size, 0, info->sector_size);
595 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
596 ret = bops->read(blkDrv, (UINT8 *)gptBuf, TABLE_START_SECTOR + i, 1);
597 if (ret != 1) { /* read failed */
598 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
599 ret = -EIO;
600 goto OUT_WITH_MEM;
601 }
602
603 ret = OsGPTPartitionRecognition(blkDrv, info, gptBuf, partitionBuf, &partitionCount);
604 if (ret < 0) {
605 if (ret == VFS_ERROR) {
606 ret = (INT32)partitionCount;
607 }
608 goto OUT_WITH_MEM;
609 }
610 }
611 ret = (INT32)partitionCount;
612
613OUT_WITH_MEM:
614 free(gptBuf);
615 free(partitionBuf);
616 return ret;
617}
static INT32 DiskPartitionMemZalloc(size_t boundary, size_t size, CHAR **gptBuf, CHAR **partitionBuf)
磁盘分区内存申请
Definition: disk.c:453
static INT32 GPTInfoGet(struct Vnode *blkDrv, CHAR *gptBuf)
获取GPT信息,是GPT还是MBR取决于磁盘上放的内容
Definition: disk.c:478
static INT32 OsGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info, const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount)
识别GPT分区内容
Definition: disk.c:522
UINT32 sector_size
Definition: disk.h:226
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartAddToDisk()

static VOID DiskPartAddToDisk ( los_disk disk,
los_part part 
)
static

磁盘增加一个分区

在文件 disk.c289 行定义.

290{
291 part->disk_id = disk->disk_id;
292 part->part_no_disk = disk->part_count;
293 LOS_ListTailInsert(&disk->head, &part->list);
294 disk->part_count++;
295}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
UINT32 disk_id
Definition: disk.h:198
UINT32 part_no_disk
Definition: disk.h:200
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartAllocate()

static los_part * DiskPartAllocate ( struct Vnode dev,
UINT64  start,
UINT64  count 
)
static

分配一个磁盘分区,必须要有索引节点才给分配.

在文件 disk.c303 行定义.

304{
305 UINT32 i;//从数组的开头遍历,先获取第一个分区
306 los_part *part = get_part(0); /* traversing from the beginning of the array */
307
308 if (part == NULL) {
309 return NULL;
310 }
311
312 for (i = 0; i < SYS_MAX_PART; i++) {//从数组开头开始遍历
313 if (part->dev == NULL) {//分区是否被使用,通过dev来判断.
314 part->part_id = i; //分区ID
315 part->part_no_mbr = 0; //主分区一般为0
316 part->dev = dev; //设置索引节点,所以节点这个概念很重要,贯彻了整个文件/磁盘系统,一定要理解透彻!!!
317 part->sector_start = start;//开始扇区
318 part->sector_count = count;//扇区总大小
319 part->part_name = NULL; //分区名称,暂无
320 LOS_ListInit(&part->list); //初始化链表节点,将通过它挂入磁盘分区链表上(los_disk->head).
321
322 return part; //就这个分区了.
323 }
324 part++;//找下一个空闲分区位
325 }
326
327 return NULL;
328}
los_part * get_part(INT32 id)
获取某个分区的描述符
Definition: disk.c:272
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
struct Vnode * dev
Definition: disk.h:205
UINT64 sector_count
Definition: disk.h:211
CHAR * part_name
Definition: disk.h:206
UINT32 part_no_mbr
Definition: disk.h:201
UINT64 sector_start
Definition: disk.h:207
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartDelFromDisk()

static VOID DiskPartDelFromDisk ( los_disk disk,
los_part part 
)
static

从磁盘上删除分区

在文件 disk.c297 行定义.

298{
299 LOS_ListDelete(&part->list);//从分区链表上摘掉
300 disk->part_count--;//分区数量减少
301}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartitionMemZalloc()

static INT32 DiskPartitionMemZalloc ( size_t  boundary,
size_t  size,
CHAR **  gptBuf,
CHAR **  partitionBuf 
)
static

磁盘分区内存申请

在文件 disk.c453 行定义.

454{
455 CHAR *buffer1 = NULL;
456 CHAR *buffer2 = NULL;
457 //分配一个 size 字节的块,其地址是边界的倍数。边界必须是 2 的幂!
458 buffer1 = (CHAR *)memalign(boundary, size);//对齐 memalign -> LOS_KernelMallocAlign
459 if (buffer1 == NULL) {
460 PRINT_ERR("%s buffer1 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__);
461 return -ENOMEM;
462 }
463 buffer2 = (CHAR *)memalign(boundary, size);
464 if (buffer2 == NULL) {
465 PRINT_ERR("%s buffer2 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__);
466 free(buffer1);
467 return -ENOMEM;
468 }
469 (VOID)memset_s(buffer1, size, 0, size);
470 (VOID)memset_s(buffer2, size, 0, size);
471
472 *gptBuf = buffer1;
473 *partitionBuf = buffer2;
474
475 return ENOERR;
476}
void * memalign(size_t boundary, size_t size)
Definition: malloc.c:112
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartitionRecognition()

static INT32 DiskPartitionRecognition ( struct Vnode blkDrv,
struct disk_divide_info info 
)
static

识别磁盘分区信息 https://blog.csdn.net/Hilavergil/article/details/79270379

在文件 disk.c728 行定义.

729{
730 INT32 ret;
731 INT32 extendedFlag;
732 INT32 extendedPos = 0;
733 INT32 mbrCount = 0;
734 UINT32 extendedAddress;
735 CHAR *mbrBuf = NULL;
736 CHAR *ebrBuf = NULL;
737
738 if (blkDrv == NULL) {
739 return -EINVAL;
740 }
741 //获取块设备驱动程序
742 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
743
744 if ((bops == NULL) || (bops->read == NULL)) {
745 return -EINVAL;
746 }
747
748 ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &mbrBuf, &ebrBuf);
749 if (ret != ENOERR) {
750 return ret;
751 }
752
753 ret = OsMBRInfoGet(blkDrv, mbrBuf);//获取(MBR)首个扇区内容,
754 if (ret < 0) {
755 goto OUT_WITH_MEM;
756 }
757
758 /* The partition type is GPT */
759 if (mbrBuf[PARTION_MODE_BTYE] == (CHAR)PARTION_MODE_GPT) {//如果采用了GPT的分区方式 0xEE
760 ret = DiskGPTPartitionRecognition(blkDrv, info);//用GPT方式解析分区信息
761 goto OUT_WITH_MEM;
762 }
763
764 ret = OsEBRInfoGet(blkDrv, info, ebrBuf, mbrBuf);//获取扩展分区信息
765 if (ret < 0) {//4个分区表中不一定会有扩展分区
766 ret = 0; /* no mbr */
767 goto OUT_WITH_MEM;
768 }
769
770 extendedFlag = OsPrimaryPartitionRecognition(mbrBuf, info, &extendedPos, &mbrCount);//解析主分区信息
771 if (extendedFlag) {//如果有扩展分区
772 extendedAddress = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (extendedPos * PAR_TABLE_SIZE)]);//逻辑分区开始解析位置
773 ret = OsLogicalPartitionRecognition(blkDrv, info, extendedAddress, ebrBuf, mbrCount);//解析逻辑分区
774 if (ret <= 0) {
775 goto OUT_WITH_MEM;
776 }
777 }
778 ret += mbrCount;
779
780OUT_WITH_MEM:
781 free(ebrBuf);
782 free(mbrBuf);
783 return ret;
784}
static INT32 OsMBRInfoGet(struct Vnode *blkDrv, CHAR *mbrBuf)
获取MBR信息,即特殊扇区信息,在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。
Definition: disk.c:619
static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divide_info *info, INT32 *extendedPos, INT32 *mbrCount)
识别主分区
Definition: disk.c:662
static INT32 OsEBRInfoGet(struct Vnode *blkDrv, const struct disk_divide_info *info, CHAR *ebrBuf, const CHAR *mbrBuf)
Definition: disk.c:641
static INT32 DiskGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
Definition: disk.c:567
static INT32 OsLogicalPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info, UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
识别扩展分区
Definition: disk.c:689
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartitionRegister()

INT32 DiskPartitionRegister ( los_disk disk)

磁盘分区注册

在文件 disk.c786 行定义.

787{
788 INT32 count;
789 UINT32 i, partSize;
790 los_part *part = NULL;
791 struct disk_divide_info parInfo;
792 //填充disk_divide_info结构体设置分区信息
793 /* Fill disk_divide_info structure to set partition's infomation. */
794 (VOID)memset_s(parInfo.part, sizeof(parInfo.part), 0, sizeof(parInfo.part));
795 partSize = sizeof(parInfo.part) / sizeof(parInfo.part[0]);//获取能分区的最大数量
796 parInfo.sector_size = disk->sector_size;//磁盘扇区大小,这是固定的,不管什么分区,扇区大小是不变的(512字节)
797 parInfo.sector_count = disk->sector_count;//扇区数量,注意:这里只是默认的值,最终的值来源于读取的MBR或EBR内容
798 //即每个分区的扇区大小和总数量是可以不一样的.
799 count = DiskPartitionRecognition(disk->dev, &parInfo);//有了分区信息就阔以开始解析了
800 if (count == VFS_ERROR) {//分区表错误, @note_thinking 直接返回就行了,做 get_part 没意义了吧
801 part = get_part(DiskAddPart(disk, 0, disk->sector_count, FALSE));//
802 if (part == NULL) {
803 return VFS_ERROR;
804 }
805 part->part_no_mbr = 0;//打印磁盘没有一个可用的分区表
806 PRINTK("Disk %s doesn't contain a valid partition table.\n", disk->disk_name);
807 return ENOERR;
808 } else if (count < 0) {
809 return VFS_ERROR;
810 }
811
812 parInfo.part_count = count;//保存分区数量
813 if (count == 0) { //整个函数写的很怪,建议重写 @note_thinking
814 part = get_part(DiskAddPart(disk, 0, disk->sector_count, TRUE));
815 if (part == NULL) {
816 return VFS_ERROR;
817 }
818 part->part_no_mbr = 0;
819
820 PRINTK("No MBR detected.\n");
821 return ENOERR;
822 }
823
824 for (i = 0; i < partSize; i++) {//磁盘的分区是解析出来了,接着要纳入全局统一管理了.
825 /* Read the disk_divide_info structure to get partition's infomation. */
826 if ((parInfo.part[i].type != 0) && (parInfo.part[i].type != EXTENDED_PAR) &&
827 (parInfo.part[i].type != EXTENDED_8G)) {
828 part = get_part(DiskAddPart(disk, parInfo.part[i].sector_start, parInfo.part[i].sector_count, TRUE));
829 if (part == NULL) {
830 return VFS_ERROR;
831 }
832 part->part_no_mbr = i + 1;//全局记录 第几个主引导分区
833 part->filesystem_type = parInfo.part[i].type;//全局记录 文件系统类型
834 }
835 }
836
837 return ENOERR;
838}
static INT32 DiskPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
识别磁盘分区信息 https://blog.csdn.net/Hilavergil/article/details/79270379
Definition: disk.c:728
函数调用图:
这是这个函数的调用关系图:

◆ DiskPartRelease()

static VOID DiskPartRelease ( los_part part)
static

清空分区信息

在文件 disk.c330 行定义.

331{
332 part->dev = NULL;//全局释放这步最关键,因为 DiskPartAllocate 中是通过它来判断是否全局分区项已被占用
333 part->part_no_disk = 0; //复位归0
334 part->part_no_mbr = 0; //复位归0
335 if (part->part_name != NULL) {
336 free(part->part_name);//分区名称是内核内存分配的,所以要单独释放.
337 part->part_name = NULL;
338 }
339}
函数调用图:
这是这个函数的调用关系图:

◆ DiskStructInit()

static VOID DiskStructInit ( const CHAR diskName,
INT32  diskID,
const struct geometry *  diskInfo,
struct Vnode blkDriver,
los_disk disk 
)
static

磁盘结构体初始化,初始化 los_disk 结构体

在文件 disk.c1347 行定义.

1349{
1350 size_t nameLen;
1351 disk->disk_id = diskID;
1352 disk->dev = blkDriver;
1353 disk->sector_start = 0;
1354 disk->sector_size = diskInfo->geo_sectorsize;
1355 disk->sector_count = diskInfo->geo_nsectors;
1356
1357 nameLen = strlen(diskName); /* caller los_disk_init has chek name */
1358
1359 if (disk->disk_name != NULL) {
1361 disk->disk_name = NULL;
1362 }
1363
1364 disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1));
1365 if (disk->disk_name == NULL) {
1366 PRINT_ERR("DiskStructInit alloc memory failed.\n");
1367 return;
1368 }
1369
1370 if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) {
1371 PRINT_ERR("DiskStructInit strncpy_s failed.\n");
1373 disk->disk_name = NULL;
1374 return;
1375 }
1376 disk->disk_name[nameLen] = '\0';
1377 LOS_ListInit(&disk->head);
1378}
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT64 sector_start
Definition: disk.h:186
函数调用图:
这是这个函数的调用关系图:

◆ EraseDiskByID()

INT32 EraseDiskByID ( UINT32  diskID,
size_t  startSector,
UINT32  sectors 
)

在文件 disk.c1831 行定义.

1832{
1833 INT32 ret = VFS_ERROR;
1834#ifdef LOSCFG_DRIVERS_MMC //使能MMC
1835 los_disk *disk = get_disk((INT32)diskID);//找到磁盘信息
1836 if (disk != NULL) {
1837 ret = StorageBlockMmcErase(diskID, startSector, sectors);
1838 }//..\code-2.0-canary\device\hisilicon\third_party\uboot\u-boot-2020.01\cmd\mmc.c
1839#endif
1840
1841 return ret;
1842}
ssize_t StorageBlockMmcErase(uint32_t blockId, size_t secStart, size_t secNr)
通过磁盘ID 擦除磁盘信息
los_disk * get_disk(INT32 id)
Find disk driver.
Definition: disk.c:263
函数调用图:
这是这个函数的调用关系图:

◆ GetDiskUsbStatus()

static BOOL GetDiskUsbStatus ( UINT32  diskID)
static

在文件 disk.c257 行定义.

258{
259 return (g_usbMode & (1u << diskID)) ? TRUE : FALSE;
260}
UINT32 g_usbMode
Definition: disk.c:85
这是这个函数的调用关系图:

◆ GetFatBlockNums()

UINT32 GetFatBlockNums ( VOID  )

在文件 disk.c110 行定义.

111{
112 return g_uwFatBlockNums;
113}
这是这个函数的调用关系图:

◆ GetFatSectorsPerBlock()

UINT32 GetFatSectorsPerBlock ( VOID  )

在文件 disk.c120 行定义.

121{
123}

◆ GetFirstPartStart()

static UINT64 GetFirstPartStart ( const los_part part)
static

在文件 disk.c281 行定义.

282{
283 los_part *firstPart = NULL;
284 los_disk *disk = get_disk((INT32)part->disk_id);
285 firstPart = (disk == NULL) ? NULL : LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
286 return (firstPart == NULL) ? 0 : firstPart->sector_start;
287}
函数调用图:
这是这个函数的调用关系图:

◆ GPTInfoGet()

static INT32 GPTInfoGet ( struct Vnode blkDrv,
CHAR gptBuf 
)
static

获取GPT信息,是GPT还是MBR取决于磁盘上放的内容

在文件 disk.c478 行定义.

479{
480 INT32 ret;
481 //获取驱动程序
482 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
483 //从第一个扇区,从这可以看出 GPT是兼容 MBR的,因为 MBR的内容是放在 0 扇区.
484 ret = bops->read(blkDrv, (UINT8 *)gptBuf, 1, 1); /* Read the device first sector */
485 if (ret != 1) { /* Read failed */
486 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
487 return -EIO;
488 }
489
490 if (!VERIFY_GPT(gptBuf)) {
491 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
492 return VFS_ERROR;
493 }
494
495 return ENOERR;
496}
这是这个函数的调用关系图:

◆ GPTPartitionTypeRecognition()

static CHAR GPTPartitionTypeRecognition ( const CHAR parBuf)
static

GPT分区类型识别

在文件 disk.c437 行定义.

438{
439 const CHAR *buf = parBuf;
440 const CHAR *fsType = "FAT";
441 const CHAR *str = "\xEB\x52\x90" "NTFS "; /* NTFS Boot entry point | NTFS 引导入口点*/
442
443 if (((LD_DWORD_DISK(&buf[BS_FILSYSTEMTYPE32]) & BS_FS_TYPE_MASK) == BS_FS_TYPE_VALUE) ||
444 (strncmp(&buf[BS_FILSYSTYPE], fsType, strlen(fsType)) == 0)) {//识别FAT的方法
445 return BS_FS_TYPE_FAT;
446 } else if (strncmp(&buf[BS_JMPBOOT], str, strlen(str)) == 0) {//识别NTFS的方法
447 return BS_FS_TYPE_NTFS;
448 }
449
450 return ENOERR;
451}
这是这个函数的调用关系图:

◆ los_get_mmcdisk_bytype()

los_disk * los_get_mmcdisk_bytype ( UINT8  type)

在文件 disk.c226 行定义.

227{
228 const CHAR *mmcDevHead = "/dev/mmcblk";
229
230 for (INT32 diskId = 0; diskId < SYS_MAX_DISK; diskId++) {
231 los_disk *disk = get_disk(diskId);
232 if (disk == NULL) {
233 continue;
234 } else if ((disk->type == type) && (strncmp(disk->disk_name, mmcDevHead, strlen(mmcDevHead)) == 0)) {
235 return disk;
236 }
237 }
238 PRINT_ERR("Cannot find the mmc disk!\n");
239 return NULL;
240}
函数调用图:
这是这个函数的调用关系图:

◆ OsDiskInitSub()

static UINT32 OsDiskInitSub ( const CHAR diskName,
INT32  diskID,
los_disk disk,
struct geometry *  diskInfo,
struct Vnode blkDriver 
)
static

磁盘初始化

在文件 disk.c1452 行定义.

1454{
1455 pthread_mutexattr_t attr;
1456#ifdef LOSCFG_FS_FAT_CACHE
1457 OsBcache *bc = DiskCacheInit((UINT32)diskID, diskInfo, blkDriver);
1458 if (bc == NULL) {
1459 return VFS_ERROR;
1460 }
1461 disk->bcache = bc;
1462#endif
1463
1464 (VOID)pthread_mutexattr_init(&attr);
1465 attr.type = PTHREAD_MUTEX_RECURSIVE;
1466 (VOID)pthread_mutex_init(&disk->disk_mutex, &attr);
1467
1468 DiskStructInit(diskName, diskID, diskInfo, blkDriver, disk);
1469
1470#ifndef LOSCFG_FS_FAT_CACHE
1471 disk->buff = malloc(diskInfo->geo_sectorsize * DISK_DIRECT_BUFFER_SIZE);
1472 if (disk->buff == NULL) {
1473 PRINT_ERR("OsDiskInitSub: direct buffer of disk init failed\n");
1474 return VFS_ERROR;
1475 }
1476#endif
1477
1478 return ENOERR;
1479}
static OsBcache * DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver)
Definition: disk.c:1303
static VOID DiskStructInit(const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver, los_disk *disk)
磁盘结构体初始化,初始化 los_disk 结构体
Definition: disk.c:1347
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
初始化互斥锁。 如果 mutexAttr 为 NULL,则使用默认属性。
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
初始化互斥锁属性
Definition: pthread_mutex.c:65
函数调用图:
这是这个函数的调用关系图:

◆ OsEBRInfoGet()

static INT32 OsEBRInfoGet ( struct Vnode blkDrv,
const struct disk_divide_info info,
CHAR ebrBuf,
const CHAR mbrBuf 
)
static

在文件 disk.c641 行定义.

643{
644 INT32 ret;
645
646 if (VERIFY_FS(mbrBuf)) {//确认是个文件系统的引导扇区,因为紧接着要去读这个扇区内容,所以先判断有没有这个扇区.
647 if (info->sector_count <= LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET])) {
648 return VFS_ERROR;
649 }
650 //获取块设备驱动程序
651 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
652 ret = bops->read(blkDrv, (UINT8 *)ebrBuf, LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]), 1);//读取某个扇区信息
653 if ((ret != 1) || (!VERIFY_FS(ebrBuf))) { /* read failed */ //这里同样要确认下读出来的扇区是文件系统的引导扇区
654 PRINT_ERR("OsEBRInfoGet, verify_fs error, ret = %d\n", ret);
655 return -EIO;
656 }
657 }
658
659 return ENOERR;
660}
这是这个函数的调用关系图:

◆ OsGPTPartitionRecognition()

static INT32 OsGPTPartitionRecognition ( struct Vnode blkDrv,
struct disk_divide_info info,
const CHAR gptBuf,
CHAR partitionBuf,
UINT32 partitionCount 
)
static

识别GPT分区内容

在文件 disk.c522 行定义.

524{
525 UINT32 j;
526 INT32 ret = VFS_ERROR;
527 UINT64 partitionStart, partitionEnd;
528 struct block_operations *bops = NULL;
529
530 for (j = 0; j < PAR_ENTRY_NUM_PER_SECTOR; j++) {
531 if (!VERITY_AVAILABLE_PAR(&gptBuf[j * TABLE_SIZE])) {//ESP 和 MSR 分区
532 PRINTK("The partition type is ESP or MSR!\n");
533 continue;
534 }
535
536 if (!VERITY_PAR_VALID(&gptBuf[j * TABLE_SIZE])) {
537 return VFS_ERROR;
538 }
539
540 partitionStart = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_START_OFFSET]);//读取开始扇区
541 partitionEnd = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_END_OFFSET]);//读取结束扇区
542 if ((partitionStart >= partitionEnd) || (partitionEnd > info->sector_count)) {
543 PRINT_ERR("GPT partition %u recognition failed : partitionStart = %llu, partitionEnd = %llu\n",
544 j, partitionStart, partitionEnd);
545 return VFS_ERROR;
546 }
547
548 (VOID)memset_s(partitionBuf, info->sector_size, 0, info->sector_size);
549
550 bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
551
552 ret = bops->read(blkDrv, (UINT8 *)partitionBuf, partitionStart, 1);//读取扇区内容
553 if (ret != 1) { /* read failed */
554 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
555 return -EIO;
556 }
557
558 ret = OsGPTPartitionRecognitionSub(info, partitionBuf, partitionCount, partitionStart, partitionEnd);
559 if (ret != ENOERR) {
560 return VFS_ERROR;
561 }
562 }
563
564 return ret;
565}
static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const CHAR *partitionBuf, UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd)
解析GPT分区内容
Definition: disk.c:498
long unsigned int UINT64
Definition: los_typedef.h:66
函数调用图:
这是这个函数的调用关系图:

◆ OsGPTPartitionRecognitionSub()

static INT32 OsGPTPartitionRecognitionSub ( struct disk_divide_info info,
const CHAR partitionBuf,
UINT32 partitionCount,
UINT64  partitionStart,
UINT64  partitionEnd 
)
static

解析GPT分区内容

在文件 disk.c498 行定义.

500{
501 CHAR partitionType;
502
503 if (VERIFY_FS(partitionBuf)) {
504 partitionType = GPTPartitionTypeRecognition(partitionBuf);//文件系统类型,支持FAT和NTFS
505 if (partitionType) {
506 if (*partitionCount >= MAX_DIVIDE_PART_PER_DISK) {
507 return VFS_ERROR;
508 }
509 info->part[*partitionCount].type = partitionType;//文件系统
510 info->part[*partitionCount].sector_start = partitionStart;//开始扇区
511 info->part[*partitionCount].sector_count = (partitionEnd - partitionStart) + 1;//扇区总数
512 (*partitionCount)++;//磁盘扇区数量增加
513 } else {
514 PRINT_ERR("The partition type is not allowed to use!\n");
515 }
516 } else {
517 PRINT_ERR("Do not support the partition type!\n");
518 }
519 return ENOERR;
520}
static CHAR GPTPartitionTypeRecognition(const CHAR *parBuf)
GPT分区类型识别
Definition: disk.c:437
函数调用图:
这是这个函数的调用关系图:

◆ OsLogicalPartitionRecognition()

static INT32 OsLogicalPartitionRecognition ( struct Vnode blkDrv,
struct disk_divide_info info,
UINT32  extendedAddress,
CHAR ebrBuf,
INT32  mbrCount 
)
static

识别扩展分区

在文件 disk.c689 行定义.

691{
692 INT32 ret;
693 UINT32 extendedOffset = 0;
694 CHAR ebrPartitionType;
695 INT32 ebrCount = 0;
696
697 do {//循环读取一个个扩展分区信息
698 (VOID)memset_s(ebrBuf, info->sector_size, 0, info->sector_size);
699 if (((UINT64)(extendedAddress) + extendedOffset) >= info->sector_count) {
700 PRINT_ERR("extended partition is out of disk range: extendedAddress = %u, extendedOffset = %u\n",
701 extendedAddress, extendedOffset);
702 break;
703 }
704 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
705 ret = bops->read(blkDrv, (UINT8 *)ebrBuf, extendedAddress + extendedOffset, 1);//读取扇区
706 if (ret != 1) { /* read failed */
707 PRINT_ERR("driver read return error: %d, extendedAddress = %u, extendedOffset = %u\n", ret,
708 extendedAddress, extendedOffset);
709 return -EIO;
710 }
711 ebrPartitionType = ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET];//读取分区类型
712 if (ebrPartitionType && ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK)) {//填充分区信息
713 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].type = ebrPartitionType;
714 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_start = extendedAddress + extendedOffset +
715 LD_DWORD_DISK(&ebrBuf[PAR_OFFSET +
716 PAR_START_OFFSET]);
717 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_count = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET +
718 PAR_COUNT_OFFSET]);
719 ebrCount++;//扩展分区的数量
720 }
721 extendedOffset = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET + PAR_START_OFFSET + PAR_TABLE_SIZE]);//继续下一个分区
722 } while ((ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + PAR_TABLE_SIZE] != 0) &&
723 ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK));//结束条件1.读完分区表 2.总分区数超了
724
725 return ebrCount;
726}
这是这个函数的调用关系图:

◆ OsMBRInfoGet()

static INT32 OsMBRInfoGet ( struct Vnode blkDrv,
CHAR mbrBuf 
)
static

获取MBR信息,即特殊扇区信息,在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。

在文件 disk.c619 行定义.

620{
621 INT32 ret;
622 //读取MBR,从0扇区开始,长度为1扇区
623 /* read MBR, start from sector 0, length is 1 sector */
624 //以块为操作的接口封装
625 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
626
627 ret = bops->read(blkDrv, (UINT8 *)mbrBuf, 0, 1);//读一个扇区 [0-1]
628 if (ret != 1) { /* read failed */
629 PRINT_ERR("driver read return error: %d\n", ret);
630 return -EIO;
631 }
632
633 /* Check boot record signature. *///检查引导记录签名
634 if (LD_WORD_DISK(&mbrBuf[BS_SIG55AA]) != BS_SIG55AA_VALUE) {//高低换位
635 return VFS_ERROR;
636 }
637
638 return ENOERR;
639}
这是这个函数的调用关系图:

◆ OsPartFind()

static los_part * OsPartFind ( los_disk disk,
const struct Vnode blkDriver 
)
static

通过索引节点从磁盘中找分区信息

在文件 disk.c1656 行定义.

1657{
1658 los_part *part = NULL;
1659
1660 DISK_LOCK(&disk->disk_mutex);//先上锁,disk->head上挂的是本磁盘所有的分区
1661 if ((disk->disk_status != STAT_INUSED) || (LOS_ListEmpty(&disk->head) == TRUE)) {
1662 goto EXIT;
1663 }
1664 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);//拿出首个分区信息
1665 if (disk->dev == blkDriver) {//如果节点信息等于 disk->dev,注意此处是 disk 而不是 part->dev
1666 goto EXIT;//找到 goto
1667 }
1668
1669 while (&part->list != &disk->head) {//遍历链表
1670 if (part->dev == blkDriver) {//找到节点所在分区
1671 goto EXIT;
1672 }
1673 part = LOS_DL_LIST_ENTRY(part->list.pstNext, los_part, list);//下一个分区信息
1674 }
1675 part = NULL;
1676
1677EXIT:
1678 DISK_UNLOCK(&disk->disk_mutex);
1679 return part;
1680}
@ STAT_INUSED
Definition: disk.h:172
函数调用图:
这是这个函数的调用关系图:

◆ OsPrimaryPartitionRecognition()

static INT32 OsPrimaryPartitionRecognition ( const CHAR mbrBuf,
struct disk_divide_info info,
INT32 extendedPos,
INT32 mbrCount 
)
static

识别主分区

在文件 disk.c662 行定义.

664{
665 INT32 i;
666 CHAR mbrPartitionType;
667 INT32 extendedFlag = 0;
668 INT32 count = 0;
669 //mbrBuf的内容是磁盘的第0柱面第0磁盘的首个扇区内容,也称为特殊扇区
670 for (i = 0; i < MAX_PRIMARY_PART_PER_DISK; i++) {//最多4个主分区,这是由MBR的第二部分DPT(Disk Partition Table,硬盘分区表)规定死的
671 mbrPartitionType = mbrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + (i * PAR_TABLE_SIZE)];//读取分区类型
672 if (mbrPartitionType) {
673 info->part[i].type = mbrPartitionType;//记录分区
674 info->part[i].sector_start = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (i * PAR_TABLE_SIZE)]);//读取开始扇区编号
675 info->part[i].sector_count = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_COUNT_OFFSET + (i * PAR_TABLE_SIZE)]);//读取共有多少扇区
676 if ((mbrPartitionType == EXTENDED_PAR) || (mbrPartitionType == EXTENDED_8G)) {//分区类型如果是扩展分区
677 extendedFlag = 1;//贴上硬盘分区表有扩展分区
678 *extendedPos = i;//记录第几个位置是扩展分区
679 continue;//继续,说明 count 记录的是主分区的数量
680 }
681 count++;
682 }
683 }
684 *mbrCount = count;//带出主分区数量
685
686 return extendedFlag;//返回是否为扩展分区标签
687}
这是这个函数的调用关系图:

◆ OsReHookFuncAddDiskRef()

static UINT32 OsReHookFuncAddDiskRef ( StorageHookFunction  handler,
VOID *  param 
)
static
这是这个函数的调用关系图:

◆ OsReHookFuncDelDiskRef()

static UINT32 OsReHookFuncDelDiskRef ( StorageHookFunction  handler)
static
这是这个函数的调用关系图:

◆ SetDiskPartName()

INT32 SetDiskPartName ( los_part part,
const CHAR src 
)

设置分区名称

在文件 disk.c1726 行定义.

1727{
1728 size_t len;
1729 los_disk *disk = NULL;
1730
1731 if ((part == NULL) || (src == NULL)) {
1732 return VFS_ERROR;
1733 }
1734
1735 len = strlen(src);
1736 if ((len == 0) || (len >= DISK_NAME)) {
1737 return VFS_ERROR;
1738 }
1739
1740 disk = get_disk((INT32)part->disk_id);
1741 if (disk == NULL) {
1742 return VFS_ERROR;
1743 }
1744
1745 DISK_LOCK(&disk->disk_mutex);
1746 if (disk->disk_status != STAT_INUSED) {
1747 goto ERROR_HANDLE;
1748 }
1749
1750 part->part_name = (CHAR *)zalloc(len + 1);//分区名称内存需来自内核空间
1751 if (part->part_name == NULL) {
1752 PRINT_ERR("%s[%d] zalloc failure\n", __FUNCTION__, __LINE__);
1753 goto ERROR_HANDLE;
1754 }
1755
1756 if (strcpy_s(part->part_name, len + 1, src) != EOK) {
1757 free(part->part_name);
1758 part->part_name = NULL;
1759 goto ERROR_HANDLE;
1760 }
1761
1762 DISK_UNLOCK(&disk->disk_mutex);
1763 return ENOERR;
1764
1765ERROR_HANDLE:
1766 DISK_UNLOCK(&disk->disk_mutex);
1767 return VFS_ERROR;
1768}
void * zalloc(size_t size)
Definition: malloc.c:91
函数调用图:
这是这个函数的调用关系图:

◆ SetFatBlockNums()

VOID SetFatBlockNums ( UINT32  blockNums)

在文件 disk.c115 行定义.

116{
117 g_uwFatBlockNums = blockNums;
118}

◆ SetFatSectorsPerBlock()

VOID SetFatSectorsPerBlock ( UINT32  sectorsPerBlock)

设置FAR每块扇区数

在文件 disk.c125 行定义.

126{
127 if (((sectorsPerBlock % UNSIGNED_INTEGER_BITS) == 0) && //1.必须是整数倍
128 ((sectorsPerBlock >> UNINT_LOG2_SHIFT) <= BCACHE_BLOCK_FLAGS)) {
129 g_uwFatSectorsPerBlock = sectorsPerBlock;
130 }
131}

◆ StorageBlockMmcErase()

ssize_t StorageBlockMmcErase ( uint32_t  blockId,
size_t  secStart,
size_t  secNr 
)

通过磁盘ID 擦除磁盘信息

这是这个函数的调用关系图:

变量说明

◆ g_diskFatBlockSpinlock

spinlock_t g_diskFatBlockSpinlock

磁盘Fat块自旋锁

在文件 disk.c83 行定义.

◆ g_diskSpinlock

spinlock_t g_diskSpinlock

磁盘自锁锁

在文件 disk.c82 行定义.

◆ g_sysDisk

los_disk g_sysDisk[SYS_MAX_DISK]

支持挂载的磁盘总数量 5个

在文件 disk.c76 行定义.

◆ g_sysPart

los_part g_sysPart[SYS_MAX_PART]

支持磁盘的分区总数量 5*16,每个磁盘最大分16个区

在文件 disk.c77 行定义.

◆ g_usbMode

UINT32 g_usbMode = 0

在文件 disk.c85 行定义.

◆ g_uwFatBlockNums

UINT32 g_uwFatBlockNums = CONFIG_FS_FAT_BLOCK_NUMS

块数量 默认28

在文件 disk.c80 行定义.

◆ g_uwFatSectorsPerBlock

UINT32 g_uwFatSectorsPerBlock = CONFIG_FS_FAT_SECTOR_PER_BLOCK

每块支持扇区数 默认64个扇区

在文件 disk.c79 行定义.