mount函数分析
来源:互联网 发布:北大开放数据 编辑:程序博客网 时间:2024/05/08 17:53
首先判断挂载的类型是否符和已经定义好的文件系统类型。里面的实现方式是比较对应字符串是否相同。
mount_findfs(g_bdfsmap, filesystemtype);
其中g_bdfsmap就是已经定义好的文件系统类型。
static const struct fsmap_t g_bdfsmap[] = { #ifdef CONFIG_FS_FAT { "vfat", &fat_operations }, #endif #ifdef CONFIG_FS_ROMFS { "romfs", &romfs_operations }, #endif #ifdef CONFIG_FS_SMARTFS { "smartfs", &smartfs_operations }, #endif { NULL, NULL }, };
根据文件路径找到相应的inode节点。//如何寻找的实现方式说明已经在之前的stat系统调用文章中说明。
接下来最核心的函数是
mops->bind(blkdrvr_inode, data, &fshandle);该bind方法,该方法首先分配一个绑定的结构体空间
fs = (struct fat_mountpt_s *)kmm_zalloc(sizeof(struct fat_mountpt_s));最终该结构体内容要被各种fat相关参数填充。
接下来就是fat文件系统挂载的核心函数
int fat_mount(struct fat_mountpt_s *fs, bool writeable)一路跟踪下来,该函数中有关读写的都比较重要,我们先来看一下读函数(主要是读取一些扇区的信息)
int fat_hwread(struct fat_mountpt_s *fs, uint8_t *buffer, off_t sector, unsigned int nsectors)该函数主要是调用已经注册好的回调函数
inode->u.i_bops->read(inode, buffer,sector, nsectors);而该回调函数又在注册块设备驱动的时候被赋值
int register_blockdriver(FAR const char *path, FAR const struct block_operations *bops, mode_t mode, FAR void *priv){ <span style="white-space:pre"></span>node->u.i_bops = bops; #ifdef CONFIG_FILE_MODE node->i_mode = mode; #endif node->i_private = priv;}
sd卡注册的块设备驱动应该是在相关mmcsd相关源文件中,而usb注册的块设备在相关usbhost相关源文件中。
首先介绍的sd的注册过程。
int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev) { FAR struct mmcsd_state_s *priv; char devname[16]; int ret = -ENOMEM; fvdbg("minor: %d\n", minor); /* Sanity check */ #ifdef CONFIG_DEBUG if (minor < 0 || minor > 255 || !dev) { return -EINVAL; } #endif /* Allocate a MMC/SD state structure */ priv = (FAR struct mmcsd_state_s *)kmm_malloc(sizeof(struct mmcsd_state_s)); if (priv) { /* Initialize the MMC/SD state structure */ memset(priv, 0, sizeof(struct mmcsd_state_s)); sem_init(&priv->sem, 0, 1); /* Bind the MMCSD driver to the MMCSD state structure */ priv->dev = dev; priv->dev_id = minor; /* Initialize the hardware associated with the slot */ ret = mmcsd_hwinitialize(priv); /* Was the slot initialized successfully? */ if (ret != OK) { if (ret == SDIO_OK) { return OK; } /* No... But the error ENODEV is returned if hardware initialization * succeeded but no card is inserted in the slot. In this case, the * no error occurred, but the driver is still not ready. */ if (ret == -ENODEV) { /* No card in the slot (or if there is, we could not recognize * it).. Setup to receive the media inserted event */ SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED); fvdbg("MMC/SD slot is empty\n"); } else { /* Some other non-recoverable bad thing happened */ fdbg("ERROR: Failed to initialize MMC/SD slot: %d\n", ret); goto errout_with_alloc; } } #if defined(CONFIG_DRVR_WRITEBUFFER) || defined(CONFIG_DRVR_READAHEAD) /* Initialize buffering */ #warning "Missing setup of rwbuffer" ret = rwb_initialize(&priv->rwbuffer); if (ret < 0) { fdbg("ERROR: Buffer setup failed: %d\n", ret); goto errout_with_hwinit; } #endif /* Create a MMCSD device name */ snprintf(devname, 16, "/dev/mmcsd%d", minor); /* Inode private data is a reference to the MMCSD state structure */ ret = register_blockdriver(devname, &g_bops, 0, priv);
相关回调函数方法是
static const struct block_operations g_bops = { mmcsd_open, /* open */ mmcsd_close, /* close */ mmcsd_read, /* read */ #ifdef CONFIG_FS_WRITABLE mmcsd_write, /* write */ #else NULL, /* write */ #endif mmcsd_geometry, /* geometry */ mmcsd_ioctl /* ioctl */ };
而在上面用到的read方法:
static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,size_t startsector, unsigned int nsectors);
#define SDIO_LOCK(dev,state) ((dev)->lock(dev,state))#define SDIO_RESET(dev) ((dev)->reset(dev))#define SDIO_STATUS(dev) ((dev)->status(dev))#define SDIO_WIDEBUS(dev,wide) ((dev)->widebus(dev,wide))#define SDIO_CLOCK(dev,rate) ((dev)->clock(dev,rate))#define SDIO_ATTACH(dev) ((dev)->attach(dev))#define SDIO_SENDCMD(dev,cmd,arg) ((dev)->sendcmd(dev,cmd,arg))#define SDIO_RECVSETUP(dev,buffer,nbytes) ((dev)->recvsetup(dev,buffer,nbytes))#define SDIO_SENDSETUP(dev,buffer,nbytes) ((dev)->sendsetup(dev,buffer,nbytes))#define SDIO_CANCEL(dev) ((dev)->cancel(dev))#define SDIO_WAITRESPONSE(dev,cmd) ((dev)->waitresponse(dev,cmd))#define SDIO_RECVR1(dev,cmd,R1) ((dev)->recvR1(dev,cmd,R1)) /* 48-bit */#define SDIO_RECVR2(dev,cmd,R2) ((dev)->recvR2(dev,cmd,R2)) /* 136-bit */#define SDIO_RECVR3(dev,cmd,R3) ((dev)->recvR3(dev,cmd,R3)) /* 48-bit */#define SDIO_RECVR4(dev,cmd,R4) ((dev)->recvR4(dev,cmd,R4)) /* 48-bit */#define SDIO_RECVR5(dev,cmd,R5) ((dev)->recvR5(dev,cmd,R5)) /* 48-bit */#define SDIO_RECVR6(dev,cmd,R6) ((dev)->recvR6(dev,cmd,R6)) /* 48-bit */#define SDIO_RECVR7(dev,cmd,R7) ((dev)->recvR7(dev,cmd,R7)) /* 48-bit */#define SDIO_WAITENABLE(dev,eventset) ((dev)->waitenable(dev,eventset))#define SDIO_EVENTWAIT(dev,timeout) ((dev)->eventwait(dev,timeout))#define SDIO_CALLBACKENABLE(dev,eventset) ((dev)->callbackenable(dev,eventset))
{ 375 #ifdef CONFIG_SDIO_MUXBUS 376 .lock = xxx_lock, 377 #endif 378 .reset = xxx_reset, 379 .status = xxx_status, 380 .widebus = xxx_widebus, 381 .clock = xxx_clock, 382 .attach = xxx_attach, 383 .sendcmd = xxx_sendcmd, 384 #ifdef CONFIG_SDIO_BLOCKSETUP 385 .blocksetup = xxx_blocksetup, 386 #endif 387 .recvsetup = xxx_recvsetup, 388 .sendsetup = xxx_sendsetup, 389 .cancel = xxx_cancel, 390 .waitresponse = xxx_waitresponse, 391 .recvR1 = xxx_recvshortcrc, 392 .recvR2 = xxx_recvlong, 393 .recvR3 = xxx_recvshortcrc, 394 .recvR4 = xxx_recvshortcrc, 395 .recvR5 = xxx_recvshortcrc, 396 .recvR6 = xxx_recvshortcrc, 397 .recvR7 = xxx_recvshortcrc, 398 .waitenable = xxx_waitenable, 399 .eventwait = xxx_eventwait, 400 .callbackenable = xxx_callbackenable, 401 .registercallback = xxx_registercallback, 402 #ifdef CONFIG_SDIO_DMA 403 .dmasupported = xxx_dmasupported, 404 #ifdef CONFIG_SDIO_PREFLIGHT 405 .dmapreflight = xxx_dmapreflight, 406 #endif 407 .dmarecvsetup = xxx_dmarecvsetup, 408 .dmasendsetup = xxx_dmasendsetup, 409 #endif 410 },
最终这些回调函数会被上面的框架所调用,而实际上这些函数都是对寄存器的读写操作。
注意mmc中有两种模式一种是sd,一种是sdio。前一种主要是为sd卡,后者主要是为wifi,所以sdio也有相关的一系列回调函数。
接下来是usb挂载文件系统:
usb最初的注册函数是usbhost_msc_initialize。这个接口是usb框架提供的接口。
于是usbhost_registerclass(&g_storage);
最后调用注册块设备注册的函数register_blockdriver是 int usbhost_initvolume(FAR struct usbhost_state_s *priv);当然在这之前会分配相应的结构体空间。而在执行这一函数的前提是在connect的时候执行的。问题是谁去出发这个connect的条件,在查看nuttx源码的时候没有找到???
与mmc不相同的是usb首先调用相关框架的函数,然后再调用注册的回调函数,但是整体上都是相同的,跟着框架的逻辑走,最后调用回调函数,具体这两者的驱动的通信方式是怎么样的,那还需要我好好研究再做总结。
mount这个一个系统调用涉及了很多的方面东西(文件系统,块设备驱动)。
- ubifs mount 函数分析
- mount函数分析
- VFS之mount函数分析
- mount 函数
- Linux mount代码分析
- mount 流程分析
- Linux命令分析: mount
- mount/umount函数
- 文件系统的mount参数分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- Android SDCard Mount 流程分析
- C++函数模板 模板实例化、具体化
- 【记录】UART
- PHP的两个特性导致waf绕过注入(有趣的知识点)
- fragment中嵌套viewpager,vierpager中有多个fragment,不显示 .
- rand与srand:随机数的生成
- mount函数分析
- Android系统应用---SystemUI之二:Statusbar显示流程以及系统状态图标更新分析
- [AngularJS面面观] 11. scope事件机制 - 事件系统在Angular框架中的应用
- 使用DBCP连接池时出现MySql 8小时断开连接的解决方法
- Java内存区域划分、内存分配原理
- java学习——静态方法和非静态方法
- 用python实现Kaggle的Titanic数据分析例子
- cocos2dx-CCControlButton源码分析
- 图论专题总结