提交 a8e9169e 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

根文件系统rootfs 部分注释

搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
上级 9f85adba
......@@ -30,8 +30,6 @@
搜索 **[@note_thinking]()** 是注者的思考和吐槽鸿蒙源码的地方
若有好的建议请邮箱**kuangyufei@126.com**或私信联系.
- ### **理解内核的三个层级**
笔者认为理解内核需分三个层级:
......@@ -66,8 +64,13 @@
中文加注版比官方版无新增文件,只多了一个zzz的目录,里面放了一些笔者使用的文件,它与内核代码无关,大家可以忽略它,取名zzz是为了排在最后,减少对原有代码目录级的侵入,zzz的想法源于微信中名称为AAA的那批牛人,你的微信里应该也有他们熟悉的身影吧 :|P
- ### **参与贡献**
1. Fork 本仓库 >> 新建 Feat_xxx 分支 >> 提交代码注解 >> 新建 Pull Request
2. [新建 Issue](https://gitee.com/weharmony/kernel_liteos_a_note/issues)
- ### **既然选择了远方,就不要怕天高路远,行动起来!**
- ### **联系方式**
kuangyufei@126.com
---
......@@ -75,6 +78,5 @@
注释中文版 进入 >\> [鸿蒙内核源码注释中文版 【 Gitee仓](https://gitee.com/weharmony/kernel_liteos_a_note) | [CSDN仓](https://codechina.csdn.net/kuangyufei/kernel_liteos_a_note) | [Github仓](https://github.com/kuangyufei/kernel_liteos_a_note) | [Coding仓 】](https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files)阅读
内容仅代表个人观点,会反复修正,出精品注解,写精品文章,一律原创,转载需注明出处,不修改内容,不乱插广告,错漏之处欢迎指正笔者第一时间加以完善。
# ![](https://oscimg.oschina.net/oscnet/up-c1f5f5e88b38fcb25f274a2062384b0c61e.png)
\ No newline at end of file
......@@ -52,13 +52,30 @@
extern "C" {
#endif
#endif /* __cplusplus */
#define SYS_MAX_DISK 5
#define MAX_DIVIDE_PART_PER_DISK 16
#define MAX_PRIMARY_PART_PER_DISK 4
#define SYS_MAX_PART (SYS_MAX_DISK * MAX_DIVIDE_PART_PER_DISK)
#define DISK_NAME 255
#define DISK_MAX_SECTOR_SIZE 512
/***********************************************
https://blog.csdn.net/buzaikoulan/article/details/44405915
MBR 全称为Master Boot Record,即硬盘的主引导记录,硬盘分区有三种,主磁盘分区、扩展磁盘分区、逻辑分区
主分区:也叫引导分区,硬盘的启动分区,最多可能创建4个
扩展磁盘分区:除了主分区外,剩余的磁盘空间就是扩展分区了,扩展分区可以没有,最多1个。
逻辑分区:在扩展分区上面,可以创建多个逻辑分区。逻辑分区相当于一块存储截止,和操作系统还有别的逻辑分区、主分区没有什么关系,是“独立的”。
硬盘的容量=主分区的容量+扩展分区的容量
扩展分区的容量=各个逻辑分区的容量之和
通俗的讲主分区是硬盘的主人,而扩展分区是这个硬盘上的仆人,主分区和扩展分区为主从关系。
给新硬盘上建立分区时都要遵循以下的顺序:建立主分区→建立扩展分区→建立逻辑分区→激活主分区→格式化所有分区
--------------------------
与MBR对应的是GPT,是对超大容量磁盘的一种分区格式
GPT,即Globally Unique Identifier Partition Table Format,全局唯一标识符的分区表的格式。
这种分区模式相比MBR有着非常多的优势。
首先,它至少可以分出128个分区,完全不需要扩展分区和逻辑分区来帮忙就可以分出任何想要的分区来。
其次,GPT最大支持18EB的硬盘,几乎就相当于没有限制。
***********************************************/
#define SYS_MAX_DISK 5 //最大支持磁盘数量
#define MAX_DIVIDE_PART_PER_DISK 16 //磁盘最大支持逻辑分区数
#define MAX_PRIMARY_PART_PER_DISK 4 //磁盘最大支持主分区数
#define SYS_MAX_PART (SYS_MAX_DISK * MAX_DIVIDE_PART_PER_DISK) //系统最大支持分区数
#define DISK_NAME 255 //磁盘名称
#define DISK_MAX_SECTOR_SIZE 512 //扇区大小,字节
#define PAR_OFFSET 446 /* MBR: Partition table offset (2) */
#define BS_SIG55AA 510 /* Signature word (2) */
......@@ -71,9 +88,9 @@ extern "C" {
#define PAR_START_OFFSET 8
#define PAR_COUNT_OFFSET 12
#define PAR_TABLE_SIZE 16
#define EXTENDED_PAR 0x0F
#define EXTENDED_8G 0x05
#define EMMC 0xEC
#define EXTENDED_PAR 0x0F //扩展分区
#define EXTENDED_8G 0x05 //
#define EMMC 0xEC //eMMC=NAND闪存+闪存控制芯片+标准接口封装
#define OTHERS 0x01 /* sdcard or umass */
#define BS_FS_TYPE_MASK 0xFFFFFF
......@@ -210,21 +227,21 @@ typedef struct _los_part_ {//分区描述符
LOS_DL_LIST list; /* linklist of partition */ //通过它挂到los_disk->head上
} los_part;
struct partition_info {
UINT8 type;
UINT64 sector_start;
UINT64 sector_count;
struct partition_info {//分区信息
UINT8 type; //分区类型,是主分区还是扩展分区
UINT64 sector_start;//开始扇区位置
UINT64 sector_count;//扇区大小
};
struct disk_divide_info {
UINT64 sector_count;
UINT32 sector_size;
UINT32 part_count;
struct disk_divide_info {//磁盘分区描述符,
UINT64 sector_count; //扇区数量
UINT32 sector_size; //扇区大小,一般是512字节
UINT32 part_count; //分区数量 需 < MAX_DIVIDE_PART_PER_DISK + MAX_PRIMARY_PART_PER_DISK
/*
* The primary partition place should be reversed and set to 0 in case all the partitions are
* logical partition (maximum 16 currently). So the maximum part number should be 4 + 16.
*/
struct partition_info part[MAX_DIVIDE_PART_PER_DISK + MAX_PRIMARY_PART_PER_DISK];
*/ //如果所有分区都是逻辑分区(目前最多16个),则主分区位置应颠倒并设置为0。所以最大分区号应该是4+16。
struct partition_info part[MAX_DIVIDE_PART_PER_DISK + MAX_PRIMARY_PART_PER_DISK];//分区数组,记录每个分区的详细情况
};
/**
......
......@@ -447,7 +447,7 @@ static INT32 GPTInfoGet(struct inode *blkDrv, CHAR *gptBuf)
return ENOERR;
}
//GPT(Globally Unique Identifier Partition Table Format),全局唯一标识符的分区表的格式
static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const CHAR *partitionBuf,
UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd)
{
......@@ -603,7 +603,7 @@ static INT32 OsEBRInfoGet(struct inode *blkDrv, const struct disk_divide_info *i
return ENOERR;
}
//给所有主分区的分区信息初始化
static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divide_info *info,
INT32 *extendedPos, INT32 *mbrCount)
{
......@@ -612,7 +612,7 @@ static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divid
INT32 extendedFlag = 0;
INT32 count = 0;
for (i = 0; i < MAX_PRIMARY_PART_PER_DISK; i++) {
for (i = 0; i < MAX_PRIMARY_PART_PER_DISK; i++) {//遍历主分区
mbrPartitionType = mbrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + (i * PAR_TABLE_SIZE)];
if (mbrPartitionType) {
info->part[i].type = mbrPartitionType;
......@@ -630,7 +630,7 @@ static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divid
return extendedFlag;
}
//给所有逻辑分区的分区信息初始化
static INT32 OsLogicalPartitionRecognition(struct inode *blkDrv, struct disk_divide_info *info,
UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
{
......@@ -1298,7 +1298,7 @@ INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
VOID *priv, INT32 diskID, VOID *info)
{
struct geometry diskInfo; //此结构提供有关块驱动程序状态的信息
struct inode *blkDriver = NULL;
struct inode *blkDriver = NULL;//块设备驱动
los_disk *disk = get_disk(diskID);
struct inode_search_s desc;//见于 ../../../../../third_party/NuttX/fs/inode/inode.h
INT32 ret;
......@@ -1576,7 +1576,7 @@ ERROR_HANDLE:
DISK_UNLOCK(&disk->disk_mutex);
return VFS_ERROR;
}
//增加一个MMC分区
INT32 add_mmc_partition(struct disk_divide_info *info, size_t sectorStart, size_t sectorCount)
{
UINT32 index, i;
......
......@@ -65,7 +65,7 @@ mtd_partition *GetSpinorPartitionHead(VOID)
//初始化 norflash 参数
static VOID MtdNorParamAssign(partition_param *spinorParam, const struct MtdDev *spinorMtd)
{
LOS_ListInit(&g_spinorPartitionHead->node_info);
LOS_ListInit(&g_spinorPartitionHead->node_info);//初始化双向链表,链表用于挂其他分区,方便管理
/*
* If the user do not want to use block mtd or char mtd ,
* you can change the SPIBLK_NAME or SPICHR_NAME to NULL.
......@@ -147,7 +147,7 @@ static INT32 MtdDeinitFsparParam(const CHAR *type)
return ENOERR;
}
//分区参数检查
static INT32 AddParamCheck(UINT32 startAddr,
const partition_param *param,
UINT32 partitionNum,
......@@ -181,7 +181,7 @@ static INT32 AddParamCheck(UINT32 startAddr,
return ENOERR;
}
//注册块设备
//注册块设备,此函数之后设备将支持VFS访问
static INT32 BlockDriverRegisterOperate(mtd_partition *newNode,
const partition_param *param,
UINT32 partitionNum)
......@@ -217,7 +217,7 @@ static INT32 BlockDriverRegisterOperate(mtd_partition *newNode,
}
return ENOERR;
}
//注册字符设备
//注册字符设备,,此函数之后设备将支持VFS访问
static INT32 CharDriverRegisterOperate(mtd_partition *newNode,
const partition_param *param,
UINT32 partitionNum)
......@@ -289,7 +289,7 @@ static INT32 CharDriverUnregister(mtd_partition *node)
/*
* Attention: both startAddr and length should be aligned with block size.
* If not, the actual start address and length won't be what you expected.
*/
*/ //参数必须对齐 块大小检查
INT32 add_mtd_partition(const CHAR *type, UINT32 startAddr,
UINT32 length, UINT32 partitionNum)
{
......@@ -323,7 +323,7 @@ INT32 add_mtd_partition(const CHAR *type, UINT32 startAddr,
}
PAR_ASSIGNMENT(newNode, length, startAddr, partitionNum, param->flash_mtd, param->block_size);
//注册块设备驱动程序,支持VFS访问
ret = BlockDriverRegisterOperate(newNode, param, partitionNum);
if (ret) {
goto ERROR_OUT1;
......
......@@ -95,7 +95,7 @@ los_disk *GetMmcDisk(UINT8 type)
#endif
#ifdef LOSCFG_PLATFORM_HI3516DV300
STATIC const CHAR *AddEmmcRootfsPart(INT32 rootAddr, INT32 rootSize)
STATIC const CHAR *AddEmmcRootfsPart(INT32 rootAddr, INT32 rootSize)//在EMMC介质上增加一个根文件系统分区
{
INT32 ret;
......@@ -106,7 +106,7 @@ STATIC const CHAR *AddEmmcRootfsPart(INT32 rootAddr, INT32 rootSize)
return NULL;
}
struct disk_divide_info *emmc = get_emmc();
struct disk_divide_info *emmc = get_emmc();//获取emmc,将完善其分区信息
ret = add_mmc_partition(emmc, rootAddr / EMMC_SEC_SIZE, rootSize / EMMC_SEC_SIZE);
if (ret != LOS_OK) {
PRINT_ERR("Failed to add mmc root partition!\n");
......@@ -138,7 +138,7 @@ STATIC const CHAR *AddEmmcRootfsPart(INT32 rootAddr, INT32 rootSize)
}
}
#endif
//系统可以有多个根文件系统并存,可放在 USB,SD卡,flash上
STATIC const CHAR *GetDevName(const CHAR *rootType, INT32 rootAddr, INT32 rootSize)
{
const CHAR *rootDev = NULL;
......@@ -439,7 +439,7 @@ STATIC INT32 OsMountRootfsAndUserfs(const CHAR *rootDev, const CHAR *fsType)
}
}
}
OsMountUserdata(fsType);
OsMountUserdata(fsType);//挂载用户数据
#endif
} else { //非 vfat格式
ret = mount(rootDev, "/", fsType, MS_RDONLY, NULL);
......
......@@ -31,6 +31,27 @@
#ifndef _LOS_ROOTFS_H
#define _LOS_ROOTFS_H
/**********************************************
rootfs之所以存在,是因为需要在VFS机制下给系统提供最原始的挂载点
https://blog.csdn.net/tankai19880619/article/details/12093239
与linux一样,在鸿蒙内核一切皆文件:普通文件、目录、字符设备、块设备、套接字
等都以文件被对待;他们具体的类型及其操作不同,但需要向上层提供统一的操作接口。
虚拟文件系统VFS就是内核中的一个软件层,向上给用户空间程序提供文件系统操作接口;
向下允许不同的文件系统共存。所以,所有实际文件系统都必须实现VFS的结构封装。
系统中任何文件系统的挂载必须满足两个条件:挂载点和文件系统。
rootfs是基于内存的文件系统,所有操作都在内存中完成;也没有实际的存储设备,所以不需要设备驱动程序的参与.
只在启动阶段使用rootfs文件系统,当磁盘驱动程序和磁盘文件系统成功加载后,系统会将系统根目录从rootfs切换
到磁盘上的具体文件系统。
rootfs的特点:
1.它是系统自己创建并加载的第一个文件系统;
2.该文件系统的挂载点就是它自己的根目录项对象;
3.该文件系统仅仅存在于内存中。
VFS是一种机制、是每一种文件系统都必须按照这个机制去实现的一种规范;
而rootfs仅仅是符合VFS规范的而且又具有如上3个特点的一个文件系统。
**********************************************/
#define BYTES_PER_MBYTE 0x100000 //1M = 1024 * 1024
#define BYTES_PER_KBYTE 0x400 //1K = 1024
......@@ -39,21 +60,21 @@
#define COMMAND_LINE_SIZE 1024
#ifdef LOSCFG_PLATFORM_HI3518EV300
#define ROOTFS_ROOT_TYPE "flash" //根文件系统存放在哪种设备上,这里是flash
#define ROOTFS_FS_TYPE "jffs2" //3518 平台使用根文件系统的类型
#define ROOTFS_ROOT_TYPE "flash" //根文件系统存放在nor flash上
#define ROOTFS_FS_TYPE "jffs2" //Journalling Flash File System(闪存设备日志型文件系统,JFFS),一般用于nor flash的文件系统
#endif
#ifdef LOSCFG_PLATFORM_HI3516DV300
#define ROOTFS_ROOT_TYPE "emmc" //eMMC=NAND闪存+闪存控制芯片+标准接口封装 https://blog.csdn.net/xjw1874/article/details/81505967
#define ROOTFS_FS_TYPE "vfat" //3516 平台使用根文件系统的类型
#define ROOTFS_FS_TYPE "vfat" //即FAT32,采用32位的文件分配表,支持最大分区128GB,最大文件4GB
#endif
#ifdef LOSCFG_TEE_ENABLE
#ifdef LOSCFG_TEE_ENABLE //TEE(Trust Execution Environment),可信执行环境,和REE(Rich Execution Environment)相对应
#define ROOTFS_FLASH_ADDR 0x600000
#define ROOTFS_FLASH_SIZE 0x800000
#else
#define ROOTFS_FLASH_ADDR 0x400000
#define ROOTFS_FLASH_SIZE 0xa00000
#define ROOTFS_FLASH_ADDR 0x400000 //根文件系统地址
#define ROOTFS_FLASH_SIZE 0xa00000 //根文件系统大小 10M
#endif
#define FLASH_TYPE "spinor" //flash类型
......
......@@ -205,7 +205,7 @@ STATIC const struct file_operations_vfs g_serialDevOps = {
SerialRead, /* read */
SerialWrite,
NULL,
SerialIoctl,
SerialIoctl,//ioctl主要用read/write很难定义的情况,比如 光盘播放的快进,倒退等,ioctl命令和设备紧耦合.
NULL,
#ifndef CONFIG_DISABLE_POLL
SerialPoll,
......
......@@ -83,9 +83,9 @@ LOSCFG_FS_FAT_CHINESE=y #区域设置和命名空间配置
LOSCFG_FS_FAT_VIRTUAL_PARTITION=y
LOSCFG_FS_FAT_VOLUMES=16
LOSCFG_FS_FAT_DISK=y #
LOSCFG_FS_RAMFS=y
LOSCFG_FS_RAMFS=y #内存文件系统
LOSCFG_FS_NFS=y #网络文件系统,英文Network File System(NFS)
LOSCFG_FS_PROC=y
LOSCFG_FS_PROC=y #一个伪文件系统,提供了访问内核数据的方法 /proc
LOSCFG_FS_JFFS=y #Journalling Flash File System(闪存设备日志型文件系统,JFFS),一般用于nor flash的文件系统
#
......
git add -A
git commit -m '1.zzz目录添加编译hi3516dv300后自动生成的宏文件 2.内核有哪些块/字符设备,是如何实现的?
git commit -m '根文件系统rootfs 部分注释
搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册