>>>>一)驱动注册open函数都干了些什么?
register_chrdev->cdev_add->kobj_map
file:fs/char_dev.c
intregister_chrdev(unsignedintmajor,constchar*name,conststructfile_operations*fops{
structchar_device_struct*cd;structcdev*cdev;char*s;
interr=-ENOMEM;
cd=__register_chrdev_region(major,0,256,name;if(IS_ERR(cd
returnPTR_ERR(cd;
cdev=cdev_alloc(;if(!cdevgotoout2;
cdev->owner=fops->owner;
cdev->ops=fops;//注意,在后面的chrdev_open会从cdev再得到fops...}
file:fs/char_dev.c
intcdev_add(structcdev*p,dev_tdev,unsignedcount{
p->dev=dev;p->count=count;
returnkobj_map(cdev_map,dev,count,NULL,exact_match,exact_lock,p;}
file:fs/char_dev.c
staticstructkobject*exact_match(dev_tdev,int*part,void*data{
structcdev*p=data;return&p->kobj;}
file:drivers/base/map.c
intkobj_map(structkobj_map*domain,dev_tdev,unsignedlongrange,structmodule*module,kobj_probe_t*probe,int(*lock(dev_t,void*,void*data{
unsignedn=MAJOR(dev+range-1-MAJOR(dev+1;unsignedindex=MAJOR(dev;
>>>>unsignedi;structprobe*p;
if(n>255n=255;
p=kmalloc(sizeof(structprobe*n,GFP_KERNEL;
if(p==NULLreturn-ENOMEM;
for(i=0;ip->owner=module;
p->get=probe;//此处其实就是exact_matchp->lock=lock;p->dev=dev;p->range=range;p->data=data;}
mutex_lock(domain->lock;
for(i=0,p-=n;i
structprobe**s=&domain->probes[index%255];while(*s&&(*s->ranges=&(*s->next;p->next=*s;*s=p;}
mutex_unlock(domain->lock;return0;}
【参考UnderstandingTheLinuxKernel13.5.CharacterDeviceDrivers】
Thedevicedrivermodeldefinesakobjectmappingdomainforthecharacterdevices,whichisrepresentedbyadescriptoroftypekobj_mapandisreferencedbythecdev_mapglobalvariable.Thekobj_mapdescriptorincludesahashtableof255entriesindexedbythemajornumberoftheintervals.Thehashtablestoresobjectsoftypeprobe,oneforeachregisteredrangeofmajorandminornumbers,whosefieldsarelistedinTable13-9.
Whenthekobj_map(functionisinvoked,thespecifiedintervalofdevicenumbersisaddedtothehashtable.Thedatafieldofthecorrespondingprobeobjectpointstothecdevdescriptorofthedevicedriver.Thevalueofthisfieldispassedtothegetandlockmethodswhentheyareexecuted.Inthiscase,thegetmethodisimplementedbyashortfunctionthatreturnstheaddressofthekobjectembeddedinthecdevdescriptor;thelockmethod,instead,essentiallyincreasesthereferencecounterintheembeddedkobject.
Thekobj_lookup(functionreceivesasinputparametersakobjectmappingdomainandadevicenumber;itsearchesthehashtableandreturnstheaddressofthekobjectoftheowneroftheintervalincludingthenumber,ifitwasfound.Whenappliedtothemappingdomainofthecharacterdevices,thefunctionreturns
>>>>theaddressofthekobjectembeddedinthecdevdescriptorofthedevicedriverthatownstheintervalofdevicenumbers.
二)从系统调用往内核走,看当初驱动里注册的file_operations里的open函数怎么被调用的sys_open->do_sys_open->do_filp_open->nameidata_to_filp->__dentry_open
问题是1)__dentry_open如何找到chrdev_open?
2)最终又是如何调用file_operations里的在驱动里面注册的open函数的呢?staticstructfile*__dentry_open(structdentry*dentry,structvfsmount*mnt,intflags,structfile*f,
int(*open(structinode*,structfile*{
structinode*inode;interror;
f->f_flags=flags;
f->f_mode=((flags+1&O_ACCMODE|FMODE_LSEEK|FMODE_PREAD|FMODE_PWRITE;inode=dentry->d_inode;
if(f->f_mode&FMODE_WRITE{
error=__get_file_write_access(inode,mnt;if(error
gotocleanup_file;
if(!special_file(inode->i_modefile_take_write(f;}
f->f_mapping=inode->i_mapping;f->f_path.dentry=dentry;f->f_path.mnt=mnt;f->f_pos=0;
f->f_op=fops_get(inode->i_fop;//此处获得def_chr_fopsfile_move(f,&inode->i_sb->s_files;
error=security_dentry_open(f;if(error
gotocleanup_all;
if(!open&&f->f_op
open=f->f_op->open;//此处调用