⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 037_fs_devices_c.html

📁 重读linux 2.4.2o所写的笔记
💻 HTML
字号:
  <html lang="zh-CN" xmlns:gdoc="">  <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <style type="text/css">/* default css */table {  font-size: 1em;  line-height: inherit;}div, address, ol, ul, li, option, select {   margin-top: 0px;  margin-bottom: 0px;}p {  margin: 0px;}body {        margin: 0px;          padding: 0px;    font-family: Verdana, sans-serif;  font-size: 10pt;  background-color: #ffffff;}h6 { font-size: 10pt }h5 { font-size: 11pt }h4 { font-size: 12pt }h3 { font-size: 13pt }h2 { font-size: 14pt }h1 { font-size: 16pt }blockquote {padding: 10px; border: 1px #DDD dashed }a img {border: 0}div.google_header, div.google_footer {  position: relative;  margin-top: 1em;  margin-bottom: 1em;}/* end default css */  /* default print css */    @media print {    body {       padding: 0;       margin: 0;     }    div.google_header, div.google_footer {      display: block;      min-height: 0;      border: none;    }    div.google_header {      flow: static(header);    }    /* used to insert page numbers */    div.google_header::before, div.google_footer::before {      position: absolute;      top: 0;    }    div.google_footer {      flow: static(footer);    }    /* always consider this element at the start of the doc */    div#google_footer {      flow: static(footer, start);    }    span.google_pagenumber {      content: counter(page);    }    span.google_pagecount {      content: counter(pages);    }  }  @page {    @top {      content: flow(header);    }    @bottom {      content: flow(footer);    }  }  /* end default print css */ /* custom css *//* end custom css */  /* ui edited css */    body {    font-family: Verdana;        font-size: 10.0pt;    line-height: normal;    background-color: #ffffff;  }    .documentBG {    background-color: #ffffff;  }  /* end ui edited css */</style>   </head>  <body  revision="dcbsxfpf_21gsc4r6:67">      <table align=center cellpadding=0 cellspacing=0 height=5716 width=800>
  <tbody>
  <tr>
    <td height=5716 valign=top width=800>
      <pre><br>2007-11-28  <br>            by heyl<br><br>/*<br> *  linux/fs/devices.c<br> *<br> * (C) 1993 Matthias Urlichs -- <font color=#3333ff><b>collected common code and tables.</b></font><br> * <br> *  Copyright (C) 1991, 1992  Linus Torvalds<br> *<br> *  Added kerneld support: Jacques Gelinas and Bjorn Ekwall<br> *  (changed to kmod)<br> */<br> 看到这儿注释,不难理解这里为啥不搭边...<br><br>这里是char dev的天下?想起了block_dev 的相关结构,倒是和这个有点类似.<br>struct <font color=#333399><b>device_struct</b></font> {<br>	const char * name;<br>	struct <font color=#3333ff>file_operations</font> * fops;<br>};<br>和blkdev是不同的,存储的是name和fops. <br>static struct {<br>	const char *name;<br>	struct block_device_operations *bdops;<br>} blkdevs[MAX_BLKDEV];<br><br>static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;<br>static struct device_struct <font color=#000099><b>chrdevs</b></font>[MAX_CHRDEV];<br><br>int <font color=#000099><b>get_device_list</b></font>(char * page) : 获取char dev 和block dev的列表,极尽简单.<br><br><font color=#009900>static</font> struct file_operations * <font color=#000099><b>get_chrfops</b></font>(unsigned int major, unsigned int minor) : 从char获取file ops, char dev<br>直接面对file,真是素面朝天的做法,比起block dev的七拐八拐直接多了.这个函数无非就是如果是tty照顾到了kmod. 参考major.h,里边是<br>所有已知设备的major number.<br><br>chardev的注册函数,真是直白,我们需要这样子的代码.<br>int <font color=#000099>register_chrdev</font>(unsigned int major, const char * name, struct file_operations *fops)<br>int <font color=#000099>unregister_chrdev</font>(unsigned int major, const char * name)<br><br><br>/*<br> * Called every time a character special file is opened<br> */<br>int <font color=#000099><b>chrdev_open</b></font>(struct inode * inode, struct file * filp)<br>{<br>	int ret = -ENODEV;<br><br>	filp-&gt;f_op = <font color=#006600><b>get_chrfops</b></font>(MAJOR(inode-&gt;i_rdev), MINOR(inode-&gt;i_rdev));<br>	if (filp-&gt;f_op) {<br>		ret = 0;<br>		if (filp-&gt;f_op-&gt;open != NULL) {<br>			lock_kernel();<br>			ret = filp-&gt;<font color=#006600><b>f_op-&gt;open</b></font>(inode,filp);<br>			unlock_kernel();<br>		}<br>	}<br>	return ret;<br>}<br><br>/*<br> * Dummy default file-operations: the only thing this does<br> * is contain the open that then fills in the correct operations<br> * depending on the special file...<br> */<br>static <font color=#cc0000>struct</font> file_operations <font color=#000099><b>def_chr_fops</b></font> = {<br>	open:		<font color=#006600>chrdev_open</font>,<br>};<br><br>def注册到inode的i_fops,<br>通denty_open这个file ops转移到filep-&gt;f_ops.<br>struct file *<font color=#000099><b>dentry_open</b></font>(struct dentry *dentry, struct vfsmount *mnt, int flags)<br>{<br>	struct file * f;<br>        .....<br>	<font color=#006600>f-&gt;f_op = fops_get(inode-&gt;i_fop);</font><br>}<br><br>接下来就是一个很知名的函数了:<br>void <font color=#000099><b>init_special_inode</b></font>(struct inode *inode, umode_t mode, int rdev)<br>{<br>	inode-&gt;i_mode = mode;<br>	if (S_ISCHR(mode)) {<br>		<font color=#006600><b>inode-&gt;i_fop</b></font> = &amp;def_chr_fops;<br>		<b>inode-&gt;i_rdev</b> = to_kdev_t(rdev);<br>	} else if (S_ISBLK(mode)) { /*block dev 有两个dev和之对应*/<br>		<font color=#006600><b>inode-&gt;i_fop</b></font> = &amp;def_blk_fops;<br>		<b>inode-&gt;i_rdev</b> = to_kdev_t(rdev); <font color=#3333ff>/*kdev,一个int, 系统中所有dev的统一handler*/</font><br>		<b>inode-&gt;i_bdev</b> = bdget(rdev);<font color=#3333ff> /* block_device pointer */</font><br>	} else if (S_ISFIFO(mode))<br>		inode-&gt;i_fop = &amp;def_fifo_fops;<br>	else if (S_ISSOCK(mode))<br>		<b>inode-&gt;i_fop</b> = &amp;bad_sock_fops;<font color=#3333ff> /*sock使用另外的soket标准接口和文件系统相区别*/</font><br>	else<br>		printk(KERN_DEBUG "init_special_inode: bogus imode (%o)\n", mode);<br>}<br><br><font color=#3333ff>搜索init_special_inode的调用者,我们知道不是所有的文件系统都支持设备文件的, 比如vfat就免谈了.</font><br><br><br>剩下的函数看看名字好了.<br>const char * kdevname(kdev_t dev)<br>const char * cdevname(kdev_t dev)<br> static int sock_no_open(struct inode *irrelevant, struct file *dontcare)<br>static struct file_operations bad_sock_fops = {<br>	open:		sock_no_open<br>};<br><br>不想我们从这里得窥char device的一角, chardev 直接实现一个file ops给文件系统,倒是省心了不少. 比block dev干净许多啊.<br><br></pre>
    </td>
  </tr>
  </tbody>
</table></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -