°æÈ¨ © 2000, 2001, 2002, 2003, 2004, 2005, 2006 The FreeBSD Documentation Project
°æÈ¨ © 2004, 2005, 2006 FreeBSD ÖÐÎļƻ®
¡¡¡¡»¶ÓÄúÔĶÁ¡¶FreeBSDϵͳ½á¹¹Êֲᡷ¡£ Õâ±¾ÊֲỹÔÚ²»¶ÏÓÉÐí¶àÈ˼ÌÐøÊéд¡£ Ðí¶àÕ½ڻ¹Êǿհף¬ÓеÄÕÂ½ÚØ½´ý¸üС£ Èç¹ûÄú¶ÔÕâ¸öÏîÄ¿¸ÐÐËȤ²¢Ô¸ÒâÓÐËù¹±Ï×£¬Ç뷢Пø FreeBSD Îĵµ¼Æ»®ÓʼþÁÐ±í¡£
¡¡¡¡ ±¾ÎĵµµÄ×îÐÂÓ¢ÎÄÔʼ°æ±¾¿É´Ó FreeBSD Web Õ¾µã »ñµÃ£¬ ÓÉ FreeBSD ÖÐÎļƻ® ά»¤µÄ×îÐÂÒë±¾¿ÉÒÔÔÚ FreeBSD ÖÐÎļƻ® ¿ìÕÕ Web Õ¾µã ºÍ FreeBSD ÖÐÎļƻ® Îĵµ¿ìÕÕ ´¦»ñµÃ£¬ ÕâÒ»Òë±¾»á²»¶ÏÏòÖ÷վͬ²½¡£ ´ËÍ⣬ ÄúÒ²¿ÉÒÔ´Ó FreeBSD FTP ·þÎñÆ÷ »òÖÚ¶àµÄ ¾µÏñÕ¾µã µÃµ½Õâ·ÝÎĵµµÄ¸÷ÖÖÆäËû¸ñʽÒÔ¼°Ñ¹ËõÐÎʽµÄ°æ±¾¡£
FreeBSDÊÇFreeBSD»ù½ð»áµÄ×¢²áÉ̱ꡣ
UNIXÊÇOpen GroupÔÚÃÀ¹úºÍÆäËü¹ú¼ÒµÄ×¢²áÉ̱ꡣ
Sun, Sun Microsystems, SunOS, Solaris, Java, JDK, ÒÔ¼° OpenJDK ÊÇ Sun Microsystems, Inc. ÔÚÃÀ¹úºÍÆäËü¹ú¼ÒµÄÉ̱ê»ò×¢²áÉ̱ꡣ
Apple and QuickTimeÊÇApple Computer, Inc.µÄÉ̱꣬ ÔÚÃÀ¹úºÍÆäËü¹ú¼Ò×¢²á¡£
Macromedia and FlashÊÇMacromedia, Inc. ÔÚÃÀ¹úºÍ/»òÆäËü¹ú¼ÒµÄÉ̱ê»ò×¢²áÉ̱ꡣ
Microsoft, Windows, and Windows MediaÊÇMicrosoft Corporation ÔÚÃÀ¹úºÍ/»òÆäËü¹ú¼ÒµÄÉ̱ê»ò×¢²áÉ̱ꡣ
PartitionMagicÊÇPowerQuest CorporationÔÚÃÀ¹úºÍ/»òÆäËü¹ú¼ÒµÄ×¢²áÉ̱ꡣ
Ðí¶àÖÆÔìÉ̺;ÏúÉÌʹÓÃһЩ³ÆÎªÉ̱êµÄͼ°¸»òÎÄ×ÖÉè¼ÆÀ´ÕÃÏÔ×Ô¼ºµÄ²úÆ·¡£ ±¾ÎĵµÖгöÏֵģ¬ Ϊ FreeBSD Project ËùÖªÏþµÄÉ̱꣬ºóÃæ½«ÒÔ '"' »ò '®' ·ûºÅÀ´±ê×¢¡£
ÖØÒª: ±¾ÎÄÖÐÐí¿ÉÖ¤µÄ·Ç¹Ù·½ÖÐÎÄ·Òë½ö¹©²Î¿¼£¬ ²»×÷ΪÅж¨ÈκÎÔðÈεÄÒÀ¾Ý¡£ÈçÓëÓ¢ÎÄÔÎÄÓгöÈ룬ÔòÒÔÓ¢ÎÄÔÎÄΪ׼¡£
ÔÚÂú×ãÏÂÁÐÐí¿ÉÌõ¼þµÄǰÌáÏ£¬ ÔÊÐíÔÙ·Ö·¢»òÒÔÔ´´úÂë (SGML DocBook) »ò ¡°±àÒ롱 (SGML, HTML, PDF, PostScript, RTF µÈ) µÄ¾¹ýÐ޸ĻòδÐ޸ĵÄÐÎʽ£º
ÔÙ·Ö·¢Ô´´úÂë (SGML DocBook) ±ØÐë²»¼ÓÐ޸ĵı£ÁôÉÏÊö°æÈ¨¸æÊ¾¡¢ ±¾Ìõ¼þÇåµ¥ºÍÏÂÊöÆúȨÊé×÷Ϊ¸ÃÎļþµÄ×îÏÈÈô¸ÉÐС£
ÔÙ·Ö·¢±àÒëµÄÐÎʽ (ת»»ÎªÆäËüDTD¡¢ PDF¡¢ PostScript¡¢ RTF »òÆäËüÐÎʽ)£¬ ±ØÐ뽫ÉÏÊö°æÈ¨¸æÊ¾¡¢±¾Ìõ¼þÇåµ¥ºÍÏÂÊöÆúȨÊ鏴֯µ½Óë·Ö·¢Æ·Ò»Í¬ÌṩµÄÎļþ£¬ ÒÔ¼°ÆäËü²ÄÁÏÖС£
ÖØÒª: ±¾ÎĵµÓÉ FREEBSD DOCUMENTATION PROJECT ¡°°´ÏÖ×´Ìõ¼þ¡± Ìṩ£¬ ²¢ÔÚ´ËÃ÷ʾ²»ÌṩÈκÎÃ÷ʾ»ò°µÊ¾µÄ±£ÕÏ£¬ °üÀ¨µ«²»ÏÞÓÚ¶ÔÉÌÒµÊÊÏúÐÔ¡¢ ¶ÔÌØ¶¨Ä¿µÄµÄÊÊÓÃÐԵݵʾ±£ÕÏ¡£ ÈκÎÇé¿öÏ£¬ FREEBSD DOCUMENTATION PROJECT ¾ù²»¶ÔÈκÎÖ±½Ó¡¢ ¼ä½Ó¡¢ żȻ¡¢ ÌØÊâ¡¢ ³Í·£ÐԵģ¬ »ò±ØÈ»µÄËðʧ (°üÀ¨µ«²»ÏÞÓÚÌæ´úÉÌÆ·»ò·þÎñµÄ²É¹º¡¢ ʹÓᢠÊý¾Ý»òÀûÒæµÄËðʧ»òÓªÒµÖжÏ) ¸ºÔ𣬠ÎÞÂÛÊÇÈçºÎµ¼ÖµIJ¢ÒÔÈκÎÓÐÔðÈÎÂß¼µÄ£¬ ÎÞÂÛÊÇ·ñÊÇÔÚ±¾ÎĵµÊ¹ÓÃÒÔÍâÒÔÈκη½Ê½²úÉúµÄÆõÔ¼¡¢ ÑϸñÔðÈλòÊÇÃñÊÂÇÖȨÐÐΪ(°üÀ¨Êèºö»òÆäËü)Öеģ¬ ¼´Ê¹Òѱ»¸æÖª·¢Éú¸ÃËðʧµÄ¿ÉÄÜÐÔ¡£
Redistribution and use in source (SGML DocBook) and 'compiled' forms (SGML, HTML, PDF, PostScript, RTF and so forth) with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code (SGML DocBook) must retain the above copyright notice, this list of conditions and the following disclaimer as the first lines of this file unmodified.
Redistributions in compiled form (transformed to other DTDs, converted to PDF, PostScript, RTF and other formats) must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
ÖØÒª: THIS DOCUMENTATION IS PROVIDED BY THE FREEBSD DOCUMENTATION PROJECT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD DOCUMENTATION PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
¡¡¡¡ÕâÒ»ÕÂÊǶÔÒýµ¼¹ý³ÌºÍϵͳ³õʼ»¯¹ý³ÌµÄ×ÜÀÀ¡£ÕâЩ¹ý³ÌʼÓÚBIOS(¹Ì¼þ)POST, Ö±µ½µÚÒ»¸öÓû§½ø³Ì½¨Á¢¡£ÓÉÓÚϵͳÆô¶¯µÄ×î³õ²½ÖèÊÇÓëÓ²¼þ½á¹¹Ïà¹ØµÄ¡¢ÊǽôÅäºÏµÄ£¬ ÕâÀïÓÃIA-32(Intel Architecture 32bit)½á¹¹×÷ΪÀý×Ó¡£
¡¡¡¡Ò»Ì¨ÔËÐÐFreeBSDµÄ¼ÆËã»úÓжàÖÖÒýµ¼·½·¨¡£ÕâÀïÌÖÂÛÆäÖÐ×îͨ³£µÄ·½·¨£¬ Ò²¾ÍÊÇ´Ó°²×°Á˲Ù×÷ϵͳµÄÓ²ÅÌÉÏÒýµ¼¡£Òýµ¼¹ý³Ì·Ö¼¸²½Íê³É:
BIOS POST
boot0½×¶Î
boot2½×¶Î
loader½×¶Î
Äں˳õʼ»¯
¡¡¡¡boot0ºÍboot2½×¶ÎÔÚÊÖ²á boot(8)Öб»³ÆÎªbootstrap stages 1 and 2£¬ ÊÇFreeBSDµÄ3½×¶ÎÒýµ¼¹ý³ÌµÄ¿ªÊ¼¡£ÔÚÿһ½×¶Î¶¼Óи÷ÖÖ¸÷ÑùµÄÐÅÏ¢ÏÔʾÔÚÆÁÄ»ÉÏ£¬ Äã¿ÉÒԲο¼Ï±íʶ±ð³öÕâЩ²½Öè¡£Çë×¢Òâʵ¼ÊµÄÏÔʾÄÚÈÝ¿ÉÄÜËæ»úÆ÷µÄ²»Í¬¶øÓÐÒ»Ð©Çø±ð:
ÊÓ²»Í¬»úÆ÷¶ø¶¨ |
BIOS(¹Ì¼þ)ÏûÏ¢ |
F1 FreeBSD F2 BSD F5 Disk 2 |
boot0 |
>>FreeBSD/i386 BOOT Default: 1:ad(1,a)/boot/loader boot: |
boot2a |
BTX loader 1.0 BTX version is 1.01 BIOS drive A: is disk0 BIOS drive C: is disk1 BIOS 639kB/64512kB available memory FreeBSD/i386 bootstrap loader, Revision 0.8 Console internal video/keyboard (jkh@bento.freebsd.org, Mon Nov 20 11:41:23 GMT 2000) /kernel text=0x1234 data=0x2345 syms=[0x4+0x3456] Hit [Enter] to boot immediately, or any other key for command prompt Booting [kernel] in 9 seconds..._ |
loader |
Copyright (c) 1992-2002 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD 4.6-RC #0: Sat May 4 22:49:02 GMT 2002 devnull@kukas:/usr/obj/usr/src/sys/DEVNULL Timecounter "i8254" frequency 1193182 Hz |
ÄÚºË |
±í×¢: a. ÕâÖÖÌáʾ½öÔÚboot0½×¶ÎÓû§Ñ¡Ôñ²Ù×÷ϵͳºó ÈÔ°´×¡¼üÅÌÉÏijһ¼üʱ²Å³öÏÖ¡£ |
¡¡¡¡µ±PC¼Óµçºó£¬´¦ÀíÆ÷µÄ¼Ä´æÆ÷±»ÉèÎªÄ³Ð©ÌØ¶¨Öµ¡£ÔÚÕâЩ¼Ä´æÆ÷ÖУ¬ Ö¸ÁîÖ¸Õë¼Ä´æÆ÷±»ÉèΪ32λֵ0xfffffff0¡£ Ö¸ÁîÖ¸Õë¼Ä´æÆ÷Ö¸Ïò´¦ÀíÆ÷½«ÒªÖ´ÐеÄÖ¸Áî´úÂë¡£cr1£¬ Ò»¸ö32λ¿ØÖƼĴæÆ÷£¬ÔÚ¸ÕÆô¶¯Ê±Öµ±»ÉèΪ0¡£cr1µÄPE(Protected Enabled£¬ ±£»¤Ä£Ê½Ê¹ÄÜ)λÓÃÀ´Ö¸Ê¾´¦ÀíÆ÷ÊÇ´¦ÓÚ±£»¤Ä£Ê½»¹ÊÇʵµØÖ·Ä£Ê½¡£ ÓÉÓÚÆô¶¯Ê±¸Ãλ±»Çå룬´¦ÀíÆ÷ÔÚʵµØÖ·Ä£Ê½ÖÐÒýµ¼¡£ÔÚʵµØÖ·Ä£Ê½ÖУ¬ ÏßÐÔµØÖ·ÓëÎïÀíµØÖ·ÊǵÈͬµÄ¡£
¡¡¡¡Öµ0xfffffff0ÂÔСÓÚ4G,Òò´Ë¼ÆËã»úûÓÐ4G×Ö½ÚÎïÀíÄڴ棬 Õâ¾Í²»»áÊÇÒ»¸öÓÐЧµÄÄÚ´æµØÖ·¡£¼ÆËã»úÓ²¼þ½«Õâ¸öµØÖ·×ªÖ¸ÏòBIOS´æ´¢¿é¡£
¡¡¡¡BIOS±íʾBasic Input Output System (»ù±¾ÊäÈëÊä³öϵͳ)¡£ÔÚÖ÷°åÉÏ£¬Ëü±»¹Ì»¯ÔÚÒ»¸öÏà¶ÔÈÝÁ¿½ÏСµÄ Ö»¶Á´æ´¢Æ÷(Read-Only Memory, ROM)¡£BIOS°üº¬¸÷ÖÖ¸÷ÑùΪÖ÷°åÓ²¼þ ¶¨ÖƵĵײãÀý³Ì¡£¾ÍÕâÑù£¬´¦ÀíÆ÷Ê×ÏÈÖ¸Ïò³£×¤BIOS´æ´¢Æ÷µÄµØÖ· 0xfffffff0¡£Í¨³£Õâ¸öλÖðüº¬Ò»ÌõÌø×ªÖ¸ÁָÏòBIOSµÄPOSTÀý³Ì¡£
¡¡¡¡POST±íʾPower On Self Test(¼Óµç×Ô¼ì)¡£ ÕâÌ׳ÌÐò°üÀ¨ÄÚ´æ¼ì²é£¬ÏµÍ³×ÜÏß¼ì²éºÍÆäËüµ×²ã¹¤¾ß£¬ ´Ó¶øÊ¹µÃCPUÄܹ»³õʼ»¯Õų̂¼ÆËã»ú¡£ÕâÒ»½×¶ÎÖÐÓÐÒ»¸öÖØÒª²½Ö裬 ¾ÍÊÇÈ·¶¨Òýµ¼É豸¡£ÏÖÔÚËùÓеÄBIOS¶¼ÔÊÐíÊÖ¹¤Ñ¡ÔñÒýµ¼É豸¡£ Äã¿ÉÒÔ´ÓÈíÅÌ¡¢¹âÅÌÇý¶¯Æ÷¡¢Ó²Å̵ÈÉ豸Òýµ¼¡£
¡¡¡¡POSTµÄ×îºóÒ»²½ÊÇÖ´ÐÐINT 0x19Ö¸Áî¡£ Õâ¸öÖ¸Áî´ÓÒýµ¼É豸µÚÒ»¸öÉÈÇø¶ÁÈ¡512×Ö½Ú£¬×°ÈëµØÖ·0x7c00¡£ µÚÒ»¸öÉÈÇøµÄ˵·¨×îÔçÆðÔ´ÓÚÓ²Å̵Ľṹ£¬ Ó²ÅÌÃæ±»·ÖΪÈô¸ÉÔ²ÖùÐιìµÀ¡£¸ø¹ìµÀ±àºÅ£¬Í¬Ê±ÓÖ½«¹ìµÀ·ÖΪ Ò»¶¨ÊýÄ¿(ͨ³£ÊÇ64)µÄÉÈÐΡ£0ºÅ¹ìµÀÊÇÓ²Å̵Ä×îÍâȦ£¬1ºÅÉÈÇø£¬ µÚÒ»¸öÉÈÇø(¹ìµÀ¡¢ÖùÃæ¶¼´Ó0¿ªÊ¼±àºÅ£¬¶øÉÈÇø´Ó1¿ªÊ¼±àºÅ) ÓÐ×ÅÌØÊâµÄ×÷Óã¬ËüÓÖ±»³ÆÎªÖ÷Òýµ¼¼Ç¼(Master Boot Record, MBR)¡£ µÚÒ»¹ìÊ£ÓàµÄÉÈÇø³£³£²»Ê¹ÓÃ[1]¡£
¡¡¡¡ÈÃÎÒÃÇ¿´Ò»ÏÂÎļþ/boot/boot0¡£ ÕâÊÇÒ»¸ö½ö512×Ö½ÚµÄСÎļþ¡£Èç¹ûÔÚFreeBSD°²×°¹ý³ÌÖÐÑ¡Ôñ ¡°bootmanager¡±£¬Õâ¸öÎļþÖеÄÄÚÈݽ«±»Ð´ÈëÓ²ÅÌMBR
¡¡¡¡ÈçǰËùÊö£¬ INT 0x19 Ö¸Áî×°ÔØ MBR£¬ Ò²¾ÍÊÇ boot0 µÄÄÚÈÝÖÁÄÚ´æµØÖ· 0x7c00¡£ ÔÙ¿´Îļþ sys/boot/i386/boot0/boot0.S£¬ ¿ÉÒÔ²ÂÏëÕâÀïÃæ·¢ÉúÁËʲô - ÕâÊÇÒýµ¼¹ÜÀíÆ÷£¬ Ò»¶ÎÓÉ Robert NordierÊéдµÄÁîÈËÆð¾´µÄ³ÌÐòƬ¶Î¡£
¡¡¡¡MBRÀҲ¾ÍÊÇboot0À ´ÓÆ«ÒÆÁ¿0x1be¿ªÊ¼ÓÐÒ»¸öÌØÊâµÄ½á¹¹£¬³ÆÎª ·ÖÇø±í¡£ÆäÖÐÓÐ4Ìõ¼Ç¼ (³ÆÎª·ÖÇø¼Ç¼)£¬Ã¿Ìõ¼Ç¼16×Ö½Ú¡£ ·ÖÇø¼Ç¼±íʾӲÅÌÈçºÎ±»»®·Ö£¬ÔÚFreeBSDµÄÊõÓïÖУ¬ Õâ±»³ÆÎªslice(d)¡£16×Ö½ÚÖÐÓÐÒ»¸ö±êÖ¾×Ö½Ú¾ö¶¨Õâ¸ö·ÖÇøÊÇ·ñ¿ÉÒýµ¼¡£ ÓнöÖ»ÄÜÓÐÒ»¸ö·ÖÇø¿ÉÉ趨ÕâÒ»±êÖ¾¡£·ñÔò£¬ boot0µÄ´úÂ뽫¾Ü¾ø¼ÌÐøÖ´ÐС£
¡¡¡¡Ò»¸ö·ÖÇø¼Ç¼ÓÐÈçÏÂÓò£º
1×Ö½Ú ÎļþϵͳÀàÐÍ
1×Ö½Ú ¿ÉÒýµ¼±êÖ¾
6×Ö½Ú CHS¸ñʽÃèÊö·û
8×Ö½Ú LBA¸ñʽÃèÊö·û
¡¡¡¡Ò»¸ö·ÖÇø¼Ç¼ÃèÊö·û°üº¬Ä³Ò»·ÖÇøÔÚÓ²ÅÌÉϵÄÈ·ÇÐλÖÃÐÅÏ¢¡£ LBAºÍCHSÁ½ÖÖÃèÊö·ûָʾÏàͬµÄÐÅÏ¢£¬µ«ÊÇָʾ·½Ê½ÓÐËù²»Í¬£ºLBA (Âß¼¿éѰַ£¬Logical Block Addressing)ָʾ·ÖÇøµÄÆðʼÉÈÇøºÍ·ÖÇø³¤¶È£¬ ¶øCHS(ÖùÃæ ´ÅÍ· ÉÈÇø)ָʾÊ×ÉÈÇøºÍÄ©ÉÈÇø
¡¡¡¡Òýµ¼¹ÜÀíÆ÷ɨÃè·ÖÇø±í£¬²¢ÔÚÆÁÄ»ÉÏÏÔʾ²Ëµ¥£¬ÒÔ±ãÓû§¿ÉÒÔ Ñ¡ÔñÓÃÓÚÒýµ¼µÄ´ÅÅ̺ͷÖÇø¡£ÔÚ¼üÅÌÉϰ´ÏÂÏàÓ¦µÄ¼üºó£¬ boot0½øÐÐÈç϶¯×÷£º
±ê¼ÇÑ¡ÖеķÖÇøÎª¿ÉÒýµ¼£¬Çå³ýÒÔǰµÄ¿ÉÒýµ¼±êÖ¾
¼Çס±¾´ÎÑ¡ÔñµÄ·ÖÇøÒÔ±¸Ï´ÎÒýµ¼Ê±×÷ΪȱʡÏî
×°ÔØÑ¡ÖзÖÇøµÄµÚÒ»¸öÉÈÇø£¬²¢Ìø×ªÖ´ÐÐÖ®
¡¡¡¡Ê²Ã´Êý¾Ý»á´æÔÚÓÚÒ»¸ö¿ÉÒýµ¼ÉÈÇø(ÕâÀïÖ¸FreeBSDÉÈÇø)µÄµÚÒ»ÉÈÇøÀïÄØ£¿ ÕýÈçÄãÒѾ²Âµ½µÄ£¬ÄǾÍÊÇboot2¡£
¡¡¡¡Ò²ÐíÄãÏëÖªµÀ£¬ÎªÊ²Ã´boot2ÊÇÔÚ boot0Ö®ºó£¬¶ø²»ÊÇÔÚboot1Ö®ºó¡£ÊÂʵÉÏ£¬ Ò²ÓÐÒ»¸ö512×Ö½ÚµÄÎļþboot1´æ·ÅÔÚĿ¼ /bootÀÄÇÊÇÓÃÀ´´ÓÒ»ÕÅÈíÅÌÒýµ¼ÏµÍ³µÄ¡£ ´ÓÈíÅÌÒýµ¼Ê±£¬boot1Æð×Å boot0¶ÔÓ²ÅÌÒýµ¼ÏàͬµÄ×÷ÓÃ:ËüÕÒµ½ boot2²¢ÔËÐÐÖ®¡£
¡¡¡¡Äã¿ÉÄÜÒѾ¿´µ½ÓÐÒ»Îļþ/boot/mbr¡£ ÕâÊÇboot0µÄ¼ò»¯°æ±¾¡£ mbrÖеĴúÂë²»»áÏÔʾ²Ëµ¥ÈÃÓû§Ñ¡Ôñ£¬ ¶øÖ»ÊǼòµ¥µÄÒýµ¼±»±êÖ¾µÄ·ÖÇø¡£
¡¡¡¡ÊµÏÖboot2µÄ´úÂë´æ·ÅÔÚĿ¼ sys/boot/i386/boot2/À¶ÔÓ¦µÄ¿ÉÖ´ÐÐÎļþÔÚ /bootÀï¡£ÔÚ/bootÀïµÄÎļþ boot0ºÍboot2²»»áÔÚÒýµ¼¹ý³ÌÖÐʹÓ㬠ֻÓÐboot0cfgÕâÑùµÄ¹¤¾ß²Å»áʹÓÃËüÃÇ¡£ boot0µÄÄÚÈÝÓ¦ÔÚMBRÖвÅÄÜÉúЧ¡£ boot2λÓÚ¿ÉÒýµ¼µÄFreeBSD·ÖÇøµÄ¿ªÊ¼¡£ ÕâЩλÖò»ÊÜÎļþϵͳ¿ØÖÆ£¬ËùÒÔËüÃDz»¿ÉÓÃls Ö®ÀàµÄÃüÁî²é¿´¡£
¡¡¡¡boot2µÄÖ÷ÒªÈÎÎñÊÇ×°ÔØÎļþ /boot/loader£¬ÄÇÊÇÒýµ¼¹ý³ÌµÄµÚÈý½×¶Î¡£ ÔÚboot2ÖеĴúÂë²»ÄÜʹÓÃÖîÈç open()
ºÍread()
Ö®ÀàµÄÀý³Ìº¯Êý,ÒòΪÄں˻¹Ã»Óб»¼ÓÔØ¡£¶øÓ¦µ±É¨ÃèÓ²ÅÌ£¬
¶ÁÈ¡Îļþϵͳ½á¹¹£¬ÕÒµ½Îļþ/boot/loader£¬
ÓÃBIOSµÄ¹¦Äܽ«Ëü¶ÁÈëÄڴ棬Ȼºó´ÓÆäÈë¿Úµã¿ªÊ¼Ö´ÐÐÖ®¡£
¡¡¡¡³ý´ËÖ®Í⣬boot2»¹¿ÉÌáʾÓû§½øÐÐÑ¡Ôñ£¬ loader¿ÉÒÔ´ÓÆäËü´ÅÅÌ¡¢ÏµÍ³µ¥Ôª¡¢·ÖÇø×°ÔØ¡£
¡¡¡¡boot2 µÄ¶þ½øÖÆ´úÂëÓÃÌØÊâµÄ·½Ê½²úÉú£º
sys/boot/i386/boot2/Makefile boot2: boot2.ldr boot2.bin ${BTX}/btx/btx btxld -v -E ${ORG2} -f bin -b ${BTX}/btx/btx -l boot2.ldr \ -o boot2.ld -P 1 boot2.bin
¡¡¡¡Õâ¸öMakefileƬ¶Ï±íÃ÷btxld(8)±»ÓÃÀ´Á´½Ó¶þ½øÖÆ´úÂë¡£ BTX±íʾÒýµ¼À©Õ¹Æ÷(BooT eXtender)ÊǸø³ÌÐò(³ÆÎª¿Í»§(client) Ìṩ±£»¤Ä£Ê½»·¾³¡¢²¢Óë¿Í»§³ÌÐòÏàÁ´½ÓµÄÒ»¶Î´úÂë¡£ËùÒÔ boot2ÊÇÒ»¸öBTX¿Í»§£¬Ê¹ÓÃBTXÌṩµÄ·þÎñ¡£
¡¡¡¡¹¤¾ßbtxldÊÇÁ´½ÓÆ÷£¬ Ëü½«Á½¸ö¶þ½øÖÆ´úÂëÁ´½ÓÔÚÒ»Æð¡£btxld(8)ºÍld(1) µÄÇø±ðÊÇldͨ³£½«Á½¸öÄ¿±êÎļþ Á´½Ó³ÉÒ»¸ö¶¯Ì¬Á´½Ó¿â»ò¿ÉÖ´ÐÐÎļþ£¬¶øbtxld Ôò½«Ò»¸öÄ¿±êÎļþÓëBTXÁ´½ÓÆðÀ´£¬²úÉúÊʺÏÓÚ·ÅÔÚ·ÖÇøÊײ¿µÄ¶þ½øÖÆ´úÂ룬 ÒÔʵÏÖϵͳÒýµ¼¡£
¡¡¡¡boot0Ö´ÐÐÌø×ªÖÁBTXµÄÈë¿Úµã¡£ È»ºó£¬BTX½«´¦ÀíÆ÷Çл»ÖÁ±£»¤Ä£Ê½£¬²¢×¼±¸Ò»¸ö¼òµ¥µÄ»·¾³£¬ È»ºóµ÷Óÿͻ§¡£Õâ¸ö»·¾³°üÀ¨£º
ÐéÄâ8086ģʽ¡£ÕâÒâζ×ÅBTXÊÇÐéÄâ8086µÄ¼àÊÓ³ÌÐò¡£ ʵģʽָÁÈçpushf, popf, cli, sti, if£¬¾ù¿É±»¿Í»§µ÷Óá£
½¨Á¢ÖжÏÃèÊö·û±í(Interrupt Descriptor Table, IDT)£¬ ʹµÃËùÓеÄÓ²¼þÖжϿɱ»È±Ê¡µÄBIOS³ÌÐò´¦Àí¡£ ½¨Á¢ÖжÏ0x30£¬ÕâÊÇϵͳµ÷Óùؿڡ£
Á½¸öϵͳµ÷ÓÃexec
ºÍ exit
µÄ¶¨ÒåÈçÏÂ:
sys/boot/i386/btx/lib/btxsys.s: .set INT_SYS,0x30 # ÖжϺŠ# # System call: exit # __exit: xorl %eax,%eax # BTXϵͳµ÷ÓÃ0x0 int $INT_SYS # # # System call: exec # __exec: movl $0x1,%eax # BTXϵͳµ÷ÓÃ0x1 int $INT_SYS #
¡¡¡¡BTX½¨Á¢È«¾ÖÃèÊö·û±í(Global Descriptor Table, GDT):
sys/boot/i386/btx/btx/btx.s: gdt: .word 0x0,0x0,0x0,0x0 # ÒÔ¿ÕΪÈë¿Ú .word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE .word 0xffff,0x0,0x9200,0xcf # SEL_SDATA .word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE .word 0xffff,0x0,0x9200,0x0 # SEL_RDATA .word 0xffff,MEM_USR,0xfa00,0xcf# SEL_UCODE .word 0xffff,MEM_USR,0xf200,0xcf# SEL_UDATA .word _TSSLM,MEM_TSS,0x8900,0x0 # SEL_TSS
¡¡¡¡¿Í»§µÄ´úÂëºÍÊý¾ÝʼÓÚµØÖ·MEM_USR(0xa000)£¬Ñ¡Ôñ·û(selector) SEL_UCODEÖ¸Ïò¿Í»§µÄÊý¾Ý¶Î¡£Ñ¡Ôñ·û SEL_UCODE ÓµÓеÚ3¼¶ÃèÊö·ûȨÏÞ (Descriptor Privilege Level, DPL)£¬ÕâÊÇ×îµÍ¼¶È¨ÏÞ¡£µ«ÊÇ INT 0x30 Ö¸ÁîµÄ´¦Àí³ÌÐò´æ´¢ÓÚÁíÒ»¸ö¶ÎÀ Õâ¸ö¶ÎµÄÑ¡Ôñ·ûSEL_SCODE (supervisor code)ÓÉÓÐ׏ÜÀí¼¶È¨ÏÞ¡£ ÕýÈç´úÂ뽨Á¢IDT(ÖжÏÃèÊö·û±í)ʱ½øÐеIJÙ×÷ÄÇÑù:
mov $SEL_SCODE,%dh # ¶ÎÑ¡Ôñ·û init.2: shr %bx # ÊÇ·ñ´¦ÀíÕâ¸öÖжϣ¿ jnc init.3 # ·ñ mov %ax,(%di) # ÉèÖô¦Àí³ÌÐòÆ«ÒÆÁ¿ mov %dh,0x2(%di) # ÉèÖô¦Àí³ÌÐòÑ¡Ôñ·û mov %dl,0x5(%di) # ÉèÖà P:DPL:type add $0x4,%ax # ÏÂÒ»¸öÖжϴ¦Àí³ÌÐò
¡¡¡¡ËùÒÔ£¬µ±¿Í»§µ÷Óà __exec()
ʱ£¬´úÂ뽫±»ÒÔ×î¸ßȨÏÞÖ´ÐС£
ÕâʹµÃÄں˿ÉÒÔÐ޸ı£»¤Ä£Ê½Êý¾Ý½á¹¹£¬Èç·ÖÒ³±í(page tables)¡¢È«¾ÖÃèÊö·û±í(GDT)¡¢
ÖжÏÃèÊö·û±í(IDT)µÈ¡£
¡¡¡¡boot2 ¶¨ÒåÁËÒ»¸öÖØÒªµÄÊý¾Ý½á¹¹£º struct bootinfo¡£Õâ¸ö½á¹¹ÓÉ boot2 ³õʼ»¯£¬È»ºó±»×ªË͵½loader£¬Ö®ºóÓÖ±»×ªÈëÄںˡ£ Õâ¸ö½á¹¹µÄ²¿·ÖÏîÄ¿ÓÉboot2É趨£¬ÆäÓàµÄÓÉloaderÉ趨¡£ Õâ¸ö½á¹¹ÖеÄÐÅÏ¢°üÀ¨ÄÚºËÎļþÃû¡¢BIOSÌṩµÄÓ²ÅÌÖùÃæ/´ÅÍ·/ÉÈÇøÊýÄ¿ÐÅÏ¢¡¢ BIOSÌṩµÄÒýµ¼É豸µÄÇý¶¯Æ÷±àºÅ£¬¿ÉÓõÄÎïÀíÄÚ´æ´óС£¬envp Ö¸Õë(»·¾³Ö¸Õë)µÈ¡£¶¨ÒåÈçÏ£º
/usr/include/machine/bootinfo.h struct bootinfo { u_int32_t bi_version; u_int32_t bi_kernelname; /* ÓÃÒ»¸ö×Ö½Ú±íʾ * */ u_int32_t bi_nfs_diskless; /* struct nfs_diskless * */ /* ÒÔÉÏΪ³£±¸Ïî */ #define bi_endcommon bi_n_bios_used u_int32_t bi_n_bios_used; u_int32_t bi_bios_geom[N_BIOS_GEOM]; u_int32_t bi_size; u_int8_t bi_memsizes_valid; u_int8_t bi_bios_dev; /* Òýµ¼É豸µÄBIOSµ¥Ôª±àºÅ */ u_int8_t bi_pad[2]; u_int32_t bi_basemem; u_int32_t bi_extmem; u_int32_t bi_symtab; /* struct symtab * */ u_int32_t bi_esymtab; /* struct symtab * */ /* ÒÔÏÂÏîÄ¿½ö¸ß¼¶bootloaderÌṩ */ u_int32_t bi_kernend; /* Äں˿ռäÄ©¶Ë */ u_int32_t bi_envp; /* »·¾³ */ u_int32_t bi_modulep; /* Ô¤×°ÔØµÄÄ£¿é */ };
¡¡¡¡boot2 ½øÈëÒ»¸öÑ»·µÈ´ýÓû§ÊäÈ룬Ȼºóµ÷Óà load()
¡£Èç¹ûÓû§²»×öÈκÎÊäÈ룬ѻ·½«ÔÚÒ»¶Îʱ¼äºó½áÊø£¬ load()
½«»á×°ÔØÈ±Ê¡Îļþ(/boot/loader)¡£ º¯Êý
ino_t lookup(char *filename)
ºÍ int
xfsread(ino_t inode, void *buf, size_t nbyte)
ÓÃÀ´½«ÎļþÄÚÈݶÁÈëÄÚ´æ¡£/boot/loaderÊÇÒ»¸öELF¸ñʽ¶þ½øÖÆÎļþ£¬
²»¹ýËüµÄÍ·²¿±»»»³ÉÁËa.out¸ñʽÖеÄstruct exec½á¹¹¡£ load()
ɨÃèloaderµÄELFÍ·²¿£¬×°ÔØ/boot/loader
ÖÁÄڴ棬ȻºóÌø×ªÖÁÈë¿ÚÖ´ÐÐÖ®£º
sys/boot/i386/boot2/boot2.c: __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), MAKEBOOTDEV(dev_maj[dsk.type], 0, dsk.slice, dsk.unit, dsk.part), 0, 0, 0, VTOP(&bootinfo));
¡¡¡¡loaderÒ²ÊÇÒ»¸ö BTX ¿Í»§£¬ÔÚÕâÀï²»×÷ÏêÊö¡£ ÒÑÓÐÒ»²¿ÄÚÈÝÈ«ÃæµÄÊÖ²á loader(8) £¬ÓÉMike SmithÊéд¡£ ±Èloader¸üµ×²ãµÄBTXµÄ»úÀíÒѾÔÚÇ°ÃæÌÖÂÛ¹ý¡£
¡¡¡¡loader µÄÖ÷ÒªÈÎÎñÊÇÒýµ¼Äںˡ£µ±Äں˱»×°ÈëÄÚ´æºó£¬¼´±»loaderµ÷ÓÃ:
sys/boot/common/boot.c: /* ´ÓloaderÖе÷ÓÃÄÚºËÖжÔÓ¦µÄexec³ÌÐò */ module_formats[km->m_loader]->l_exec(km);
¡¡¡¡ÈÃÎÒÃÇÀ´¿´Ò»ÏÂÁ´½ÓÄں˵ÄÃüÁî¡£ ÕâÄܰïÖúÎÒÃÇÁ˽â loader ´«µÝ¸øÄں˵Ä׼ȷλÖᣠÕâ¸öλÖþÍÊÇÄÚºËÕæÊµµÄÈë¿Úµã¡£
sys/conf/Makefile.i386: ld -elf -Bdynamic -T /usr/src/sys/conf/ldscript.i386 -export-dynamic \ -dynamic-linker /red/herring -o kernel -X locore.o \ <lots of kernel .o files>
¡¡¡¡ÔÚÕâÒ»ÐÐÖÐÓÐһЩÓÐȤµÄ¶«Î÷¡£Ê×ÏÈ£¬ÄÚºËÊÇÒ»¸öELF¶¯Ì¬Á´½Ó¶þ½øÖÆÎļþ£¬ ¿ÉÊǶ¯Ì¬Á´½ÓÆ÷È´ÊÇ/red/herring£¬Ò»¸öĪÐëÓеÄÎļþ¡£ Æä´Î£¬¿´Ò»ÏÂÎļþsys/conf/ldscript.i386£¬ ¿ÉÒÔ¶ÔÀí½â±àÒëÄÚºËʱldµÄÑ¡ÏîÓÐһЩÆô·¢¡£ ÔĶÁ×îǰ¼¸ÐУ¬×Ö·û´®
sys/conf/ldscript.i386: ENTRY(btext)
¡¡¡¡±íʾÄں˵ÄÈë¿ÚµãÊÇ·ûºÅ `btext'¡£Õâ¸ö·ûºÅÔÚlocore.s Öж¨Òå:
sys/i386/i386/locore.s: .text /********************************************************************** * * This is where the bootblocks start us, set the ball rolling... * Èë¿Ú */ NON_GPROF_ENTRY(btext)
¡¡¡¡Ê×ÏȽ«¼Ä´æÆ÷EFLAGSÉèΪһ¸öÔ¤¶¨ÒåµÄÖµ0x00000002£¬ È»ºó³õʼ»¯ËùÓжμĴæÆ÷:
sys/i386/i386/locore.s /* ²»ÒªÏàÐÅBIOS¸ø³öµÄEFLAGSÖµ */ pushl $PSL_KERNEL popfl /* * ²»ÒªÏàÐÅBIOS¸ø³öµÄ%fs¡¢%gsÖµ¡£ÏàÐÅÒýµ¼¹ý³ÌÖÐÉ趨µÄ%cs¡¢%ds¡¢%es¡¢%ssÖµ */ mov %ds, %ax mov %ax, %fs mov %ax, %gs
¡¡¡¡btextµ÷ÓÃÀý³Ìrecover_bootinfo()
, identify_cpu()
,create_pagetables()
¡£
ÕâЩÀý³ÌÒ²¶¨ÔÚlocore.sÖ®ÖС£ÕâЩÀý³ÌµÄ¹¦ÄÜÈçÏ£º
recover_bootinfo |
Õâ¸öÀý³Ì·ÖÎöÓÉÒýµ¼³ÌÐò´«Ë͸øÄں˵IJÎÊý¡£Òýµ¼ÄÚºËÓÐ3ÖÖ·½Ê½: ÓÉloaderÒýµ¼(ÈçǰËùÊö), ÓÉÀÏʽ´ÅÅÌÒýµ¼¿éÒýµ¼,ÎÞÅÌÒýµ¼·½Ê½¡£ Õâ¸öº¯Êý¾ö¶¨Òýµ¼·½Ê½£¬²¢½«½á¹¹struct bootinfo ´æ´¢ÖÁÄÚºËÄÚ´æ¡£ |
identify_cpu |
Õâ¸öº¯ÊýÕì²âCPUÀàÐÍ£¬½«½á¹û´æ·ÅÔÚ±äÁ¿ _cpu ÖС£ |
create_pagetables |
Õâ¸öº¯ÊýΪ·ÖÒ³±íÔÚÄÚºËÄÚ´æ¿Õ¼ä¶¥²¿·ÖÅäÒ»¿é¿Õ¼ä£¬²¢Ìîдһ¶¨ÄÚÈÝ |
¡¡¡¡ÏÂÒ»²½ÊÇ¿ªÆôVME(Èç¹ûCPUÓÐÕâ¸ö¹¦ÄÜ):
testl $CPUID_VME, R(_cpu_feature) jz 1f movl %cr4, %eax orl $CR4_VME, %eax movl %eax, %cr4
¡¡¡¡È»ºó£¬Æô¶¯·Öҳģʽ:
/* Now enable paging */ movl R(_IdlePTD), %eax movl %eax,%cr3 /* load ptd addr into mmu */ movl %cr0,%eax /* get control word */ orl $CR0_PE|CR0_PG,%eax /* enable paging */ movl %eax,%cr0 /* and let's page NOW! */
¡¡¡¡ÓÉÓÚ·ÖҳģʽÒѾÆô¶¯£¬ÔÏȵÄʵµØÖ·Ñ°Ö··½Ê½Ë漴ʧЧ¡£ ËæºóÈýÐдúÂëÓÃÀ´Ìø×ªÖÁÐéÄâµØÖ·:
pushl $begin /* jump to high virtualized address */ ret /* ÏÖÔÚÌø×ªÖÁKERNBASE£¬ÄÇÀïÊDzÙ×÷ϵͳÄں˱»Á´½ÓºóÕæÕýµÄÈë¿Ú */ begin:
¡¡¡¡º¯Êýinit386()
±»µ÷Óã»Ëæ²ÎÊý´«µÝµÄÊÇÒ»¸öÖ¸Õ룬
Ö¸ÏòµÚÒ»¸ö¿ÕÏÐÎïÀíÒ³¡£ËæºóÖ´ÐÐmi_startup()
¡£ init386
ÊÇÒ»¸öÓëÓ²¼þϵͳÏà¹ØµÄ³õʼ»¯º¯Êý£¬ mi_startup()
ÊǸöÓëÓ²¼þϵͳÎ޹صĺ¯Êý (ǰ׺'mi_'±íʾMachine
Independent£¬²»ÒÀÀµÓÚ»úÆ÷)¡£ Äں˲»ÔÙ´Ómi_startup()
Àï·µ»Ø£»
µ÷ÓÃÕâ¸öº¯Êýºó£¬ÄÚºËÍê³ÉÒýµ¼:
sys/i386/i386/locore.s: movl physfree, %esi pushl %esi /* Ë͸øinit386()µÄµÚÒ»¸ö²ÎÊý */ call _init386 /* ÉèÖÃ386оƬʹ֮ÊÊÓ¦UNIX¹¤×÷ */ call _mi_startup /* ×Ô¶¯ÅäÖÃÓ²¼þ£¬¹Ò½Ó¸ùÎļþϵͳ£¬µÈ */ hlt /* ²»ÔÙ·µ»Øµ½ÕâÀ */
init386()
¡¡¡¡init386()
¶¨ÒåÔÚ sys/i386/i386/machdep.cÖУ¬ ËüÕë¶ÔIntel
386оƬ½øÐеͼ¶³õʼ»¯¡£loaderÒѽ«CPUÇл»ÖÁ±£»¤Ä£Ê½¡£ loaderÒѾ½¨Á¢ÁË×îÔçµÄÈÎÎñ¡£
ÒëÕß×¢: ÿ¸ö"ÈÎÎñ"¶¼ÊÇÓëÆäËü¡°ÈÎÎñ¡±Ïà¶Ô¶ÀÁ¢µÄÖ´Ðл·¾³¡£ ÈÎÎñÖ®¼ä¿ÉÒÔ·ÖʱÇл»£¬ÕâΪ²¢·¢½ø³Ì/Ï̵߳ÄʵÏÖÌṩÁ˱ØÒª»ù´¡¡£ ¶ÔÓÚIntel 80x86ÈÎÎñµÄÃèÊö£¬Ïê¼ûIntel¹«Ë¾¹ØÓÚ80386 CPU¼°ºóÐø²úÆ·µÄ×ÊÁÏ£¬ »òÕßÔÚÇ廪´óѧͼÊé¹Ý ¹Ý²Ø¼Ç¼ÖÐÓÃ"80386"×÷Ϊ¹Ø¼ü´ÊËù²éÕÒµ½µÄϵͳ½á¹¹·½ÃæµÄÊéÄ¿¡£
³õʼ»¯Äں˵Ŀɵ÷Õû²ÎÊý£¬ÕâЩ²ÎÊýÓÉÒýµ¼³ÌÐò´«À´
×¼±¸GDT(È«¾ÖÃèÊö·û±í)
×¼±¸IDT(ÖжÏÃèÊö·û±í)
³õʼ»¯ÏµÍ³¿ØÖÆÌ¨
³õʼ»¯DDB(Äں˵ĵãµ÷ÊÔÆ÷)£¬Èç¹ûËü±»±àÒë½øÄں˵ϰ
³õʼ»¯TSS(ÈÎÎñ״̬¶Î)
×¼±¸LDT(¾Ö²¿ÃèÊö·û±í)
½¨Á¢proc0(0ºÅ½ø³Ì£¬¼´Äں˵Ľø³Ì)µÄpcb(½ø³Ì¿ØÖÆ¿é)
¡¡¡¡init386()
Ê×Ïȳõʼ»¯Äں˵Ŀɵ÷Õû²ÎÊý£¬
ÕâЩ²ÎÊýÓÉÒýµ¼³ÌÐò´«À´¡£ÏÈÉèÖû·¾³Ö¸Õë(environment pointer, envp)µ÷Óã¬
ÔÙµ÷ÓÃinit_param1()
¡£
envpÖ¸ÕëÒÑÓÉloader´æ·ÅÔڽṹbootinfoÖÐ:
sys/i386/i386/machdep.c: kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE; /* ³õʼ»¯»ù±¾¿Éµ÷ÕûÏî,ÈçhzµÈ */ init_param1();
¡¡¡¡init_param1()
¶¨ÒåÔÚ sys/kern/subr_param.cÖ®ÖС£ Õâ¸öÎļþÀïÓÐһЩsysctlÏ»¹ÓÐÁ½¸öº¯Êý£¬
init_param1()
ºÍinit_param2()
¡£ ÕâÁ½¸öº¯Êý´Óinit386()
Öе÷ÓÃ:
sys/kern/subr_param.c hz = HZ; TUNABLE_INT_FETCH("kern.hz", &hz);
¡¡¡¡TUNABLE_<typename>_FETCHÓÃÀ´»ñÈ¡»·¾³±äÁ¿µÄÖµ:
/usr/src/sys/sys/kernel.h #define TUNABLE_INT_FETCH(path, var) getenv_int((path), (var))
¡¡¡¡Sysctlkern.hzÊÇϵͳʱÖÓÆµÂÊ¡£Í¬Ê±£¬
ÕâЩsysctlÏî±»init_param1()
É趨: kern.maxswzone, kern.maxbcache, kern.maxtsiz, kern.dfldsiz, kern.maxdsiz,
kern.dflssiz, kern.maxssiz, kern.sgrowsiz¡£
¡¡¡¡È»ºóinit386()
×¼±¸È«¾ÖÃèÊö·û±í (Global Descriptors
Table, GDT)¡£ÔÚx86ÉÏÿ¸öÈÎÎñ¶¼ÔËÐÐÔÚ×Ô¼ºµÄÐéÄâµØÖ·¿Õ¼äÀ
Õâ¸ö¿Õ¼äÓÉ"¶ÎÖ·:Æ«ÒÆÁ¿"µÄÊý¶ÔÖ¸¶¨¡£¾Ù¸öÀý×Ó£¬µ±Ç°½«ÒªÓÉ´¦ÀíÆ÷Ö´ÐеÄÖ¸ÁîÔÚ
CS:EIP£¬ÄÇôÕâÌõÖ¸ÁîµÄÏßÐÔÐéÄâµØÖ·¾ÍÊÇ¡°´úÂë¶ÎÐéÄâ¶ÎµØÖ·CS¡± + EIP¡£
ΪÁ˼ò±ã£¬¶ÎÆðʼÓÚÐéÄâµØÖ·0£¬ÖÕÖ¹ÓÚ½çÏÞ4G×Ö½Ú¡£ËùÒÔ£¬ÔÚÕâ¸öÀý×ÓÖУ¬
Ö¸ÁîµÄÏßÐÔÐéÄâµØÖ·ÕýÊÇEIPµÄÖµ¡£¶Î¼Ä´æÆ÷£¬ÈçCS¡¢DSµÈÊÇÑ¡Ôñ·û£¬
¼´È«¾ÖÃèÊö·û±íÖеÄË÷Òý(¸ü¾«È·µÄ˵£¬Ë÷Òý²¢·ÇÑ¡Ôñ·ûµÄÈ«²¿£¬ ¶øÊÇÑ¡Ôñ·ûÖеÄINDEX²¿·Ö)¡£
ÒëÕß×¢: ¶ÔÓÚ80386£¬ Ñ¡Ôñ·ûÓÐ16룬INDEX²¿·ÖÊÇÆäÖеĸß13λ¡£
sys/i386/i386/machdep.c: union descriptor gdt[NGDT * MAXCPU]; /* È«¾ÖÃèÊö·û±í */ sys/i386/include/segments.h: /* * È«¾ÖÃèÊö·û±í(GDT)ÖеÄÈë¿Ú */ #define GNULL_SEL 0 /* ¿ÕÃèÊö·û */ #define GCODE_SEL 1 /* Äں˴úÂëÃèÊö·û */ #define GDATA_SEL 2 /* ÄÚºËÊý¾ÝÃèÊö·û */ #define GPRIV_SEL 3 /* ¶Ô³Æ¶à´¦Àí(SMP)ÿ´¦ÀíÆ÷רÓÐÊý¾Ý */ #define GPROC0_SEL 4 /* Task state process slot zero and up, ÈÎÎñ״̬½ø³Ì */ #define GLDT_SEL 5 /* ÿ¸ö½ø³ÌµÄ¾Ö²¿ÃèÊö·û±í */ #define GUSERLDT_SEL 6 /* Óû§×Ô¶¨ÒåµÄ¾Ö²¿ÃèÊö·û±í */ #define GTGATE_SEL 7 /* ½ø³ÌÈÎÎñÇл»¹Ø¿Ú */ #define GBIOSLOWMEM_SEL 8 /* BIOSµÍ¶ËÄÚ´æ·ÃÎÊ(±ØÐëÊÇÕâµÚ8¸öÈë¿Ú) */ #define GPANIC_SEL 9 /* »áµ¼ÖÂȫϵͳÒì³£ÖÐÖ¹¹¤×÷µÄÈÎÎñ״̬ */ #define GBIOSCODE32_SEL 10 /* BIOS½Ó¿Ú(32λ´úÂë) */ #define GBIOSCODE16_SEL 11 /* BIOS½Ó¿Ú(16λ´úÂë) */ #define GBIOSDATA_SEL 12 /* BIOS½Ó¿Ú(Êý¾Ý) */ #define GBIOSUTIL_SEL 13 /* BIOS½Ó¿Ú(¹¤¾ß) */ #define GBIOSARGS_SEL 14 /* BIOS½Ó¿Ú(×Ô±äÁ¿£¬²ÎÊý) */
¡¡¡¡Çë×¢Ò⣬ÕâЩ#defines²¢·ÇÑ¡Ôñ·û±¾Éí£¬¶øÖ»ÊÇÑ¡Ôñ·ûÖеÄINDEXÓò£¬ Òò´ËËüÃÇÕýÊÇÈ«¾ÖÃèÊö·û±íÖеÄË÷Òý¡£ ÀýÈ磬Äں˴úÂëµÄÑ¡Ôñ·û(GCODE_SEL)µÄֵΪ0x08¡£
¡¡¡¡ÏÂÒ»²½Êdzõʼ»¯ÖжÏÃèÊö·û±í(Interrupt Descriptor Table, IDT)¡£ ÕâÕűíÔÚ·¢ÉúÈí¼þ»òÓ²¼þÖжÏʱ»á±»´¦ÀíÆ÷ÒýÓá£ÀýÈ磬ִÐÐϵͳµ÷ÓÃʱ£¬ Óû§Ó¦ÓóÌÐòÌá½»INT 0x80 Ö¸Áî¡£ÕâÊÇÒ»¸öÈí¼þÖжϣ¬ ´¦ÀíÆ÷ÓÃË÷ÒýÖµ0x80ÔÚÖжÏÃèÊö·û±íÖвéÕҼǼ¡£Õâ¸ö¼Ç¼ָÏò´¦ÀíÕâ¸öÖжϵÄÀý³Ì¡£ ÔÚÕâ¸öÌØ¶¨ÇéÐÎÖУ¬ÕâÊÇÄں˵Äϵͳµ÷Óùؿڡ£
ÒëÕß×¢: Intel 80386Ö§³Ö¡°µ÷ÓÃÃÅ¡±£¬¿ÉÒÔʹµÃÓû§³ÌÐòֻͨ¹ýÒ»ÌõcallÖ¸Áî ¾Íµ÷ÓÃÄÚºËÖеÄÀý³Ì¡£¿ÉÊÇFreeBSD²¢Î´²ÉÓÃÕâÖÖ»úÖÆ£¬ Ò²ÐíÊÇÒòΪʹÓÃÈíÖжϽӿڿÉÃâÈ¥¶¯Ì¬Á´½ÓµÄÂé·³°É¡£ÁíÍ⻹ÓÐÒ»¸ö¸½´øµÄºÃ´¦£º ÔÚ·ÂÕæLinuxʱ£¬µ±Óöµ½FreeBSDÄں˲»Ö§³ÖµÄ¶øÓÖ²¢·Ç¹Ø¼üÐÔµÄϵͳµ÷ÓÃʱ£¬ ÄÚºËÖ»»áÏÔʾһЩ³ö´íÐÅÏ¢£¬ÕâʹµÃ³ÌÐòÄܹ»¼ÌÐøÔËÐУ» ¶ø²»ÊÇÔÚÕæÕýÖ´ÐгÌÐò֮ǰµÄ³õʼ»¯¹ý³ÌÖоÍÒòΪ¶¯Ì¬Á´½Óʧ°Ü¶ø²»ÔÊÐí³ÌÐòÔËÐС£
sys/i386/i386/machdep.c: static struct gate_descriptor idt0[NIDT]; struct gate_descriptor *idt = &idt0[0]; /* ÖжÏÃèÊö·û±í */
¡¡¡¡Ã¿¸öÖж϶¼±»ÉèÖÃÒ»¸öºÏÊʵÄÖжϴ¦Àí³ÌÐò¡£ ϵͳµ÷ÓùؿÚINT 0x80Ò²ÊÇÈç´Ë:
sys/i386/i386/machdep.c: setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
¡¡¡¡ËùÒÔµ±Ò»¸öÓû§Ó¦ÓóÌÐòÌá½»INT 0x80Ö¸Áîʱ£¬
ȫϵͳµÄ¿ØÖÆÈ¨»á´«µÝ¸øº¯Êý_Xint0x80_syscall
£¬
Õâ¸öº¯ÊýÔÚÄں˴úÂë¶ÎÖУ¬½«±»ÒÔ¹ÜÀíԱȨÏÞÖ´ÐС£
¡¡¡¡È»ºó£¬¿ØÖÆÌ¨ºÍDDB(µ÷ÊÔÆ÷)±»³õʼ»¯:
sys/i386/i386/machdep.c: cninit(); /* ÒÔÏ´úÂë¿ÉÄÜÒòΪ䶨ÒåºêDDB¶ø±»Ìø¹ý */ #ifdef DDB kdb_init(); if (boothowto & RB_KDB) Debugger("Boot flags requested debugger"); #endif
¡¡¡¡ÈÎÎñ״̬¶Î(TSS)ÊÇÁíÒ»¸öx86±£»¤Ä£Ê½ÖеÄÊý¾Ý½á¹¹¡£µ±·¢ÉúÈÎÎñÇл»Ê±£¬ ÈÎÎñ״̬¶ÎÓÃÀ´ÈÃÓ²¼þ´æ´¢ÈÎÎñÏÖ³¡ÐÅÏ¢¡£
¡¡¡¡¾Ö²¿ÃèÊö·û±í(LDT)ÓÃÀ´Ö¸ÏòÓû§´úÂëºÍÊý¾Ý¡£ÏµÍ³¶¨ÒåÁ˼¸¸öÑ¡Ôñ·û£¬ Ö¸Ïò¾Ö²¿ÃèÊö·û±í£¬ËüÃÇÊÇϵͳµ÷ÓùؿںÍÓû§´úÂë¡¢Óû§Êý¾ÝÑ¡Ôñ·û:
/usr/include/machine/segments.h #define LSYS5CALLS_SEL 0 /* Intel BCSÇ¿ÖÆÒªÇóµÄ */ #define LSYS5SIGR_SEL 1 #define L43BSDCALLS_SEL 2 /* ÉÐÎÞ */ #define LUCODE_SEL 3 #define LSOL26CALLS_SEL 4 /* Solaris >=2.6°æÏµÍ³µ÷ÓÃ¹Ø¿Ú */ #define LUDATA_SEL 5 /* separate stack, es,fs,gs sels ? ·Ö±ðµÄÕ»¡¢es¡¢fs¡¢gsÑ¡Ôñ·û£¿ */ /* #define LPOSIXCALLS_SEL 5*/ /* notyet, ÉÐÎÞ */ #define LBSDICALLS_SEL 16 /* BSDI system call gate, BSDIϵͳµ÷ÓÃ¹Ø¿Ú */ #define NLDT (LBSDICALLS_SEL + 1)
¡¡¡¡È»ºó£¬proc0(0ºÅ½ø³Ì£¬¼´ÄÚºËËù´¦µÄ½ø³Ì)µÄ½ø³Ì¿ØÖÆ¿é(Process Control Block) (struct pcb)½á¹¹±»³õʼ»¯¡£proc0ÊÇÒ»¸ö struct proc ½á¹¹£¬ÃèÊöÁËÒ»¸öÄں˽ø³Ì¡£ ÄÚºËÔËÐÐʱ£¬¸Ã½ø³Ì×ÜÊÇ´æÔÚ£¬ËùÒÔÕâ¸ö½á¹¹ÔÚÄÚºËÖб»¶¨ÒåΪȫ¾Ö±äÁ¿:
sys/kern/kern_init.c: struct proc proc0;
¡¡¡¡½á¹¹struct pcbÊÇproc½á¹¹µÄÒ»²¿·Ö£¬ Ëü¶¨ÒåÔÚ/usr/include/machine/pcb.hÖ®ÖУ¬ ÄÚº¬Õë¶Ôi386Ó²¼þ½á¹¹×¨ÓеÄÐÅÏ¢£¬Èç¼Ä´æÆ÷µÄÖµ¡£
mi_startup()
¡¡¡¡Õâ¸öº¯ÊýÓÃðÅÝÅÅÐòËã·¨£¬½«ËùÓÐϵͳ³õʼ»¯¶ÔÏó£¬È»ºóÖð¸öµ÷ÓÃÿ¸ö¶ÔÏóµÄÈë¿Ú:
sys/kern/init_main.c: for (sipp = sysinit; *sipp; sipp++) { /* ... Ê¡ÂÔ ... */ /* µ÷Óú¯Êý */ (*((*sipp)->func))((*sipp)->udata); /* ... Ê¡ÂÔ ... */ }
¡¡¡¡¾¡¹Üsysinit¿ò¼ÜÒѾÔÚ¡¶FreeBSD¿ª·¢ÕßÊֲᡷÖÐÓÐËùÃèÊö£¬ ÎÒ»¹ÊÇÔÚÕâÀïÌÖÂÛÒ»ÏÂÆäÄÚ²¿ÔÀí¡£
¡¡¡¡Ã¿¸öϵͳ³õʼ»¯¶ÔÏó(sysinit¶ÔÏó)ͨ¹ýµ÷Óú꽨Á¢¡£ ÈÃÎÒÃÇÒÔannounce sysinit¶ÔÏóΪÀý¡£ Õâ¸ö¶ÔÏó´òÓ¡°æÈ¨ÐÅÏ¢:
sys/kern/init_main.c: static void print_caddr_t(void *data __unused) { printf("%s", (char *)data); } SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
¡¡¡¡Õâ¸ö¶ÔÏóµÄ×Óϵͳ±êʶÊÇSI_SUB_COPYRIGHT(0x0800001)£¬ ÊýÖµ¸ÕºÃÅÅÔÚSI_SUB_CONSOLE(0x0800000)ºóÃæ¡£ ËùÒÔ£¬°æÈ¨ÐÅÏ¢½«ÔÚ¿ØÖÆÌ¨³õʼ»¯Ö®ºó¾Í±»ºÜÔçµÄ´òÓ¡³öÀ´¡£
¡¡¡¡ÈÃÎÒÃÇ¿´Ò»¿´ºêSYSINIT()µ½µ××öÁËЩʲô¡£ ËüÕ¹¿ª³ÉºêC_SYSINIT()¡£ ºêC_SYSINIT()È»ºóÕ¹¿ª³ÉÒ»¸ö¾²Ì¬½á¹¹ struct sysinit¡£½á¹¹ÀïÉêÃ÷Àïµ÷ÓÃÁËÁíÒ»¸öºê DATA_SET:
/usr/include/sys/kernel.h: #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ static struct sysinit uniquifier ## _sys_init = { \ subsystem, \ order, \ func, \ ident \ }; \ DATA_SET(sysinit_set,uniquifier ## _sys_init); #define SYSINIT(uniquifier, subsystem, order, func, ident) \ C_SYSINIT(uniquifier, subsystem, order, \ (sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)ident)
¡¡¡¡ºêDATA_SET()Õ¹¿ª³ÉMAKE_SET()£¬ ºêMAKE_SET()Ö¸ÏòËùÓÐÒþº¬µÄsysinit»ÃÊý:
/usr/include/linker_set.h #define MAKE_SET(set, sym) \ static void const * const __set_##set##_sym_##sym = &sym; \ __asm(".section .set." #set ",\"aw\""); \ __asm(".long " #sym); \ __asm(".previous") #endif #define TEXT_SET(set, sym) MAKE_SET(set, sym) #define DATA_SET(set, sym) MAKE_SET(set, sym)
¡¡¡¡»Øµ½ÎÒÃǵÄÀý×ÓÖУ¬¾¹ýºêµÄÕ¹¿ª¹ý³Ì£¬½«»á²úÉúÈçÏÂÉùÃ÷:
static struct sysinit announce_sys_init = { SI_SUB_COPYRIGHT, SI_ORDER_FIRST, (sysinit_cfunc_t)(sysinit_nfunc_t) print_caddr_t, (void *) copyright }; static void const *const __set_sysinit_set_sym_announce_sys_init = &announce_sys_init; __asm(".section .set.sysinit_set" ",\"aw\""); __asm(".long " "announce_sys_init"); __asm(".previous");
¡¡¡¡µÚÒ»¸ö__asmÖ¸ÁîÔÚÄں˿ÉÖ´ÐÐÎļþÖн¨Á¢Ò»¸öELF½Ú(section)¡£ Õâ·¢ÉúÔÚÄÚºËÁ´½ÓµÄʱºò¡£ÕâÒ»½Ú½«±»ÃüÁîΪ.set.sysinit_set¡£ ÕâÒ»½ÚµÄÄÚÈÝÊÇÒ»¸ö32λֵ¡ª¡ªannounce_sys_init½á¹¹µÄµØÖ·£¬Õâ¸ö½á¹¹ÕýÊǵڶþ¸ö __asmÖ¸ÁîËù¶¨ÒåµÄ¡£µÚÈý¸ö__asmÖ¸Áî±ê¼Ç½ÚµÄ½áÊø¡£ Èç¹ûÇ°ÃæÓÐÃû×ÖÏàͬµÄ½Ú¶¨ÒåÓï¾ä£¬½ÚµÄÄÚÈÝ(ÄǸö32λֵ)½«±»Ìî¼Óµ½ÒÑ´æÔڵĽÚÀ ÕâÑù¾Í¹¹Ôì³öÁËÒ»¸ö32λָÕëÊý×é¡£
¡¡¡¡ÓÃobjdump²ì¿´Ò»¸öÄں˶þ½øÖÆÎļþ£¬ Ò²ÐíÄã»á×¢Òâµ½ÀïÃæÓÐÕâô¼¸¸öСµÄ½Ú:
% objdump -h /kernel 7 .set.cons_set 00000014 c03164c0 c03164c0 002154c0 2**2 CONTENTS, ALLOC, LOAD, DATA 8 .set.kbddriver_set 00000010 c03164d4 c03164d4 002154d4 2**2 CONTENTS, ALLOC, LOAD, DATA 9 .set.scrndr_set 00000024 c03164e4 c03164e4 002154e4 2**2 CONTENTS, ALLOC, LOAD, DATA 10 .set.scterm_set 0000000c c0316508 c0316508 00215508 2**2 CONTENTS, ALLOC, LOAD, DATA 11 .set.sysctl_set 0000097c c0316514 c0316514 00215514 2**2 CONTENTS, ALLOC, LOAD, DATA 12 .set.sysinit_set 00000664 c0316e90 c0316e90 00215e90 2**2 CONTENTS, ALLOC, LOAD, DATA
¡¡¡¡ÕâÒ»ÆÁÐÅÏ¢ÏÔʾ±íÃ÷½Ú.set.sysinit_setÓÐ0x664×ֽڵĴóС£¬ ËùÒÔ0x664/sizeof(void *)¸ösysinit¶ÔÏó±»±àÒë½øÁËÄںˡ£ ÆäËü½Ú£¬Èç.set.sysctl_set±íʾÆäËüÁ´½ÓÆ÷¼¯ºÏ¡£
¡¡¡¡Í¨¹ý¶¨ÒåÒ»¸öÀàÐÍΪstruct linker_setµÄ±äÁ¿£¬ ½Ú.set.sysinit_set½«±»¡°ÊÕ¼¯¡±µ½ÄǸö±äÁ¿Àï:
sys/kern/init_main.c: extern struct linker_set sysinit_set; /* XXX */
¡¡¡¡struct linker_set¶¨ÒåÈçÏÂ:
/usr/include/linker_set.h: struct linker_set { int ls_length; void *ls_items[1]; /* ls_length¸öÏîµÄÊý×é, ÒÔNULL½áβ */ };
¡¡¡¡
ÒëÕß×¢: ʵ¼ÊÉÏÊÇ˵£¬ ÓÃCÓïÑԽṹÌålinker_setÀ´±í´ïÄǸöELF½Ú¡£
¡¡¡¡»Øµ½¶Ômi_startup()
µÄÌÖÂÛ£¬
ÎÒÃÇÇå³þÁËsysinit¶ÔÏóÊÇÈçºÎ±»×éÖ¯ÆðÀ´µÄ¡£ º¯Êými_startup()
½«ËüÃÇÅÅÐò£¬
²¢µ÷ÓÃÿһ¸ö¶ÔÏó¡£×îºóÒ»¸ö¶ÔÏóÊÇϵͳµ÷¶ÈÆ÷:
/usr/include/sys/kernel.h: enum sysinit_sub_id { SI_SUB_DUMMY = 0x0000000, /* ²»±»Ö´ÐУ¬½ö¹©Á´½ÓÆ÷ʹÓà */ SI_SUB_DONE = 0x0000001, /* Òѱ»´¦Àí*/ SI_SUB_CONSOLE = 0x0800000, /* ¿ØÖÆÌ¨*/ SI_SUB_COPYRIGHT = 0x0800001, /* ×îÔçʹÓÿØÖÆÌ¨µÄ¶ÔÏó */ ... SI_SUB_RUN_SCHEDULER = 0xfffffff /* µ÷¶ÈÆ÷:²»·µ»Ø */ };
¡¡¡¡ÏµÍ³µ÷¶ÈÆ÷sysinit¶ÔÏó¶¨ÒåÔÚÎļþsys/vm/vm_glue.cÖУ¬
Õâ¸ö¶ÔÏóµÄÈë¿ÚµãÊÇscheduler()
¡£
Õâ¸öº¯Êýʵ¼ÊÉÏÊǸöÎÞÏÞÑ»·£¬Ëü±íʾÄǸö½ø³Ì±êʶ(PID)Ϊ0µÄ½ø³Ì¡ª¡ªswapper½ø³Ì¡£
Ç°ÃæÌáµ½µÄproc0½á¹¹ÕýÊÇÓÃÀ´ÃèÊöÕâ¸ö½ø³Ì¡£
¡¡¡¡µÚÒ»¸öÓû§½ø³ÌÊÇinit£¬ ÓÉsysinit¶ÔÏóinit½¨Á¢:
sys/kern/init_main.c: static void create_init(const void *udata __unused) { int error; int s; s = splhigh(); error = fork1(&proc0, RFFDG | RFPROC, &initproc); if (error) panic("cannot fork init: %d\n", error); initproc->p_flag |= P_INMEM | P_SYSTEM; cpu_set_fork_handler(initproc, start_init, NULL); remrunqueue(initproc); splx(s); } SYSINIT(init,SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
¡¡¡¡create_init()
ͨ¹ýµ÷ÓÃfork1()
·ÖÅäÒ»¸öеĽø³Ì£¬µ«²¢²»½«Æä±ê¼ÇΪ¿ÉÔËÐС£µ±Õâ¸öнø³Ì±»µ÷¶ÈÆ÷µ÷¶ÈÖ´ÐÐʱ£¬ start_init()
½«»á±»µ÷ÓᣠÄǸöº¯Êý¶¨ÒåÔÚinit_main.cÖС£ Ëü³¢ÊÔ×°ÔØ²¢Ö´Ðжþ½øÖÆ´úÂëinit£¬ Ïȳ¢ÊÔ/sbin/init£¬È»ºóÊÇ/sbin/oinit£¬ /sbin/init.bak£¬×îºóÊÇ/stand/sysinstall:
sys/kern/init_main.c: static char init_path[MAXPATHLEN] = #ifdef INIT_PATH __XSTRING(INIT_PATH); #else "/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall"; #endif
¡¡¡¡ÕâÒ»ÕÂÓÉ FreeBSD SMP Next Generation Project ά»¤¡£ Ç뽫ÆÀÂۺͽ¨Òé·¢Ë͸øFreeBSD ¶Ô³Æ¶à´¦Àí (SMP) ÓʼþÁбí.
¡¡¡¡ÕâÆªÎĵµÌá¸ÙêüÁìµÄ½²ÊöÁËÔÚFreeBSDÄÚºËÖеÄËø£¬ÕâÐ©ËøÊ¹µÃÓÐЧµÄ¶à´¦Àí³ÉΪ¿ÉÄÜ¡£ Ëø¿ÉÒÔÓü¸ÖÖ·½Ê½»ñµÃ¡£Êý¾Ý½á¹¹¿ÉÒÔÓÃmutex»òlockmgr(9)±£»¤¡£ ¶ÔÓÚΪÊý²»¶àµÄÈô¸É¸ö±äÁ¿£¬¼ÙÈç×ÜÊÇʹÓÃÔ×Ó²Ù×÷·ÃÎÊËüÃÇ£¬ÕâЩ±äÁ¿¾Í¿ÉÒԵõ½±£»¤¡£
ÒëÕß×¢: ½ö¶Á±¾ÕÂÄÚÈÝ£¬»¹²»×ãÒÔÕÒ³ö¡°mutex¡± ºÍ¡°¹²Ïí»¥³âËø¡±µÄÇø±ð¡£ËƺõËüÃǵŦÄÜÓÐÖØµþÖ®´¦£¬ ǰÕ߱ȺóÕߵŦÄÜÑ¡Ïî¸ü¶à¡£ËüÃÇËÆºõ¶¼ÊÇlockmgr(9)µÄ×Ó¼¯¡£
¡¡¡¡Mutex¾ÍÊÇÒ»ÖÖÓÃÀ´½â¾ö¹²Ïí/ÅÅËüì¶ÜµÄËø¡£ Ò»¸ömutexÔÚÒ»¸öʱ¿ÌÖ»¿ÉÒÔ±»Ò»¸öʵÌåÓµÓС£Èç¹ûÁíÒ»¸öʵÌåÒª»ñµÃÒѾ±»ÓµÓеÄmutex£¬ ¾Í»á½øÈëµÈ´ý£¬Ö±µ½Õâ¸ömutex±»ÊÍ·Å¡£ÔÚFreeBSDÄÚºËÖУ¬mutex±»½ø³ÌËùÓµÓС£
¡¡¡¡Mutex¿ÉÒÔ±»µÝ¹éµÄË÷Òª£¬µ«ÊÇmutexÒ»°ãÖ»±»Ò»¸öʵÌåÓµÓн϶̵ÄÒ»¶Îʱ¼ä£¬ Òò´ËÒ»¸öʵÌå²»ÄÜÔÚ³ÖÓÐmutexʱ˯Ãß¡£Èç¹ûÄãÐèÒªÔÚ³ÖÓÐmutexʱ˯Ãߣ¬ ¿ÉʹÓÃÒ»¸ö lockmgr(9) µÄËø¡£
¡¡¡¡Ã¿¸ömutexÓм¸¸öÁîÈ˸ÐÐËȤµÄÊôÐÔ:
ÔÚÄÚºËÔ´´úÂëÖÐstruct mtx±äÁ¿µÄÃû×Ö
Óɺ¯Êýmtx_init
Ö¸ÅɵÄmutexµÄÃû×Ö¡£
Õâ¸öÃû×ÖÏÔʾÔÚKTR¸ú×ÙÏûÏ¢ºÍwitness³ö´íÓ뾯¸æÐÅÏ¢Àï¡£
Õâ¸öÃû×Ö»¹ÓÃÓÚÇø·Ö±êʶÔÚwitness´úÂëÖеĸ÷¸ömutex
MutexµÄÀàÐÍ£¬ÓñêÖ¾MTX_*
±íʾ¡£ ÿ¸ö±êÖ¾µÄÒâÒåÔÚmutex(9)ÓÐËùÃèÊö¡£
MTX_DEF
Ò»¸ö˯Ãßmutex
MTX_SPIN
Ò»¸öÑ»·mutex
MTX_RECURSE
Õâ¸ömutexÔÊÐíµÝ¹é
Õâ¸öÈë¿ÚËùÒª±£»¤µÄÊý¾Ý½á¹¹Áбí»òÊý¾Ý½á¹¹³ÉÔ±ÁÐ±í¡£ ¶ÔÓÚÊý¾Ý½á¹¹³ÉÔ±£¬½«°´ÕÕ
½á¹¹Ãû
.³ÉÔ±Ãû
µÄÐÎʽÃüÃû¡£
½öµ±mutex±»³ÖÓÐʱ²Å¿ÉÒÔ±»µ÷Óõĺ¯Êý
±í 2-1. MutexÁбí
±äÁ¿Ãû | Âß¼Ãû | ÀàÐÍ | ±£»¤¶ÔÏó | ÒÀÀµº¯Êý |
---|---|---|---|---|
sched_lock | ¡°sched lock¡±(µ÷¶ÈÆ÷Ëø) | MTX_SPIN | MTX_RECURSE |
_gmonparam , cnt.v_swtch ,
cp_time , curpriority ,
mtx .mtx_blocked ,
mtx .mtx_contested ,
proc .p_procq ,
proc .p_slpq ,
proc .p_sflag ,
proc .p_stat ,
proc .p_estcpu ,
proc .p_cpticks
proc .p_pctcpu ,
proc .p_wchan ,
proc .p_wmesg ,
proc .p_swtime ,
proc .p_slptime ,
proc .p_runtime ,
proc .p_uu ,
proc .p_su ,
proc .p_iu ,
proc .p_uticks ,
proc .p_sticks ,
proc .p_iticks ,
proc .p_oncpu ,
proc .p_lastcpu ,
proc .p_rqindex ,
proc .p_heldmtx ,
proc .p_blocked ,
proc .p_mtxname ,
proc .p_contested ,
proc .p_priority ,
proc .p_usrpri ,
proc .p_nativepri ,
proc .p_nice ,
proc .p_rtprio ,
pscnt , slpque , itqueuebits , itqueues , rtqueuebits , rtqueues , queuebits , queues , idqueuebits , idqueues , switchtime , switchticks |
setrunqueue , remrunqueue , mi_switch , chooseproc , schedclock , resetpriority , updatepri ,
maybe_resched , cpu_switch ,
cpu_throw , need_resched ,
resched_wanted , clear_resched , aston , astoff , astpending , calcru , proc_compare |
vm86pcb_lock | ¡°vm86pcb lock¡±(ÐéÄâ8086ģʽ½ø³Ì¿ØÖÆ¿éËø) | MTX_DEF |
vm86pcb |
vm86_bioscall |
Giant | ¡°Giant¡±(¾ÞËø) | MTX_DEF | MTX_RECURSE |
¼¸ºõ¿ÉÒÔÊÇÈκζ«Î÷ | Ðí¶à |
callout_lock | ¡°callout lock¡±(ÑÓʱµ÷ÓÃËø) | MTX_SPIN | MTX_RECURSE |
callfree , callwheel ,
nextsoftcheck , proc .p_itcallout , proc .p_slpcallout , softticks , ticks |
¡¡¡¡ÕâÐ©ËøÌṩ»ù±¾µÄ¶Á/дÀàÐ͵ŦÄÜ£¬¿ÉÒÔ±»Ò»¸öÕýÔÚ˯ÃߵĽø³Ì³ÖÓС£ ÏÖÔÚËüÃDZ»Í³Ò»µ½lockmgr(9)Ö®ÖС£
¡¡¡¡Ô×Ó±£»¤±äÁ¿²¢·ÇÓÉÒ»¸öÏÔÔÚµÄËø±£»¤µÄÌØÊâ±äÁ¿£¬¶øÊÇ£º ¶ÔÕâЩ±äÁ¿µÄËùÓÐÊý¾Ý·ÃÎʶ¼ÒªÊ¹ÓÃÌØÊâµÄÔ×Ó²Ù×÷(atomic(9))¡£ ¾¡¹ÜÆäËüµÄ»ù±¾Í¬²½»úÖÆ(ÀýÈçmutex)¾ÍÊÇÓÃÔ×Ó±£»¤±äÁ¿ÊµÏֵģ¬ µ«ÊǺÜÉÙÓбäÁ¿Ö±½ÓʹÓÃÕâÖÖ´¦Àí·½Ê½¡£
mtx
.mtx_lock
¡¡¡¡Äں˶ÔÏó£¬Ò²¾ÍÊÇKobj£¬ÎªÄÚºËÌṩÁËÒ»ÖÖÃæÏò¶ÔÏó µÄCÓïÑÔ±à³Ì·½Ê½¡£±»²Ù×÷µÄÊý¾ÝÒ²³ÐÔØ²Ù×÷ËüµÄ·½·¨¡£ ÕâʹµÃÔÚ²»ÆÆ»µ¶þ½øÖƼæÈÝÐÔµÄǰÌáÏ£¬Ä³Ò»¸ö½Ó¿ÚÄܹ»Ôö/¼õÏàÓ¦µÄ²Ù×÷¡£
Êý¾Ý¼¯ºÏ-Êý¾Ý½á¹¹-Êý¾Ý·ÖÅäµÄ¼¯ºÏ
ijһÖÖ²Ù×÷©¤©¤º¯Êý
Ò»ÖÖ»ò¶àÖÖ·½·¨
Ò»ÖÖ»ò¶àÖÖ·½·¨µÄÒ»¸ö±ê×¼¼¯ºÏ
ÒëÕß×¢: ÕâһС½ÚÁ½¶ÎÂäÖÐÔ×÷ÕßµÄÓôÊÓÐЩº¬»ì£¬ Çë²Î¿¼ÎÒÔÚÀ¨ºÅÖеÄ×¢ÊÍÔĶÁ¡£
¡¡¡¡Kobj¹¤×÷ʱ£¬²úÉú·½·¨µÄÃèÊö¡£Ã¿¸öÃèÊöÓÐÒ»¸öΨһµÄ±êʶºÍÒ»¸öȱʡº¯Êý¡£ ij¸öÃèÊöµÄµØÖ·±»ÓÃÀ´ÔÚÒ»¸öÀàµÄ·½·¨±íÀïΨһµÄ±êʶ·½·¨¡£
¡¡¡¡¹¹½¨Ò»¸öÀ࣬¾ÍÊÇÒª½¨Á¢Ò»ÕÅ·½·¨±í£¬²¢½«ÕâÕÅ±í¹ØÁªµ½Ò»¸ö»ò¶à¸öº¯Êý(·½·¨)£» ÕâЩº¯Êý(·½·¨)¶¼´øÓз½·¨ÃèÊö¡£Ê¹ÓÃǰ£¬ÀàÒª±»±àÒë¡£±àÒëʱҪΪÕâ¸öÀà·ÖÅäһЩ»º´æ¡£ ÔÚ·½·¨±íÖеÄÿ¸ö·½·¨ÃèÊö¶¼»á±»Ö¸ÅÉÒ»¸öΨһµÄ±êʶ£¬ ³ý·ÇÒѾ±»ÆäËüÒýÓÃËüµÄÀàÔÚ±àÒëʱָÅÉÁ˱êʶ¡£¶ÔÓÚÿ¸ö½«Òª±»Ê¹Óõķ½·¨£¬ ¶¼»áÓɽű¾Éú³ÉÒ»¸öº¯Êý(·½·¨²éÕÒº¯Êý)£¬ÒÔ½âÎöÍâÀ´²ÎÊý£¬ ²¢ÔÚ±»²éѯʱ¸ø³ö·½·¨ÃèÊöµÄµØÖ·¡£±»Éú³ÉµÄº¯Êý(·½·¨²éÕÒº¯Êý) ƾ×ÅÄǸö·½·¨ÃèÊöµÄΨһ±êʶ°´HashµÄ·½·¨²éÕÒ¶ÔÏóµÄÀàµÄ»º´æ¡£ Èç¹ûÕâ¸ö·½·¨²»ÔÚ»º´æÖУ¬º¯Êý»á²éÕÒʹÓÃÀàµÄ·½·¨±í¡£Èç¹ûÕâ¸ö·½·¨±»ÕÒµ½ÁË£¬ ÀàÀïµÄÏà¹Øº¯Êý(Ò²¾ÍÊÇij¸ö·½·¨µÄʵÏÖ´úÂë)¾Í»á±»Ê¹Óᣠ·ñÔò£¬Õâ¸ö·½·¨ÃèÊöµÄȱʡº¯Êý½«±»Ê¹Óá£
¡¡¡¡ÕâЩ¹ý³Ì¿É±»±íʾÈçÏ£º
¶ÔÏó->»º´æ<->Àà
struct kobj_method
void kobj_class_compile(kobj_class_t cls); void kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops); void kobj_class_free(kobj_class_t cls); kobj_t kobj_create(kobj_class_t cls, struct malloc_type *mtype, int mflags); void kobj_init(kobj_t obj, kobj_class_t cls); void kobj_delete(kobj_t obj, struct malloc_type *mtype);
¡¡¡¡Ê¹ÓÃKobjµÄµÚÒ»²½Êǽ¨Á¢Ò»¸ö½Ó¿Ú¡£½¨Á¢½Ó¿Ú°üÀ¨½¨Á¢Ä£°åµÄ¹¤×÷¡£ ½¨Á¢Ä£°å¿ÉÓýű¾src/sys/kern/makeobjops.plÍê³É£¬ Ëü»á²úÉúÉêÃ÷·½·¨µÄÍ·ÎļþºÍ´úÂ룬½Å±¾»¹»áÉú³É·½·¨²éÕÒº¯Êý¡£
¡¡¡¡ÔÚÕâ¸öÄ£°åÖÐÈçϹؼü´Ê»á±»Ê¹ÓÃ: #include, INTERFACE, CODE, METHOD, STATICMETHOD, ºÍ DEFAULT.
¡¡¡¡#includeÓï¾äµÄÕûÐÐÄÚÈݽ«±»Ò»×Ö²»²îµÄ ¸´ÖƵ½±»Éú³ÉµÄ´úÂëÎļþµÄÍ·²¿¡£
¡¡¡¡ÀýÈç:
#include <sys/foo.h>
¡¡¡¡¹Ø¼ü´ÊINTERFACEÓÃÀ´¶¨Òå½Ó¿ÚÃû¡£ Õâ¸öÃû×Ö½«Óëÿ¸ö·½·¨Ãû½ÓºÏÔÚÒ»Æð£¬ÐÎ³É [interface name]_[method name]¡£ Óï·¨ÊÇ£ºINTERFACE [½Ó¿ÚÃû];
¡¡¡¡ÀýÈç:
INTERFACE foo;
¡¡¡¡¹Ø¼ü´ÊCODE»á½«ËüµÄ²ÎÊýÒ»×Ö²»²îµÄ¸´ÖƵ½´úÂëÎļþÖС£ Óï·¨ÊÇCODE { [ÈκδúÂë] };
¡¡¡¡ÀýÈç:
CODE { struct foo * foo_alloc_null(struct bar *) { return NULL; } };
¡¡¡¡¹Ø¼ü´ÊMETHODÓÃÀ´ÃèÊöÒ»¸ö·½·¨¡£Óï·¨ÊÇ: METHOD [·µ»ØÖµÀàÐÍ] [·½·¨Ãû] { [¶ÔÏó [, ²ÎÊýÈô¸É]] };
¡¡¡¡ÀýÈç:
METHOD int bar { struct object *; struct foo *; struct bar; };
¡¡¡¡¹Ø¼ü´ÊDEFAULT¸úÔڹؼü´ÊMETHODÖ®ºó£¬ ÊǶԹؼü´ÊMETHODµÄ²¹³ä¡£Ëü¸øÕâ¸ö·½·¨²¹³äÉÏȱʡº¯Êý¡£Óï·¨ÊÇ£º METHOD [·µ»ØÖµÀàÐÍ] [·½·¨Ãû] { [¶ÔÏó; [ÆäËü²ÎÊý]] }DEFAULT [ȱʡº¯Êý];
¡¡¡¡ÀýÈç:
METHOD int bar { struct object *; struct foo *; int bar; } DEFAULT foo_hack;
¡¡¡¡¹Ø¼ü´ÊSTATICMETHODÀàËÆ¹Ø¼ü´ÊMETHOD¡£ ¶ÔÓÚÿ¸öKobj¶ÔÏó£¬Ò»°ãÆäÍ·²¿¶¼ÓÐһЩKobjרÓеÄÊý¾Ý¡£ METHOD¶¨ÒåµÄ·½·¨¾Í¼ÙÉèÕâЩרÓÐÊý¾ÝλÓÚ¶ÔÏóÍ·²¿£» ¼ÙÈç¶ÔÏóÍ·²¿Ã»ÓÐÕâЩרÓÐÊý¾Ý£¬ÕâЩ·½·¨¶ÔÕâ¸ö¶ÔÏóµÄ·ÃÎʾͿÉÄܳö´í¡£ ¶øSTATICMETHOD¶¨ÒåµÄ¶ÔÏó¿ÉÒÔ²»ÊÜÕâ¸öÏÞÖÆ£º ÕâÑùÃèÊö³öµÄ·½·¨£¬Æä²Ù×÷µÄÊý¾Ý²»ÓÉÕâ¸öÀàµÄij¸ö¶ÔÏóʵÀý¸ø³ö£¬ ¶øÊÇÈ«¶¼Óɵ÷ÓÃÕâ¸ö·½·¨Ê±µÄ²Ù×÷Êý(ÒëÕß×¢:¼´²ÎÊý)¸ø³ö¡£ ÕâÒ²¶ÔÓÚÔÚij¸öÀàµÄ·½·¨±íÖ®Íâµ÷ÓÃÕâ¸ö·½·¨ÓÐÓá£
ÒëÕß×¢: ÕâÒ»¶ÎµÄÓïÑÔÓëÔÎÄÏà±Èµ÷ÕûºÜ´ó¡£ ¾²Ì¬·½·¨ÊDz»ÒÀÀµÓÚ¶ÔÏóʵÀýµÄ·½·¨¡£ ²Î¿´C++ÀàÖеġ°¾²Ì¬º¯Êý¡±µÄ¸ÅÄî¡£
¡¡¡¡ÆäËüÍêÕûµÄÀý×Ó:
src/sys/kern/bus_if.m src/sys/kern/device_if.m
¡¡¡¡Ê¹ÓÃKobjµÄµÚ¶þ²½Êǽ¨Á¢Ò»¸öÀà¡£Ò»¸öÀàµÄ×éÓÐÃû×Ö¡¢·½·¨±í£»
¼ÙÈçʹÓÃÁËKobjµÄ¡°¶ÔÏó¹ÜÀí¹¤¾ß¡±(Object Handling Facilities)£¬
ÀàÖл¹°üº¬¶ÔÏóµÄ´óС¡£½¨Á¢ÀàʱʹÓúêDEFINE_CLASS()
¡£
½¨Á¢·½·¨±íʱ£¬Ð뽨Á¢Ò»¸ökobj_method_tÊý×飬ÓÃNULLÏî½áβ¡£ ÿ¸ö·ÇNULLÏî¿ÉÓúêKOBJMETHOD()
½¨Á¢¡£
¡¡¡¡ÀýÈç:
DEFINE_CLASS(fooclass, foomethods, sizeof(struct foodata)); kobj_method_t foomethods[] = { KOBJMETHOD(bar_doo, foo_doo), KOBJMETHOD(bar_foo, foo_foo), { NULL, NULL} };
¡¡¡¡ÀàÐë±»¡°±àÒ롱¡£¸ù¾Ý¸ÃÀà±»³õʼ»¯Ê±ÏµÍ³µÄ״̬£¬
½«ÒªÓõ½Ò»¸ö¾²Ì¬·ÖÅäµÄ»º´æºÍ¡°²Ù×÷Êý±í¡±(ops table£¬
ÒëÕß×¢£º¼´¡°²ÎÊý±í¡±)¡£ÕâЩ²Ù×÷¿Éͨ¹ýÉùÃ÷Ò»¸ö½á¹¹Ìå struct
kobj_ops
²¢Ê¹Óà kobj_class_compile_static()
£¬
»òÊÇֻʹÓÃkobj_class_compile()
À´Íê³É¡£
¡¡¡¡Ê¹ÓÃKobjµÄµÚÈý²½ÊǶ¨Òå¶ÔÏó¡£Kobj¶ÔÏó½¨Á¢³ÌÐò¼Ù¶¨Kobj
רÓÐÊý¾ÝÔÚÒ»¸ö¶ÔÏóµÄÍ·²¿¡£Èç¹û²»ÊÇÈç´Ë£¬Ó¦µ±ÏÈ×ÔÐзÖÅä¶ÔÏó£¬ ÔÙʹÓÃkobj_init()
³õʼ»¯¶ÔÏóÖеÄKobjרÓÐÊý¾Ý£» Æäʵ¿ÉÒÔʹÓÃkobj_create()
·ÖÅä¶ÔÏó£¬ ²¢×Ô¶¯³õʼ»¯¶ÔÏóÖеÄKobjרÓÐÄÚÈÝ¡£kobj_init()
Ò²¿ÉÒÔÓÃÀ´¸Ä±äÒ»¸ö¶ÔÏóËùʹÓõÄÀà¡£
¡¡¡¡½«KobjµÄÊý¾Ý¼¯³Éµ½¶ÔÏóÖÐҪʹÓúêKOBJ_FIELDS¡£
¡¡¡¡ÀýÈç
struct foo_data { KOBJ_FIELDS; foo_foo; foo_bar; };
¡¡¡¡Ê¹ÓÃKobjµÄ×îºóÒ»²¿¾ÍÊÇͨ¹ýÉú³ÉµÄº¯Êýµ÷ÓöÔÏóÀàÖеķ½·¨¡£ µ÷ÓÃʱ£¬½Ó¿ÚÃûÓë·½·¨ÃûÓÃ'_'½ÓºÏ£¬¶øÇÒÈ«²¿Ê¹Óôóд×Öĸ¡£
¡¡¡¡ÀýÈ磬½Ó¿ÚÃûΪfoo£¬·½·¨Îªbar£¬µ÷ÓþÍÊÇ:
[·µ»ØÖµ = ] FOO_BAR(¶ÔÏó [, ÆäËü²ÎÊý]);
¡¡¡¡µ±Ò»¸öÓÃkobj_create()
²»ÔÙÐèÒª±»Ê¹ÓÃʱ£¬
¿É¶ÔÕâ¸ö¶ÔÏóµ÷ÓÃkobj_delete()
¡£ µ±Ò»¸öÀ಻ÔÙÐèÒª±»Ê¹ÓÃʱ£¬
¿É¶ÔÕâ¸öÀàµ÷ÓÃkobj_class_free()
¡£
¡¡¡¡ÔÚ´ó¶àÊýUNIX®ÏµÍ³ÖУ¬Óû§rootÊÇÍòÄܵġ£ÕâÒ²¾ÍÔö¼ÓÁËÐí¶àΣÏÕ¡£ Èç¹ûÒ»¸ö¹¥»÷Õß»ñµÃÁËÒ»¸öϵͳÖеÄroot£¬¾Í¿ÉÒÔÔÚËûµÄÖ¸¼âÕÆÎÕϵͳÖÐËùÓеŦÄÜ¡£ ÔÚFreeBSDÀÓÐһЩsysctlÏîÏ÷ÈõÁËrootµÄȨÏÞ£¬ ÕâÑù¾Í¿ÉÒÔ½«¹¥»÷ÕßÔì³ÉµÄË𺦼õСµ½×îµÍÏÞ¶È¡£ÕâЩ°²È«¹¦ÄÜÖУ¬ÓÐÒ»Öֽа²È«¼¶±ð¡£ ÁíÒ»ÖÖÔÚFreeBSD 4.0¼°ÒÔºó°æ±¾ÖÐÌṩµÄ°²È«¹¦ÄÜ£¬¾ÍÊÇjail(8)¡£ Jail½«Ò»¸öÔËÐл·¾³µÄÎļþÊ÷¸ùÇл»µ½Ä³Ò»Ìض¨Î»Ö㬠²¢ÇÒ¶ÔÕâÑù»·¾³Öвæ·ÖÉú³ÉµÄ½ø³Ì×ö³öÏÞÖÆ¡£ÀýÈ磬 Ò»¸ö±»¼à½ûµÄ½ø³Ì²»ÄÜÓ°ÏìÕâ¸öjailÖ®ÍâµÄ½ø³Ì¡¢²»ÄÜʹÓÃÒ»Ð©ÌØ¶¨µÄϵͳµ÷Ó㬠Ҳ¾Í²»ÄܶÔÖ÷¼ÆËã»úÔì³ÉÆÆ»µ¡£
ÒëÕß×¢: Ó¢Îĵ¥´Ê¡°jail¡±µÄÖÐÎÄÒâ˼ÊÇ¡°Çô½û¡¢¼à½û¡±¡£
¡¡¡¡JailÒѾ³ÉΪһÖÖÐÂÐ͵ݲȫģÐÍ¡£ ÈËÃÇ¿ÉÒÔÔÚjailÖÐÔËÐи÷ÖÖ¿ÉÄܴܺàÈõµÄ·þÎñÆ÷³ÌÐò£¬ÈçApache¡¢ BINDºÍsendmail¡£ ÕâÑùÒ»À´£¬¼´Ê¹Óй¥»÷ÕßÈ¡µÃÁËjailÖеÄroot£¬ Õâ×î¶àÈÃÈËÃÇÖåÖåüͷ£¬¶ø²»»áʹÈËÃǾª»Åʧ´ë¡£ ±¾ÎÄÖ÷Òª¹Ø×¢jailµÄÄÚ²¿ÔÀí(Ô´´úÂë)¡£ Èç¹ûÄãÕýÔÚѰÕÒÉèÖÃJailµÄÖ¸ÄÏÐÔÎĵµ£¬ ÎÒ½¨ÒéÄãÔĶÁÎÒµÄÁíһƪÎÄÕ£¬·¢±íÔÚSys Admin Magazine, May 2001, ¡¶Securing FreeBSD using Jail¡·¡£
¡¡¡¡JailÓÉÁ½²¿·Ö×é³É£ºÓû§¼¶³ÌÐò£¬ Ò²¾ÍÊÇjail(8)£»»¹ÓÐÔÚÄÚºËÖÐJailµÄʵÏÖ´úÂ룺jail(2) ϵͳµ÷ÓúÍÏà¹ØµÄÔ¼Êø¡£ÎÒ½«ÌÖÂÛÓû§¼¶³ÌÐòºÍjailÔÚÄÚºËÖеÄʵÏÖÔÀí¡£
¡¡¡¡JailµÄÓû§¼¶Ô´´úÂëÔÚ/usr/src/usr.sbin/jail£¬ ÓÉÒ»¸öÎļþjail.c×é³É¡£Õâ¸ö³ÌÐòÓÐÕâЩ²ÎÊý£ºjailµÄ·¾¶£¬ Ö÷»úÃû£¬IPµØÖ·£¬»¹ÓÐÐèÒªÖ´ÐеÄÃüÁî¡£
¡¡¡¡ÔÚjail.cÖУ¬ÎÒ½«×îÏÈ×¢½âµÄÊÇÒ»¸öÖØÒª½á¹¹Ìå struct jail j;µÄÉùÃ÷£¬Õâ¸ö½á¹¹ÀàÐ͵ÄÉùÃ÷°üº¬ÔÚ /usr/include/sys/jail.hÖ®ÖС£
¡¡¡¡jail½á¹¹µÄ¶¨ÒåÊÇ£º
/usr/include/sys/jail.h: struct jail { u_int32_t version; char *path; char *hostname; u_int32_t ip_number; };
¡¡¡¡ÕýÈçÄãËù¼û£¬´«Ë͸øÃüÁîjail(8)µÄÿ¸ö²ÎÊý¶¼ÔÚÕâÀïÓжÔÓ¦µÄÒ»Ïî¡£ ÊÂʵÉÏ£¬µ±ÃüÁîjail(8)±»Ö´ÐÐʱ£¬ÕâЩ²ÎÊý²ÅÓÉÃüÁîÐÐÕæÕý´«È룺
/usr/src/usr.sbin/jail.c char path[PATH_MAX]; ... if(realpath(argv[0], path) == NULL) err(1, "realpath: %s", argv[0]); if (chdir(path) != 0) err(1, "chdir: %s", path); memset(&j, 0, sizeof(j)); j.version = 0; j.path = path; j.hostname = argv[1];
¡¡¡¡´«¸øjail(8)µÄ²ÎÊýÖÐÓÐÒ»¸öÊÇIPµØÖ·¡£ÕâÊÇÔÚÍøÂçÉÏ·ÃÎÊjailʱµÄµØÖ·¡£ jail(8)½«IPµØÖ··Òë³ÉÍøÂç×Ö½Ú˳Ðò£¬²¢´æÈëj(jailÀàÐ͵ĽṹÌå)¡£
/usr/src/usr.sbin/jail/jail.c: struct in_addr in; ... if (inet_aton(argv[2], &in) == 0) errx(1, "Could not make sense of ip-number: %s", argv[2]); j.ip_number = ntohl(in.s_addr);
¡¡¡¡º¯Êýinet_aton(3)¡°½«Ö¸¶¨µÄ×Ö·û´®½âÊÍΪһ¸öInternetµØÖ·£¬ ²¢½«Æäת´æµ½Ö¸¶¨µÄ½á¹¹ÌåÖС±¡£inet_aton(3)É趨Á˽ṹÌåin£¬ Ö®ºóinÖеÄÄÚÈÝÔÙÓÃntohl(3)ת»»³ÉÖ÷»ú×Ö½Ú˳Ðò£¬ ²¢ÖÃÈëjail½á¹¹ÌåµÄip_number³ÉÔ±¡£
¡¡¡¡×îºó£¬Óû§¼¶³ÌÐòÇô½û½ø³Ì¡£ÏÖÔÚJail×ÔÉí±ä³ÉÁËÒ»¸ö±»Çô½ûµÄ½ø³Ì£¬ ²¢Ê¹ÓÃexecv(3)Ö´ÐÐÓû§Ö¸¶¨µÄÃüÁî¡£
/usr/src/usr.sbin/jail/jail.c i = jail(&j); ... if (execv(argv[3], argv + 3) != 0) err(1, "execv: %s", argv[3]);
¡¡¡¡ÕýÈçÄãËù¼û£¬º¯Êýjail()±»µ÷Ó㬲ÎÊýÊǽṹÌåjailÖб»ÌîÈëÊý¾ÝÏ ¶øÈçǰËùÊö£¬ÕâЩÊý¾ÝÏîÓÖÀ´×Ôjail(8)µÄÃüÁîÐвÎÊý¡£ ×îºó£¬Ö´ÐÐÁËÓû§Ö¸¶¨µÄÃüÁî¡£ÏÂÃæÎÒ½«¿ªÊ¼ÌÖÂÛjailÔÚÄÚºËÖеÄʵÏÖ¡£
¡¡¡¡ÏÖÔÚÎÒÃÇÀ´¿´Îļþ/usr/src/sys/kern/kern_jail.c¡£ ÔÚÕâÀﶨÒåÁËjail(2)µÄϵͳµ÷Óá¢Ïà¹ØµÄsysctlÏ»¹ÓÐÍøÂ纯Êý¡£
¡¡¡¡ÔÚkern_jail.cÀﶨÒåÁËÈçÏÂsysctlÏî:
/usr/src/sys/kern/kern_jail.c: int jail_set_hostname_allowed = 1; SYSCTL_INT(_security_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, &jail_set_hostname_allowed, 0, "Processes in jail can set their hostnames"); /* JailÖеĽø³Ì¿ÉÉ趨×ÔÉíµÄÖ÷»úÃû */ int jail_socket_unixiproute_only = 1; SYSCTL_INT(_security_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW, &jail_socket_unixiproute_only, 0, "Processes in jail are limited to creating UNIX/IPv4/route sockets only"); /* JailÖеĽø³Ì±»ÏÞÖÆÖ»Äܽ¨Á¢UNIXÌ×½Ó×Ö¡¢IPv4Ì×½Ó×Ö¡¢Â·ÓÉÌ×½Ó×Ö */ int jail_sysvipc_allowed = 0; SYSCTL_INT(_security_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW, &jail_sysvipc_allowed, 0, "Processes in jail can use System V IPC primitives"); /* JailÖеĽø³Ì¿ÉÒÔʹÓÃSystem V½ø³Ì¼äͨѶÔÓï */ static int jail_enforce_statfs = 2; SYSCTL_INT(_security_jail, OID_AUTO, enforce_statfs, CTLFLAG_RW, &jail_enforce_statfs, 0, "Processes in jail cannot see all mounted file systems"); /* jail ÖеĽø³Ì²é¿´ÏµÍ³ÖйҽӵÄÎļþϵͳʱÊܵ½ºÎÖÖÏÞÖÆ */ int jail_allow_raw_sockets = 0; SYSCTL_INT(_security_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW, &jail_allow_raw_sockets, 0, "Prison root can create raw sockets"); /* jail ÖÐµÄ root Óû§ÊÇ·ñ¿ÉÒÔ´´½¨ raw socket */ int jail_chflags_allowed = 0; SYSCTL_INT(_security_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW, &jail_chflags_allowed, 0, "Processes in jail can alter system file flags"); /* jail ÖеĽø³ÌÊÇ·ñ¿ÉÒÔÐÞ¸Äϵͳ¼¶Îļþ±ê¼Ç */ int jail_mount_allowed = 0; SYSCTL_INT(_security_jail, OID_AUTO, mount_allowed, CTLFLAG_RW, &jail_mount_allowed, 0, "Processes in jail can mount/unmount jail-friendly file systems"); /* jail ÖеĽø³ÌÊÇ·ñ¿ÉÒÔ¹ÒÔØ»òÐ¶ÔØ¶ÔjailÓѺõÄÎļþϵͳ */
¡¡¡¡ÕâЩsysctlÏîÖеÄÿһ¸ö¶¼¿ÉÒÔÓÃÃüÁîsysctl(8)·ÃÎÊ¡£ÔÚÕû¸öÄÚºËÖУ¬ ÕâЩsysctlÏî°´Ãû³Æ±êʶ¡£ÀýÈ磬ÉÏÊöµÚÒ»¸ösysctlÏîµÄÃû×ÖÊÇ security.jail.set_hostname_allowed¡£
¡¡¡¡ÏñËùÓеÄϵͳµ÷ÓÃÒ»Ñù£¬ÏµÍ³µ÷ÓÃjail(2)´øÓÐÁ½¸ö²ÎÊý£¬ struct thread *tdºÍstruct jail_args *uap¡£ tdÊÇÒ»¸öÖ¸Ïòthread½á¹¹ÌåµÄÖ¸Õ룬¸ÃÖ¸ÕëÓÃÓÚÃèÊöµ÷ÓÃjail(2)µÄÏ̡߳£ ÔÚÕâ¸öÉÏÏÂÎÄÖУ¬uapÖ¸ÏòÒ»¸ö½á¹¹Ì壬Õâ¸ö½á¹¹ÌåÖаüº¬ÁËÒ»¸öÖ¸Ïò´ÓÓû§¼¶ jail.c´«Ë͹ýÀ´µÄjail½á¹¹ÌåµÄÖ¸Õë¡£ ÔÚÇ°ÃæÎÒ½²ÊöÓû§¼¶³ÌÐòʱ£¬ÄãÒѾ¿´µ½¹ýÒ»¸öjail½á¹¹Ìå±»×÷Ϊ²ÎÊý´«Ë͸øÏµÍ³µ÷Óà jail(2)¡£
/usr/src/sys/kern/kern_jail.c: /* * struct jail_args { * struct jail *jail; * }; */ int jail(struct thread *td, struct jail_args *uap)
¡¡¡¡ÓÚÊÇuap->jail¿ÉÒÔÓÃÓÚ·ÃÎʱ»´«µÝ¸øjail(2)µÄjail½á¹¹Ìå¡£ È»ºó£¬jail(2)ʹÓÃcopyin(9)½«jail½á¹¹Ì叴֯µ½ÄÚºËÄÚ´æ¿Õ¼äÖС£ copyin(9)ÐèÒªÈý¸ö²ÎÊý£ºÒª¸´ÖƽøÄÚºËÄÚ´æ¿Õ¼äµÄÊý¾ÝµÄµØÖ· uap->jail£¬ÔÚÄÚºËÄÚ´æ¿Õ¼ä´æ·ÅÊý¾ÝµÄj£¬ ÒÔ¼°Êý¾ÝµÄ´óС¡£uap->jailÖ¸ÏòµÄJail½á¹¹Ìå±»¸´ÖƽøÄÚºËÄÚ´æ¿Õ¼ä£¬ ²¢±»´æ·ÅÔÚÁíÒ»¸öjail½á¹¹ÌåjÀï¡£
/usr/src/sys/kern/kern_jail.c: error = copyin(uap->jail, &j, sizeof(j));
¡¡¡¡ÔÚjail.hÖж¨ÒåÁËÁíÒ»¸öÖØÒªµÄ½á¹¹ÌåÐÍprison¡£ ½á¹¹ÌåprisonÖ»±»ÓÃÔÚÄں˿ռäÖС£ ÏÂÃæÊÇprison½á¹¹ÌåµÄ¶¨Òå¡£
/usr/include/sys/jail.h: struct prison { LIST_ENTRY(prison) pr_list; /* (a) all prisons */ int pr_id; /* (c) prison id */ int pr_ref; /* (p) refcount */ char pr_path[MAXPATHLEN]; /* (c) chroot path */ struct vnode *pr_root; /* (c) vnode to rdir */ char pr_host[MAXHOSTNAMELEN]; /* (p) jail hostname */ u_int32_t pr_ip; /* (c) ip addr host */ void *pr_linux; /* (p) linux abi */ int pr_securelevel; /* (p) securelevel */ struct task pr_task; /* (d) destroy task */ struct mtx pr_mtx; void **pr_slots; /* (p) additional data */ };
¡¡¡¡È»ºó£¬ÏµÍ³µ÷ÓÃjail(2)Ϊһ¸öprison½á¹¹Ìå·ÖÅäÒ»¿éÄڴ棬 ²¢ÔÚjailºÍprison½á¹¹ÌåÖ®¼ä¸´ÖÆÊý¾Ý¡£
/usr/src/sys/kern/kern_jail.c: MALLOC(pr, struct prison *, sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); ... error = copyinstr(j.path, &pr->pr_path, sizeof(pr->pr_path), 0); if (error) goto e_killmtx; ... error = copyinstr(j.hostname, &pr->pr_host, sizeof(pr->pr_host), 0); if (error) goto e_dropvnref; pr->pr_ip = j.ip_number;
¡¡¡¡ÏÂÃæ£¬ÎÒÃǽ«ÌÖÂÛÁíÍâÒ»¸öÖØÒªµÄϵͳµ÷ÓÃjail_attach(2)£¬ËüʵÏÖÁ˽«½ø³Ì¼à½ûµÄ¹¦ÄÜ¡£
/usr/src/sys/kern/kern_jail.c /* * struct jail_attach_args { * int jid; * }; */ int jail_attach(struct thread *td, struct jail_attach_args *uap)
¡¡¡¡Õâ¸öϵͳµ÷ÓÃ×ö³öһЩ¿ÉÒÔÓÃÓÚÇø·Ö±»¼à½ûºÍδ±»¼à½ûµÄ½ø³ÌµÄ¸Ä±ä¡£ ÒªÀí½âjail_attach(2)ΪÎÒÃÇ×öÁËʲô£¬ÎÒÃÇÊ×ÏÈÒªÀí½âһЩ±³¾°ÐÅÏ¢¡£
¡¡¡¡ÔÚFreeBSDÖУ¬Ã¿¸ö¶ÔÄں˿ɼûµÄÏß³ÌÊÇͨ¹ýÆäthread½á¹¹ÌåÀ´Ê¶±ðµÄ£¬ ͬʱ£¬½ø³Ì¶¼ÓÉËüÃÇ×Ô¼ºµÄproc½á¹¹ÌåÃèÊö¡£ Äã¿ÉÒÔÔÚ/usr/include/sys/proc.hÖÐÕÒµ½threadºÍproc½á¹¹ÌåµÄ¶¨Òå¡£ ÀýÈ磬ÔÚÈκÎϵͳµ÷ÓÃÖУ¬²ÎÊýtdʵ¼ÊÉÏÊǸöÖ¸Ïòµ÷ÓÃÏ̵߳Äthread½á¹¹ÌåµÄÖ¸Õ룬 ÕýÈçÇ°ÃæËù˵µÄÄÇÑù¡£tdËùÖ¸ÏòµÄthread½á¹¹ÌåÖеÄtd_proc³ÉÔ±ÊÇÒ»¸öÖ¸Õ룬 Õâ¸öÖ¸ÕëÖ¸ÏòtdËù±íʾµÄÏß³ÌËùÊô½ø³ÌµÄproc½á¹¹Ìå¡£ ½á¹¹Ìåproc°üº¬µÄ³ÉÔ±¿ÉÒÔÃèÊöËùÓÐÕßµÄÉí·Ý (p_ucred)£¬½ø³Ì×ÊÔ´ÏÞÖÆ(p_limit)£¬ µÈµÈ¡£ÔÚÓÉproc½á¹¹ÌåµÄp_ucred³ÉÔ±ËùÖ¸ÏòµÄucred½á¹¹ÌåµÄ¶¨ÒåÖУ¬ »¹ÓÐÒ»¸öÖ¸Ïòprison½á¹¹ÌåµÄÖ¸Õë(cr_prison)¡£
/usr/include/sys/proc.h: struct thread { ... struct proc *td_proc; ... }; struct proc { ... struct ucred *p_ucred; ... }; /usr/include/sys/ucred.h struct ucred { ... struct prison *cr_prison; ... };
¡¡¡¡ÔÚkern_jail.cÖУ¬º¯Êýjail()ÒÔ¸ø¶¨µÄjid µ÷Óú¯Êýjail_attach()¡£Ëæºójail_attach()µ÷Óú¯Êýchange_root()ÒÔ¸Ä±ä µ÷Óýø³ÌµÄ¸ùĿ¼¡£½ÓÏÂÀ´£¬jail_attach()´´½¨Ò»¸öеÄucred½á¹¹Ì壬²¢ÔÚ ³É¹¦µØ½«prison½á¹¹ÌåÁ¬½Óµ½Õâ¸öucred½á¹¹Ìåºó£¬½«Õâ¸öucred½á¹¹ÌåÁ¬½Ó µ½µ÷Óýø³ÌÉÏ¡£´Ó´ËʱÆð£¬Õâ¸öµ÷Óýø³Ì¾Í»á±»Ê¶±ðΪ±»¼à½ûµÄ¡£ µ±ÎÒÃÇÒÔд´½¨µÄÕâ¸öucred½á¹¹ÌåΪ²ÎÊýµ÷ÓÃÄں˷¾¶jailed()ʱ£¬ Ëü½«·µ»Ø1À´ËµÃ÷Õâ¸öÓû§Éí·ÝÊǺÍÒ»¸öjailÏàÁ¬µÄ¡£ ÔÚjailÖвæ·Ö³öÀ´µÄËùÓнø³ÌµÄµÄ¹«¹²×æÏȽø³Ì¾ÍÊÇÕâ¸öÖ´ÐÐÁËjail(2)µÄ½ø³Ì£¬ ÒòΪÕýÊÇËüµ÷ÓÃÁËjail(2)ϵͳµ÷Óᣵ±Ò»¸ö³ÌÐòͨ¹ýexecve(2)¶ø±»Ö´ÐÐʱ£¬ Ëü½«´ÓÆä¸¸½ø³ÌµÄucred½á¹¹Ìå¼Ì³Ð±»¼à½ûµÄÊôÐÔ£¬ Òò¶øËüÒ²»áÓµÓÐÒ»¸ö±»¼à½ûµÄucred½á¹¹Ìå¡£
/usr/src/sys/kern/kern_jail.c int jail(struct thread *td, struct jail_args *uap) { ... struct jail_attach_args jaa; ... error = jail_attach(td, &jaa); if (error) goto e_dropprref; ... } int jail_attach(struct thread *td, struct jail_attach_args *uap) { struct proc *p; struct ucred *newcred, *oldcred; struct prison *pr; ... p = td->td_proc; ... pr = prison_find(uap->jid); ... change_root(pr->pr_root, td); ... newcred->cr_prison = pr; p->p_ucred = newcred; ... }
¡¡¡¡µ±Ò»¸ö½ø³Ì±»´ÓÆä¸¸½ø³Ì²æ·ÖÀ´µÄʱºò£¬ ϵͳµ÷ÓÃfork(2)½«ÓÃcrhold()À´Î¬»¤ÆäÉí·Ýƾ֤¡£ ÕâÑù£¬ºÜ×ÔÈ»µÄ¾Í±£³ÖÁË×Ó½ø³ÌµÄÉí·Ýƾ֤ÓÚÆä¸¸½ø³ÌÒ»Ö£¬ËùÒÔ×Ó½ø³ÌÒ²ÊDZ»¼à½ûµÄ¡£
/usr/src/sys/kern/kern_fork.c: p2->p_ucred = crhold(td->td_ucred); ... td2->td_ucred = crhold(p2->p_ucred);
¡¡¡¡ÔÚÕû¸öÄÚºËÖУ¬ÓÐһϵÁжԱ»Çô½û³ÌÐòµÄÔ¼Êø´ëÊ©¡£ ͨ³££¬ÕâÐ©Ô¼ÊøÖ»¶Ô±»Çô½ûµÄ³ÌÐòÓÐЧ¡£Èç¹ûÕâЩ³ÌÐòÊÔÍ¼Í»ÆÆÕâÐ©Ô¼Êø£¬ Ïà¹ØµÄº¯Êý½«³ö´í·µ»Ø¡£ÀýÈç:
if (jailed(td->td_ucred)) return EPERM;
¡¡¡¡System V ½ø³Ì¼äͨÐÅ (IPC) ÊÇͨ¹ýÏûϢʵÏֵġ£ ÿ¸ö½ø³Ì¶¼¿ÉÒÔÏòÆäËü½ø³Ì·¢ËÍÏûÏ¢£¬ ¸æËß¶Ô·½¸Ã×öʲô¡£ ´¦ÀíÏûÏ¢µÄº¯ÊýÊÇ£º msgctl(3)¡¢msgget(3)¡¢msgsnd(3) ºÍ msgrcv(3)¡£Ç°ÃæÒѾÌáµ½£¬Ò»Ð© sysctl ¿ª¹Ø¿ÉÒÔÓ°Ïì jail µÄÐÐΪ£¬ ÆäÖÐÓÐÒ»¸öÊÇ security.jail.sysvipc_allowed¡£ ÔÚ´ó¶àÊýϵͳÉÏ£¬ Õâ¸ö sysctl Ïî»áÉè³É0¡£ Èç¹û½«ËüÉèΪ1£¬ Ôò»áÍêȫʧȥ jail µÄÒâÒ壺 ÒòΪÄÇÑùÔÚ jail ÖÐÌØÈ¨½ø³Ì¾Í¿ÉÒÔÓ°Ïì±»¼à½ûµÄ»·¾³ÍâµÄ½ø³ÌÁË¡£ ÏûÏ¢ÓëÐźŵÄÇø±ðÊÇ£ºÏûÏ¢½öÓÉÒ»¸öÐźűàºÅ×é³É¡£
¡¡¡¡/usr/src/sys/kern/sysv_msg.c:
msgget(key, msgflg): msgget·µ»Ø(Ò²¿ÉÄÜ´´½¨)Ò»¸öÏûÏ¢ÃèÊö·û£¬ ÒÔÖ¸ÅÉÒ»¸öÔÚÆäËüº¯ÊýÖÐʹÓõÄÏûÏ¢¶ÓÁС£
msgctl(msgid, cmd, buf): ͨ¹ýÕâ¸öº¯Êý£¬ Ò»¸ö½ø³Ì¿ÉÒÔ²éѯһ¸öÏûÏ¢ÃèÊö·ûµÄ״̬¡£
msgsnd(msgid, msgp, msgsz, msgflg): msgsndÏòÒ»¸ö½ø³Ì·¢ËÍÒ»ÌõÏûÏ¢¡£
msgrcv(msgid, msgp, msgsz, msgtyp, msgflg): ½ø³ÌÓÃÕâ¸öº¯Êý½ÓÊÕÏûÏ¢¡£
¡¡¡¡ÔÚÕâЩº¯Êý¶ÔÓ¦µÄϵͳµ÷ÓõĴúÂëÖУ¬¶¼ÓÐÕâÑùÒ»¸öÌõ¼þÅжϣº
/usr/src/sys/kern/sysv_msg.c: if (!jail_sysvipc_allowed && jailed(td->td_ucred)) return (ENOSYS);
¡¡¡¡ÐźÅÁ¿ÏµÍ³µ÷ÓÃʹµÃ½ø³Ì¿ÉÒÔͨ¹ýһϵÁÐÔ×Ó²Ù×÷ʵÏÖͬ²½¡£ ÐźÅÁ¿Îª½ø³ÌËø¶¨×ÊÔ´ÌṩÁËÓÖÒ»ÖÖ;¾¶¡£ È»¶ø£¬½ø³Ì½«ÎªÕýÔÚ±»Ê¹ÓõÄÐźÅÁ¿½øÈëµÈ´ý״̬£¬Ò»Ö±ÐÝÃßµ½×ÊÔ´±»ÊÍ·Å¡£ ÔÚjailÖÐÈçϵÄÐźÅÁ¿ÏµÍ³µ÷Óý«»áʧЧ: semget(2), semctl(2) ºÍsemop(2)¡£
¡¡¡¡/usr/src/sys/kern/sysv_sem.c:
semctl(semid, num, cmd, ...): semctl¶ÔÔÚÐźÅÁ¿¶ÓÁÐÖÐÓÃsemid±êʶµÄÐźÅÁ¿Ö´ÐÐcmdÖ¸¶¨µÄÃüÁî¡£
semget(key, nsems, flag): semget½¨Á¢Ò»¸ö¶ÔÓ¦ÓÚkeyµÄÐźÅÁ¿Êý×é¡£
²ÎÊýkeyºÍflagÓëËûÃÇÔÚmsgget()µÄÒâÒåÏàͬ¡£
setop(semid, array, nops): semop¶Ôsemid±êʶµÄÐźÅÁ¿Íê³ÉÒ»×éÓÉarrayËùÖ¸¶¨µÄ²Ù×÷¡£
¡¡¡¡System V IPCʹ½ø³Ì¼ä¿ÉÒÔ¹²ÏíÄÚ´æ¡£½ø³ÌÖ®¼ä¿ÉÒÔͨ¹ýËüÃÇÐéÄâµØÖ·¿Õ¼ä µÄ¹²Ïí²¿·ÖÒÔ¼°Ïà¹ØÊý¾Ý¶Áд²Ù×÷Ö±½ÓͨѶ¡£ÕâЩϵͳµ÷ÓÃÔÚ±»¼à½ûµÄ»·¾³Öн«»áʧЧ: shmdt(2)¡¢shmat(2)¡¢shmctl(2)ºÍshmget(2)
¡¡¡¡/usr/src/sys/kern/sysv_shm.c:
shmctl(shmid, cmd, buf): shmctl¶Ôid±êʶµÄ¹²ÏíÄÚ´æÇøÓò×ö¸÷ÖÖ¸÷ÑùµÄ¿ØÖÆ¡£
shmget(key, size, flag): shmget½¨Á¢/´ò¿ªsize×ֽڵĹ²ÏíÄÚ´æÇøÓò¡£
shmat(shmid, addr, flag): shmat½«shmid±êʶµÄ¹²ÏíÄÚ´æÇøÓòÖ¸Åɵ½½ø³ÌµÄµØÖ·¿Õ¼äÀï¡£
shmdt(addr): shmdtÈ¡Ïû¹²ÏíÄÚ´æÇøÓòµÄµØÖ·Ö¸ÅÉ¡£
¡¡¡¡JailÒÔÒ»ÖÖÌØÊâµÄ·½Ê½´¦Àísocket(2)ϵͳµ÷ÓúÍÏà¹ØµÄµÍ¼¶Ì×½Ó×Öº¯Êý¡£ ΪÁ˾ö¶¨Ò»¸öÌ×½Ó×ÖÊÇ·ñÔÊÐí±»´´½¨£¬ËüÏȼì²ésysctlÏî security.jail.socket_unixiproute_onlyÊÇ·ñ±»ÉèÖÃΪ1¡£ Èç¹û±»ÉèΪ1£¬Ì×½Ó×Ö½¨Á¢Ê±½«Ö»ÄÜÖ¸¶¨ÕâЩÐÒé×壺 PF_LOCAL, PF_INET, PF_ROUTE¡£·ñÔò£¬socket(2)½«»á·µ»Ø³ö´í¡£
/usr/src/sys/kern/uipc_socket.c: int socreate(int dom, struct socket **aso, int type, int proto, struct ucred *cred, struct thread *td) { struct protosw *prp; ... if (jailed(cred) && jail_socket_unixiproute_only && prp->pr_domain->dom_family != PF_LOCAL && prp->pr_domain->dom_family != PF_INET && prp->pr_domain->dom_family != PF_ROUTE) { return (EPROTONOSUPPORT); } ... }
¡¡¡¡Berkeley°ü¹ýÂËÆ÷ÌṩÁËÒ»¸öÓëÐÒéÎ޹صģ¬Ö±½ÓͨÏòÊý¾ÝÁ´Â·²ãµÄµÍ¼¶½Ó¿Ú¡£ ÏÖÔÚBPFÊÇ·ñ¿ÉÒÔÔÚ¼à½ûµÄ»·¾³Öб»Ê¹ÓÃÊÇͨ¹ýdevfs(8)À´¿ØÖƵġ£
¡¡¡¡ÍøÂçÐÒéTCP, UDP, IPºÍICMPºÜ³£¼û¡£IPºÍICMP´¦ÓÚͬһÐÒé²ã´Î£ºµÚ¶þ²ã£¬ ÍøÂç²ã¡£µ±²ÎÊýnam±»ÉèÖÃʱ£¬ ÓÐһЩÏÞÖÆ´ëÊ©»á·ÀÖ¹±»Çô½ûµÄ³ÌÐò°ó¶¨µ½Ò»Ð©ÍøÂç½Ó¿ÚÉÏ¡£ namÊÇÒ»¸öÖ¸Ïòsockaddr½á¹¹ÌåµÄÖ¸Õ룬 ÃèÊö¿ÉÒ԰󶨷þÎñµÄµØÖ·¡£Ò»¸ö¸üÈ·Çе͍Ò壺sockaddr¡°ÊÇÒ»¸öÄ£°å£¬°üº¬Á˵ØÖ·µÄ±êʶ·ûºÍµØÖ·µÄ³¤¶È¡±¡£ ÔÚº¯Êýin_pcbbind_setup()ÖÐsinÊÇÒ»¸öÖ¸Ïòsockaddr_in½á¹¹ÌåµÄÖ¸Õ룬 Õâ¸ö½á¹¹Ìå°üº¬ÁËÌ×½Ó×Ö¿ÉÒ԰󶨵Ķ˿ڡ¢µØÖ·¡¢³¤¶È¡¢ÐÒé×å¡£ Õâ¾Í½ûÖ¹ÁËÔÚjailÖеĽø³ÌÖ¸¶¨²»ÊôÓÚÕâ¸ö½ø³ÌËù´æÔÚÓÚµÄjailµÄIPµØÖ·¡£
/usr/src/sys/kern/netinet/in_pcb.c: int in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, u_short *lportp, struct ucred *cred) { ... struct sockaddr_in *sin; ... if (nam) { sin = (struct sockaddr_in *)nam; ... if (sin->sin_addr.s_addr != INADDR_ANY) if (prison_ip(cred, 0, &sin->sin_addr.s_addr)) return(EINVAL); ... if (lport) { ... if (prison && prison_ip(cred, 0, &sin->sin_addr.s_addr)) return (EADDRNOTAVAIL); ... } } if (lport == 0) { ... if (laddr.s_addr != INADDR_ANY) if (prison_ip(cred, 0, &laddr.s_addr)) return (EINVAL); ... } ... if (prison_ip(cred, 0, &laddr.s_addr)) return (EINVAL); ... }
¡¡¡¡ÄãÒ²ÐíÏëÖªµÀº¯Êýprison_ip()×öʲô¡£ prison_ip()ÓÐÈý¸ö²ÎÊý£¬Ò»¸öÖ¸ÏòÉí·Ýƾ֤µÄÖ¸Õë(ÓÃcred±íʾ)£¬ һЩ±êÖ¾ºÍÒ»¸öIPµØÖ·¡£µ±Õâ¸öIPµØÖ·²»ÊôÓÚÕâ¸öjailʱ£¬·µ»Ø1£» ·ñÔò·µ»Ø0¡£ÕýÈçÄã´Ó´úÂëÖп´¼ûµÄ£¬Èç¹û£¬ÄǸöIPµØÖ·È·Êµ²»ÊôÓÚÕâ¸öjail£¬ ¾Í²»ÔÙÔÊÐíÏòÕâ¸öÍøÂçµØÖ·°ó¶¨ÐÒé¡£
/usr/src/sys/kern/kern_jail.c: int prison_ip(struct ucred *cred, int flag, u_int32_t *ip) { u_int32_t tmp; if (!jailed(cred)) return (0); if (flag) tmp = *ip; else tmp = ntohl(*ip); if (tmp == INADDR_ANY) { if (flag) *ip = cred->cr_prison->pr_ip; else *ip = htonl(cred->cr_prison->pr_ip); return (0); } if (tmp == INADDR_LOOPBACK) { if (flag) *ip = cred->cr_prison->pr_ip; else *ip = htonl(cred->cr_prison->pr_ip); return (0); } if (cred->cr_prison->pr_ip != tmp) return (1); return (0); }
¡¡¡¡Èç¹ûÍêÈ«¼¶±ð´óÓÚ0£¬¼´±ãÊÇjailÀïÃæµÄroot£¬ Ò²²»ÔÊÐíÔÚJailÖÐÈ¡Ïû»ò¸ü¸ÄÎļþ±êÖ¾£¬Èç¡°²»¿ÉÐ޸ġ±¡¢¡°Ö»¿ÉÌí¼Ó¡±¡¢¡°²»¿Éɾ³ý¡±±êÖ¾¡£
/usr/src/sys/ufs/ufs/ufs_vnops.c: static int ufs_setattr(ap) ... { ... if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0)) { if (ip->i_flags & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { error = securelevel_gt(cred, 0); if (error) return (error); } ... } } /usr/src/sys/kern/kern_priv.c int priv_check_cred(struct ucred *cred, int priv, int flags) { ... error = prison_priv_check(cred, priv); if (error) return (error); ... } /usr/src/sys/kern/kern_jail.c int prison_priv_check(struct ucred *cred, int priv) { ... switch (priv) { ... case PRIV_VFS_SYSFLAGS: if (jail_chflags_allowed) return (0); else return (EPERM); ... } ... }
¡¡¡¡SYSINITÊÇÒ»¸öͨÓõĵ÷ÓÃÅÅÐòÓë·Ö±ðÖ´ÐлúÖÆµÄ¿ò¼Ü¡£ FreeBSDĿǰʹÓÃËüÀ´½øÐÐÄں˵Ķ¯Ì¬³õʼ»¯¡£ SYSINITʹµÃFreeBSDµÄÄں˸÷×Óϵͳ¿ÉÒÔÔÚÄں˻òÄ£¿é¶¯Ì¬¼ÓÔØÁ´½Óʱ±»ÖØÕû¡¢ Ìí¼Ó¡¢É¾³ý¡¢Ìæ»»£¬ÕâÑù£¬Äں˺ÍÄ£¿é¼ÓÔØÊ±¾Í²»±ØÈ¥ÐÞ¸ÄÒ»¸ö¾²Ì¬µÄÓÐÐò³õʼ»¯ °²ÅűíÉõÖÁÖØÐ±àÒëÄںˡ£Õâ¸öÌåϵҲʹµÃÄÚºËÄ£¿é (ÏÖÔÚ³ÆÎªKLD¿ÉÒÔÓëÄں˲»Í¬Ê±±àÒë¡¢Á´½Ó¡¢ ÔÚÒýµ¼ÏµÍ³Ê±¼ÓÔØ£¬ÉõÖÁÔÚϵͳÔËÐÐʱ¼ÓÔØ¡£ÕâЩ²Ù×÷ÊÇͨ¹ý ¡°ÄÚºËÁ´½ÓÆ÷¡±(kernel linker)ºÍ¡°Á´½ÓÆ÷¼¯ºÏ¡± (linker set)Íê³ÉµÄ¡£
Ò»ÖÖÁ´½Ó·½·¨¡£ÕâÖÖ·½·¨½«Õû¸ö³ÌÐòÔ´ÎļþÖо²Ì¬ÉêÃ÷µÄÊý¾ÝÊÕ¼¯µ½ Ò»¸ö¿ÉÁÚ½üѰַµÄÊý¾Ýµ¥ÔªÖС£
¡¡¡¡SYSINITÒªÒÀ¿¿Á´½ÓÆ÷»ñÈ¡±é²¼Õû¸ö³ÌÐòÔ´´úÂë¶à´¦ÉêÃ÷µÄ¾²Ì¬Êý¾Ý ²¢°ÑËüÃÇ×é³ÉÒ»¸ö±Ë´ËÏàÁÚµÄÊý¾Ý¿é¡£ÕâÖÖÁ´½Ó·½·¨±»³ÆÎª ¡°Á´½ÓÆ÷¼¯ºÏ¡±(linker set)¡£ SYSINITʹÓÃÁ½¸öÁ´½ÓÆ÷¼¯ºÏÒÔά»¤Á½¸öÊý¾Ý¼¯ºÏ£¬ °üº¬Ã¿¸öÊý¾ÝÌõÄ¿µÄµ÷ÓÃ˳Ðò¡¢º¯Êý¡¢Ò»¸ö»á±»Ìá½»¸ø¸Ãº¯ÊýµÄÊý¾ÝÖ¸Õë¡£
¡¡¡¡SYSINIT°´ÕÕÁ½ÀàÓÅÏȼ¶±êʶ¶Ôº¯ÊýÅÅÐòÒÔ±ãÖ´ÐС£ µÚÒ»ÀàÓÅÏȼ¶µÄ±êʶÊÇ×ÓϵͳµÄ±êʶ£¬ ¸ø³öSYSINIT·Ö±ðÖ´ÐÐ×ÓϵͳµÄº¯ÊýµÄÈ«¾Ö˳Ðò£¬ ¶¨ÒåÔÚ<sys/kernel.h>ÖеÄö¾Ù sysinit_sub_idÄÚ¡£µÚ¶þÀàÓÅÏȼ¶±êʶÔÚ×ÓϵͳÖеÄÔªËØµÄ˳Ðò£¬ ¶¨ÒåÔÚ<sys/kernel.h>ÖеÄö¾Ù sysinit_elem_orderÄÚ¡£
¡¡¡¡ÓÐÁ½ÖÖʱ¿ÌÐèҪʹÓÃSYSINIT£ºÏµÍ³Æô¶¯»òÄÚºËÄ£¿é¼ÓÔØÊ±£¬ ϵͳÎö¹¹»òÄÚºËÄ£¿éÐ¶ÔØÊ±¡£ÄÚºË×Óϵͳͨ³£ÔÚϵͳÆô¶¯Ê±Ê¹ÓÃSYSINIT µÄ¶¨ÒåÏîÒÔ³õʼ»¯Êý¾Ý½á¹¹¡£ÀýÈ磬½ø³Ìµ÷¶È×ÓϵͳʹÓÃÒ»¸öSYSINIT ¶¨ÒåÏîÀ´³õʼ»¯ÔËÐжÓÁÐÊý¾Ý½á¹¹¡£É豸Çý¶¯³ÌÐòÓ¦±ÜÃâÖ±½ÓʹÓà SYSINIT()£¬¶ÔÓÚ×ÜÏ߽ṹÉϵÄÎïÀíÕæÊµÉ豸ӦʹÓà DRIVER_MODULE()µ÷Óõĺ¯ÊýÏÈÕì²âÉ豸µÄ´æÔÚ£¬ Èç¹û´æÔÚ£¬ÔÙ½øÐÐÉ豸µÄ³õʼ»¯¡£Õâһϵͳ¹ý³ÌÖУ¬ »á×öһЩרÃÅÕë¶ÔÉ豸µÄÊÂÇ飬Ȼºóµ÷ÓÃSYSINIT()±¾Éí¡£ ¶ÔÓÚ·Ç×ÜÏ߽ṹһ²¿·ÖµÄÐéÉ豸£¬Ó¦¸ÄÓÃDEV_MODULE()¡£
<sys/kernel.h>
SYSINIT(uniquifier, subsystem, order, func, ident) SYSUNINIT(uniquifier, subsystem, order, func, ident)
¡¡¡¡ºêSYSINIT()ÔÚSYSINITÆô¶¯Êý¾Ý¼¯ºÏÖÐ ½¨Á¢Ò»¸öSYSINITÊý¾ÝÏÒÔ±ãSYSINITÔÚϵͳÆô¶¯»òÄ£¿é¼ÓÔØÊ±ÅÅÐò ²¢Ö´ÐÐÆäÖеĺ¯Êý¡£SYSINIT()ÓÐÒ»¸ö²ÎÊýuniquifier£¬ SYSINITÓÃËüÀ´±êʶÊý¾ÝÏî£¬ËæºóÊÇ×Óϵͳ˳ÐòºÅ¡¢×ÓÏµÍ³ÔªËØË³ÐòºÅ¡¢ ´ýµ÷Óú¯Êý¡¢´«µÝ¸øº¯ÊýµÄÊý¾Ý¡£ËùÓеĺ¯Êý±ØÐëÓÐÒ»¸öºãÁ¿Ö¸Õë²ÎÊý¡£
Àý 5-1. SYSINIT()µÄÀý×Ó
#include <sys/kernel.h> void foo_null(void *unused) { foo_doo(); } SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_null, NULL); struct foo foo_voodoo = { FOO_VOODOO; } void foo_arg(void *vdata) { struct foo *foo = (struct foo *)vdata; foo_data(foo); } SYSINIT(bar, SI_SUB_FOO, SI_ORDER_FOO, foo_arg, &foo_voodoo);
¡¡¡¡×¢Ò⣬SI_SUB_FOOºÍSI_ORDER_FOO Ó¦µ±·Ö±ðÔÚÉÏÃæÌáµ½µÄö¾Ùsysinit_sub_idºÍ sysinit_elem_orderÖ®ÖС£¼È¿ÉÒÔʹÓÃÒÑÓеÄö¾ÙÏ Ò²¿ÉÒÔ½«×Ô¼ºµÄö¾ÙÏîÌí¼Óµ½ÕâÁ½¸öö¾ÙµÄ¶¨ÒåÖ®ÖС£ Äã¿ÉÒÔʹÓÃÊýѧ±í´ïʽ΢µ÷SYSINITµÄÖ´ÐÐ˳Ðò¡£ ÒÔϵÄÀý×ÓʾÀýÁËÒ»¸öÐèÒª¸ÕºÃÒªÔÚÄں˲ÎÊýµ÷ÕûµÄSYSINIT֮ǰִÐеÄSYSINIT¡£
¡¡¡¡ºêSYSUNINIT()µÄÐÐΪÓëSYSINIT()µÄÏ൱£¬ Ö»ÊÇËü½«Êý¾ÝÏîÌî¼ÓÖÁSYSINITµÄÎö¹¹Êý¾Ý¼¯ºÏ¡£
Àý 5-3. SYSUNINIT()µÄÀý×Ó
#include <sys/kernel.h> void foo_cleanup(void *unused) { foo_kill(); } SYSUNINIT(foobar, SI_SUB_FOO, SI_ORDER_FOO, foo_cleanup, NULL); struct foo_stack foo_stack = { FOO_STACK_VOODOO; } void foo_flush(void *vdata) { } SYSUNINIT(barfoo, SI_SUB_FOO, SI_ORDER_FOO, foo_flush, &foo_stack);
¡¡¡¡±¾ÎĵµÊÇ×÷Ϊ DARPA CHATS Ñо¿¼Æ»®µÄÒ»²¿·Ö£¬Óɹ©Ö°ÓÚ Security Research Division of Network Associates ¹«Ë¾Safeport Network Services and Network Associates Laboratories µÄChris CostelloÒÀ¾Ý DARPA/SPAWAR ºÏͬ N66001-01-C-8035 (¡°CBOSS¡±)£¬Îª FreeBSD ÏîÄ¿±àдµÄ¡£
¡¡¡¡Redistribution and use in source (SGML DocBook) and 'compiled' forms (SGML, HTML, PDF, PostScript, RTF and so forth) with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code (SGML DocBook) must retain the above copyright notice, this list of conditions and the following disclaimer as the first lines of this file unmodified.
Redistributions in compiled form (transformed to other DTDs, converted to PDF, PostScript, RTF and other formats) must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
ÖØÒª: THIS DOCUMENTATION IS PROVIDED BY THE NETWORKS ASSOCIATES TECHNOLOGY, INC "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETWORKS ASSOCIATES TECHNOLOGY, INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ÖØÒª: ±¾ÎÄÖÐÐí¿ÉÖ¤µÄ·Ç¹Ù·½ÖÐÎÄ·Òë½ö¹©²Î¿¼£¬ ²»×÷ΪÅж¨ÈκÎÔðÈεÄÒÀ¾Ý¡£ÈçÓëÓ¢ÎÄÔÎÄÓгöÈ룬ÔòÒÔÓ¢ÎÄÔÎÄΪ׼¡£
¡¡¡¡ÔÚÂú×ãÏÂÁÐÐí¿ÉÌõ¼þµÄǰÌáÏ£¬ÔÊÐíÔÙ·Ö·¢»òÒÔÔ´´úÂë (SGML DocBook) »ò ¡°±àÒ롱 (SGML, HTML, PDF, PostScript, RTF µÈ) µÄ¾¹ýÐ޸ĻòδÐ޸ĵÄÐÎʽ£º
ÔÙ·Ö·¢Ô´´úÂë (SGML DocBook) ±ØÐë²»¼ÓÐ޸ĵı£ÁôÉÏÊö°æÈ¨¸æÊ¾¡¢±¾Ìõ¼þÇåµ¥ºÍÏÂÊöÆúȨÊé×÷Ϊ¸ÃÎļþµÄ×îÏÈÈô¸ÉÐС£
ÔÙ·Ö·¢±àÒëµÄÐÎʽ (ת»»ÎªÆäËüDTD¡¢ PDF¡¢ PostScript¡¢ RTF »òÆäËüÐÎʽ)£¬±ØÐ뽫ÉÏÊö°æÈ¨¸æÊ¾¡¢ ±¾Ìõ¼þÇåµ¥ºÍÏÂÊöÆúȨÊ鏴֯µ½Óë·Ö·¢Æ·Ò»Í¬ÌṩµÄÎļþ£¬ÒÔ¼°ÆäËü²ÄÁÏÖС£
ÖØÒª: ±¾ÎĵµÓÉ NETWORKS ASSOCIATES TECHNOLOGY, INC ¡°°´ÏÖ×´Ìõ¼þ¡±Ìṩ£¬²¢ÔÚ´ËÃ÷ʾ²»ÌṩÈκÎÃ÷ʾ»ò°µÊ¾µÄ±£ÕÏ£¬ °üÀ¨µ«²»ÏÞÓÚ¶ÔÉÌÒµÊÊÏúÐÔ¡¢¶ÔÌØ¶¨Ä¿µÄµÄÊÊÓÃÐԵݵʾ±£ÕÏ¡£ÈκÎÇé¿öÏ£¬ NETWORKS ASSOCIATES TECHNOLOGY, INC ¾ù²»¶ÔÈκÎÖ±½Ó¡¢ ¼ä½Ó¡¢ żȻ¡¢ ÌØÊâ¡¢ ³Í·£ÐԵģ¬ »ò±ØÈ»µÄËðʧ (°üÀ¨µ«²»ÏÞÓÚÌæ´úÉÌÆ·»ò·þÎñµÄ²É¹º¡¢ ʹÓᢠÊý¾Ý»òÀûÒæµÄËðʧ»òÓªÒµÖжÏ) ¸ºÔ𣬠ÎÞÂÛÊÇÈçºÎµ¼ÖµIJ¢ÒÔÈκÎÓÐÔðÈÎÂß¼µÄ£¬ ÎÞÂÛÊÇ·ñÊÇÔÚ±¾ÎĵµÊ¹ÓÃÒÔÍâÒÔÈκη½Ê½²úÉúµÄÆõÔ¼¡¢ÑϸñÔðÈλòÊÇÃñÊÂÇÖȨÐÐΪ(°üÀ¨Êèºö»òÆäËü)Öеģ¬ ¼´Ê¹Òѱ»¸æÖª·¢Éú¸ÃËðʧµÄ¿ÉÄÜÐÔ¡£
¡¡¡¡FreeBSD ÒÔÒ»¸öÄں˰²È«À©Õ¹ÐÔ¿ò¼Ü(TrustedBSD MAC ¿ò¼Ü)µÄ·½Ê½£¬ÎªÈô¸ÉÇ¿ÖÆ·ÃÎÊ¿ØÖƲßÂÔ£¨Ò²³Æ¡°¼¯È¨Ê½·ÃÎÊ¿ØÖƲßÂÔ¡±£© ÌṩÊÔÑéÐÔÖ§³Ö¡£MAC ¿ò¼ÜÊÇÒ»¸ö²åÈëʽµÄ·ÃÎÊ¿ØÖÆ¿ò¼Ü£¬ÔÊÐíÐµİ²È«²ßÂÔ¸ü·½±ãµØÈÚÈëÄÚºË:°²È«²ßÂÔ¿ÉÒÔ¾²Ì¬Á´ÈëÄÚºË,Ò²¿ÉÒÔ ÔÚÒýµ¼Ê±¼ÓÔØ,ÉõÖÁÔÚÔËÐÐʱ¶¯Ì¬¼ÓÔØ¡£¸Ã¿ò¼ÜËùÌṩµÄ±ê×¼»¯½Ó¿Ú,ʹµÃÔËÐÐÔÚÆäÉϵݲȫ²ßÂÔÄ£¿éÄܶÔϵͳ¶ÔÏóµÄ°²È«ÊôÐÔ½øÐÐÖîÈç±ê¼ÇµÈһϵÁвÙ×÷¡£ MAC ¿ò¼ÜµÄ´æÔÚ£¬¼ò»¯ÁËÕâЩ²Ù×÷ÔÚ²ßÂÔÄ£¿éÖеÄʵÏÖ£¬´Ó¶øÏÔÖø½µµÍÁËа²È«²ßÂÔÄ£¿éµÄ¿ª·¢ÄѶȡ£
¡¡¡¡±¾Õ½«½éÉÜ MAC ²ßÂÔ¿ò¼Ü£¬Îª¶ÁÕßÌṩһ¸öʾÀýÐ﵀ MAC ²ßÂÔÄ£¿éÎĵµ¡£
¡¡¡¡TrustedBSD MAC ¿ò¼ÜÌṩµÄ»úÖÆ,ÔÊÐíÔÚÆäÉÏÔËÐеÄÄÚºËÄ£¿éÔÚÄں˱àÒë»òÕßÔËÐÐʱ£¬¶ÔÄں˵ķÃÎÊ¿ØÖÆÄ£ÐͽøÐÐÀ©Õ¹¡£ еÄϵͳ°²È«²ßÂÔ×÷Ϊһ¸öÄÚºËÄ£¿éʵÏÖ,²¢±»Á´½Óµ½ÄÚºËÖУ»Èç¹ûϵͳÖÐͬʱ´æÔÚ¶à¸ö°²È«²ßÂÔÄ£¿é£¬ÔòËüÃǵľö²ß½á¹û½«ÒÔijÖÖÈ·¶¨µÄ·½Ê½×éºÏ¡£ ΪÁ˸ø¼ò»¯Ð°²È«²ßÂԵĿª·¢£¬MAC ÏòÉÏÌṩÁË´óÁ¿ÓÃÓÚ·ÃÎÊ¿ØÖƵĻù´¡ÉèÊ©£¬ÌرðÊÇ£¬¶ÔÁÙʱµÄ»òÕ߳־õġ¢²ßÂÔÎ޹صĶÔÏó°²È«±ê¼ÇµÄÖ§³Ö¡£ ¸ÃÖ§³ÖĿǰÈÔÊÇÊÔÑéÐÔÖʵġ£
¡¡¡¡±¾ÕÂËùÌṩµÄÐÅÏ¢²»½ö½«Ê¹ÔÚ MAC ʹÄÜ»·¾³Ï¹¤×÷µÄDZÔÚÓû§ÊÜÒæ£¬ Ò²¿ÉÒÔΪÐèÒªÁ˽â MAC ¿ò¼ÜÊÇÈçºÎÖ§³Ö¶ÔÄں˷ÃÎÊ¿ØÖƽøÐÐÀ©Õ¹µÄ²ßÂÔÄ£¿é¿ª·¢ÈËÔ±ËùÓá£
¡¡¡¡Ç¿ÖÆ·ÃÎÊ¿ØÖÆ£¨¼ò³Æ MAC£©£¬ÊÇÖ¸ÓɲÙ×÷ÏµÍ³Ç¿ÖÆÊµÊ©µÄÒ»×éÕë¶ÔÓû§µÄ·ÃÎÊ¿ØÖƲßÂÔ¡£ ÔÚijЩÇé¿öÏÂ,Ç¿ÖÆ·ÃÎÊ¿ØÖƵIJßÂÔ¿ÉÄÜ»áÓë×ÔÖ÷·ÃÎÊ¿ØÖÆ£¨¼ò³Æ DAC£©ËùÌṩµÄ±£»¤´ëÊ©·¢Éú³åÍ»£¬ ºóÕßÊÇÓÃÀ´Ïò·Ç¹ÜÀíÔ±Óû§¶ÔÊý¾Ý²ÉÈ¡±£»¤´ëÊ©Ìṩ֧³ÖµÄ¡£ÔÚ´«Í³µÄ UNIX ϵͳÖУ¬ DAC ±£»¤´ëÊ©°üÀ¨Îļþ·ÃÎÊģʽºÍ·ÃÎÊ¿ØÖÆÁÐ±í£»¶ø MAC ÔòÌṩ½ø³Ì¿ØÖƺͷÀ»ðǽµÈ¡£ ²Ù×÷ϵͳÉè¼ÆÕߺͰ²È«»úÖÆÑо¿ÈËÔ±¶ÔÐí¶à¾µäµÄ MAC °²È«²ßÂÔ×÷ÁËÐÎʽ»¯µÄ±íÊö£¬±ÈÈ磬 ¶à¼¶°²È«£¨MLS)»úÃÜÐÔ²ßÂÔ£¬Biba ÍêÕûÐÔ²ßÂÔ£¬»ùÓÚ½ÇÉ«µÄ·ÃÎÊ¿ØÖƲßÂÔ£¨RBAC£©£¬ÓòºÍÐͲþö²ßÂÔ(DTE),ÒÔ¼°ÐͲþö²ßÂÔ(TE)¡£ °²È«²ßÂÔµÄÐÎʽ»¯±íÊö±»³ÆÎª°²È«Ä£ÐÍ¡£Ã¿¸öÄ£Ð͸ù¾ÝһϵÁÐÌõ¼þ×ö³ö°²È«Ïà¹ØµÄ¾ö²ß£¬ÕâЩÌõ¼þ°üÀ¨£¬ Óû§µÄÉí·Ý¡¢½ÇÉ«ºÍ°²È«ÐÅÈÎ×´£¬ÒÔ¼°¶ÔÏóµÄ°²È«±ê¼Ç(ÓÃÀ´´ú±í¸Ã¶ÔÏóÊý¾ÝµÄ»úÃÜÐÔ/ÍêÕûÐÔ¼¶±ð)¡£
¡¡¡¡TrustedBSD MAC ¿ò¼ÜËùÌṩµÄ¶Ô²ßÂÔÄ£¿éµÄÖ§³Ö£¬²»½ö¿ÉÒÔÓÃÀ´ÊµÏÖÉÏÊöËùÓвßÂÔ£¬ »¹ÄÜÓÃÓÚʵÏÖÆäËûÀûÓÃÒÑÓа²È«ÊôÐÔ(È磬Óû§ºÍ×éID¡¢ÎļþÀ©Õ¹ÊôÐԵȣ©¾ö²ßµÄϵͳ°²È«Ç¿»¯²ßÂÔ¡£ ´ËÍ⣬ÒòΪ¾ßÌå²ßÂÔÄ£¿éÔÚ·ÃÎÊÊÚȨ·½ÃæËùÓµÓеĸ߶ÈÁé»îÐÔºÍ×ÔÖ÷ÐÔ£¬ËùÒÔMAC ¿ò¼ÜͬÑù¿ÉÒÔÓÃÀ´ÊµÏÖÍêÈ«×ÔÖ÷ʽµÄ°²È«²ßÂÔ.
¡¡¡¡TrustedBSD MAC ¿ò¼ÜΪ´ó¶àÊýµÄ·ÃÎÊ¿ØÖÆÄ£¿éÌṩ»ù±¾ÉèÊ©£¬ÔÊÐíËüÃÇÒÔÄÚºËÄ£¿éµÄÐÎʽÁé»îµØÀ©Õ¹ÏµÍ³ÖÐʵʩµÄ°²È«²ßÂÔ¡£ Èç¹ûϵͳÖÐͬʱ¼ÓÔØÁ˶à¸ö²ßÂÔ£¬MAC ¿ò¼Ü½«¸ºÔ𽫸÷¸ö²ßÂÔµÄÊÚȨ½á¹ûÒÔÒ»ÖÖ£¨Ä³Ö̶ֳÈÉÏ£©ÓÐÒâÒåµÄ·½Ê½×éºÏ£¬ÐγÉ×îºóµÄ¾ö²ß¡£
¡¡¡¡MAC ¿ò¼ÜÓÉÏÂÁÐÄÚºËÔªËØ×é³É£º
¿ò¼Ü¹ÜÀí½Ó¿Ú
²¢·¢Óëͬ²½ÔÓï
²ßÂÔ×¢²á
Äں˶ÔÏóµÄÀ©Õ¹ÐÔ°²È«±ê¼Ç
²ßÂÔÈë¿Úº¯ÊýµÄ×éºÏ²Ù×÷
±ê¼Ç¹ÜÀíÔÓï
ÓÉÄں˷þÎñµ÷ÓõÄÈë¿Úº¯Êý API
²ßÂÔÄ£¿éµÄÈë¿Úº¯Êý API
Èë¿Úº¯ÊýµÄʵÏÖ£¨°üÀ¨²ßÂÔÉúÃüÖÜÆÚ¹ÜÀí¡¢±ê¼Ç¹ÜÀíºÍ·ÃÎÊ¿ØÖƼì²éÈý²¿·Ö£©
¹ÜÀí²ßÂÔÎ޹رê¼ÇµÄϵͳµ÷ÓÃ
¸´ÓõÄmac_syscall()
ϵͳµ÷ÓÃ
ÒÔ MAC µÄ²ßÂÔ¼ÓÔØÄ£¿éÐÎʽʵÏֵĸ÷ÖÖ°²È«²ßÂÔ
¡¡¡¡¶Ô TrustedBSD MAC ¿ò¼Ü½øÐÐÖ±½Ó¹ÜÀíµÄ·½Ê½ÓÐÈýÖÖ:ͨ¹ý sysctl ×Óϵͳ¡¢Í¨¹ý loader ÅäÖÃ, »òÕßʹÓÃϵͳµ÷Óá£
¡¡¡¡¶àÊýÇé¿öÏ£¬Óëͬһ¸öÄÚºËÄÚ²¿±äÁ¿Ïà¹ØÁªµÄ sysctl ±äÁ¿ºÍ loader ²ÎÊýµÄÃû×ÖÊÇÏàͬµÄ£¬ ͨ¹ýÉèÖÃËüÃÇ£¬¿ÉÒÔ¿ØÖƱ£»¤´ëÊ©µÄʵʩϸ½Ú£¬±ÈÈ磬ij¸ö²ßÂÔÔÚ¸÷¸öÄÚºË×ÓϵͳÖеÄʵʩÓë·ñµÈµÈ¡£ ÁíÍ⣬Èç¹ûÔÚÄں˱àÒëʱѡÔñÖ§³Ö MAC µ÷ÊÔÑ¡ÏÄں˽«Î¬»¤Èô¸É¼ÆÊýÆ÷ÒÔ¸ú×Ù±ê¼ÇµÄ·ÖÅäʹÓÃÇé¿ö¡£ ͨ³£²»½¨ÒéÔÚʵÓû·¾³ÏÂͨ¹ýÔÚ²»Í¬×ÓϵͳÉÏÉèÖò»Í¬µÄ±äÁ¿»ò²ÎÊýÀ´ÊµÊ©¿ØÖÆ£¬ÒòΪÕâÖÖ·½·¨½«»á×÷ÓÃÓÚϵͳÖÐËùÓеĻîÔ¾²ßÂÔ¡£ Èç¹ûÏ£Íû¶Ô¾ßÌå²ßÂÔʵʩ¹ÜÀí¶ø²»ÏàÓ°ÏìÆäËû»îÔ¾²ßÂÔ,ÔòÓ¦µ±Ê¹ÓòßÂÔ¼¶±ðµÄ¿ØÖÆ£¬ÒòΪÕâÖÖ·½·¨µÄ¿ØÖÆÁ£¶È¸üϸ£¬ ²¢ÄܸüºÃµØ±£Ö¤²ßÂÔÄ£¿éµÄ¹¦ÄÜÒ»ÖÂÐÔ¡£
¡¡¡¡ÓëÆäËûÄÚºËÄ£¿éÒ»Ñù£¬ÏµÍ³¹ÜÀíÔ±¿ÉÒÔͨ¹ýϵͳµÄÄ£¿é¹ÜÀíϵͳµ÷ÓÃºÍÆäËûϵͳ½Ó¿Ú£¬°üÀ¨ boot loader ±äÁ¿£¬¶Ô²ßÂÔÄ£¿éÖ´ÐмÓÔØÓëÐ¶ÔØ²Ù×÷£» ²ßÂÔÄ£¿é¿ÉÒÔÔÚ¼ÓÔØÊ±,ÉèÖüÓÔØ±êÖ¾,À´Ö¸Ê¾ÏµÍ³¶ÔÆä¼ÓÔØ¡¢Ð¶ÔزÙ×÷½øÐÐÏàÓ¦¿ØÖÆ£¬±ÈÈç×èÖ¹·ÇÆÚÍûµÄÐ¶ÔØ²Ù×÷¡£
¡¡¡¡ÔÚÔËÐÐʱ,ϵͳÖлîÔ¾µÄ²ßÂÔ¼¯ºÏ¿ÉÄÜ·¢Éú±ä»¯£¬È»¶ø¶Ô²ßÂÔÈë¿Úº¯ÊýµÄʹÓòÙ×÷²¢²»ÊÇÔ×ÓÐԵģ¬Òò´Ë£¬µ±Ä³Ò»¸öÈë¿Úº¯ÊýÕý±»Ê¹ÓÃʱ£¬ ϵͳÐèÒªÌṩ¶îÍâµÄͬ²½»úÖÆÀ´×èÖ¹¶Ô¸Ã²ßÂÔÄ£¿éµÄ¼ÓÔØÓëÐ¶ÔØ£¬ÒÔÈ·±£µ±Ç°»îÔ¾µÄ²ßÂÔ¼¯ºÏ²»»áÔڴ˹ý³ÌÖз¢Éú¸Ä±ä¡£ ͨ¹ýʹÓÃ"¿ò¼Ü桱¼ÆÊýÆ÷,¾Í¿ÉÒÔ×öµ½ÕâÒ»µã£ºÒ»µ©Ä³¸öÈë¿Úº¯Êý±»µ÷Ó㬼ÆÊýÆ÷µÄÖµ±»Ôö¼Ó1£»¶øÃ¿µ±Ò»¸öÈë¿Úº¯Êýµ÷ÓýáÊøÊ±£¬¼ÆÊýÆ÷µÄÖµ±»¼õÉÙ1¡£ ¼ì²é¼ÆÊýÆ÷µÄÖµ£¬Èç¹ûÆäֵΪÕý£¬¿ò¼Ü½«×èÖ¹¶Ô²ßÂÔÁ´±íµÄÐ޸IJÙ×÷£¬ÇëÇó²Ù×÷µÄÏ߳̽«±»ÆÈ½øÈë˯Ãߣ¬Ö±µ½¼ÆÊýÆ÷µÄÖµÖØÐ¼õÉÙµ½0Ϊֹ¡£ ¼ÆÊýÆ÷±¾ÉíÓÉÒ»¸ö»¥³âËø±£»¤£¬Í¬Ê±½áºÏÒ»¸öÌõ¼þ±äÁ¿(ÓÃÓÚ»½Ðѵȴý¶Ô²ßÂÔÁ´±í½øÐÐÐ޸IJÙ×÷µÄ˯ÃßÏß³Ì)¡£ ²ÉÓÃÕâÖÖͬ²½Ä£Ð͵ÄÒ»¸ö¸±×÷ÓÃÊÇ£¬ÔÚͬһ¸ö²ßÂÔÄ£¿éÄÚ²¿£¬ÔÊÐíǶÌ׵ص÷Óÿò¼Ü£¬²»¹ýÕâÖÖÇé¿öÆäʵºÜÉÙ³öÏÖ¡£
¡¡¡¡ÎªÁ˼õÉÙÓÉÓÚ²ÉÓüÆÊýÆ÷ÒýÈëµÄ¶îÍ⿪Ïú£¬Éè¼ÆÕß²ÉÓÃÁ˸÷ÖÖÓÅ»¯´ëÊ©¡£ÆäÖаüÀ¨£¬µ±²ßÂÔÁ´±íΪ¿Õ»òÕ߯äÖнöº¬Óо²Ì¬±íÏî £¨ÄÇЩֻÄÜÔÚϵͳÔËÐÐ֮ǰ¼ÓÔØ¶øÇÒ²»Äܶ¯Ì¬Ð¶ÔصIJßÂÔ£©Ê±£¬¿ò¼Ü²»¶Ô¼ÆÊýÆ÷½øÐвÙ×÷£¬ÆäÖµ×ÜÊÇΪ0£¬´Ó¶ø½«´ËʱµÄͬ²½¿ªÏú¼õµ½0¡£ ÁíÒ»¸ö¼«¶ËµÄ°ì·¨ÊÇ£¬Ê¹ÓÃÒ»¸ö±àÒëÑ¡ÏîÀ´½ûÖ¹ÔÚÔËÐÐʱ¶Ô¼ÓÔØµÄ²ßÂÔÁ´±í½øÐÐÐ޸쬴Ëʱ²»ÔÙÐèÒª¶Ô²ßÂÔÁ´±íµÄʹÓýøÐÐͬ²½±£»¤¡£
¡¡¡¡ÒòΪ MAC ¿ò¼Ü²»ÔÊÐíÔÚijЩÈë¿Úº¯ÊýÖ®ÄÚ×èÈû£¬ËùÒÔ²»ÄÜʹÓÃÆÕͨµÄ˯ÃßËø¡£ ¹Ê¶ø£¬¼ÓÔØ»òÐ¶ÔØ²Ù×÷¿ÉÄÜ»áΪµÈ´ý¿ò¼Ü¿ÕÏжø±»×èÈûÏ൱³¤µÄÒ»¶Îʱ¼ä¡£
¡¡¡¡MAC ¿ò¼Ü±ØÐë¶ÔÆä¸ºÔðά»¤µÄ°²È«ÊôÐÔ±ê¼ÇµÄ´æ´¢·ÃÎÊÌṩͬ²½±£»¤¡£ÏÂÁÐÁ½ÖÖÇéÐΣ¬¿ÉÄܵ¼Ö¶԰²È«ÊôÐÔ±ê¼ÇµÄ²»Ò»Ö·ÃÎÊ£º µÚÒ»£¬×÷Ϊ°²È«ÊôÐÔ±ê¼ÇµÄ³ÖÓÐÕߣ¬Äں˶ÔÏó±¾Éí¿ÉÄÜͬʱ±»¶à¸öÏ̷߳ÃÎÊ£»µÚ¶þ£¬MAC ¿ò¼Ü´úÂëÊÇ¿ÉÖØÈëµÄ£¬ ¼´ÔÊÐí¶à¸öÏß³ÌͬʱÔÚ¿ò¼ÜÄÚÖ´ÐС£Í¨³££¬MAC ¿ò¼ÜʹÓÃÄں˶ÔÏóÊý¾ÝÉÏÒÑÓеÄÄÚºËͬ²½»úÖÆÀ´±£»¤¸ÃÆäÉϸ½¼ÓµÄ MAC °²È«±ê¼Ç¡£ ÀýÈ磬Ì×½Ó×ÖÉ쵀 MAC ±ê¼ÇÓÉÒÑÓеÄÌ×½Ó×Ö»¥³âËø±£»¤¡£ÀàËÆµÄ£¬¶ÔÓÚ°²È«±ê¼ÇµÄ²¢·¢·ÃÎʵĹý³ÌÓë¶ÔÆäËùÔÚ¶ÔÏó½øÐеIJ¢·¢·ÃÎÊÔÚÓïÒåÉÏÊÇÒ»ÑùµÄ£¬ ÀýÈ磬ÐÅÈÎ×´°²È«±ê¼Ç,½«±£³ÖÓë¸ÃÊý¾Ý½á¹¹ÖÐÆäËûÄÚÈÝÒ»ÖµÄ"дʱ¸´ÖÆ"µÄ¸üйý³Ì¡£ MAC ¿ò¼ÜÔÚÒýÓÃÒ»¸öÄں˶ÔÏóʱ£¬½«Ê×ÏȶԷÃÎʸöÔÏóÉϵıê¼ÇÐèÒªÓõ½µÄËø½øÐжÏÑÔ¡£ ²ßÂÔÄ£¿éµÄ±àдÕß±ØÐëÁ˽âÕâЩͬ²½ÓïÒ壬 ÒòΪËüÃÇ¿ÉÄÜ»áÏÞÖÆ¶Ô°²È«±ê¼ÇËùÄܽøÐеķÃÎÊÀàÐÍ¡£ ¾Ù¸öÀý×Ó£¬Èç¹ûͨ¹ýÈë¿Úº¯Êý´«¸ø²ßÂÔÄ£¿éµÄÊǶÔij¸öÐÅÈÎ×´µÄÖ»¶ÁÒýÓã¬ÄÇôÔÚ²ßÂÔÄÚ²¿£¬Ö»ÄܶÁ¸Ã½á¹¹¶ÔÓ¦µÄ±ê¼Ç״̬¡£
¡¡¡¡FreeBSD ÄÚºËÊÇÒ»¸ö¿ÉÇÀռʽµÄÄںˣ¬Òò´Ë£¬×÷ΪÄÚºËÒ»²¿·ÖµÄ²ßÂÔÄ£¿éÒ²±ØÐëÊÇ¿ÉÖØÈëµÄ£¬Ò²¾ÍÊÇ˵£¬ ÔÚ¿ª·¢²ßÂÔÄ£¿éʱ±ØÐë¼ÙÉè¶à¸öÄÚºËÏ߳̿ÉÒÔͬʱͨ¹ý²»Í¬µÄÈë¿Úº¯Êý½øÈë¸ÃÄ£¿é¡£ Èç¹û²ßÂÔÄ£¿éʹÓÿɱ»Ð޸ĵÄÄÚºË״̬£¬ÄÇô»¹ÐèÒªÔÚ²ßÂÔÄÚ²¿Ê¹ÓÃÇ¡µ±µÄͬ²½ÔÓȷ±£ÔÚ²ßÂÔÄÚ²¿µÄ¶à¸öÏ̲߳»»áÒò´Ë¹Û²ìµ½²»Ò»ÖµÄÄÚºË״̬£¬ ´Ó¶ø±ÜÃâÓɴ˲úÉúµÄ²ßÂÔÎó²Ù×÷¡£Îª´Ë£¬²ßÂÔ¿ÉÒÔʹÓà FreeBSD ÏÖÓеÄͬ²½ÔÓ°üÀ¨»¥³âËø¡¢Ë¯ÃßËø¡¢Ìõ¼þ±äÁ¿ºÍ¼ÆÊýÐźÅÁ¿¡£ ¶ÔÕâЩͬ²½ÔÓïµÄʹÓñØÐëÉ÷ÖØ£¬ÐèÒªÌØ±ð×¢ÒâÁ½µã£ºµÚÒ»£¬±£³ÖÏÖÓеÄÄÚºËÉÏËø´ÎÐò£» µÚ¶þ£¬ÔÚ·Ç˯ÃßµÄÈë¿Úº¯ÊýÖ®ÄÚ²»ÒªÊ¹Óû¥³âËøºÍ»½ÐѲÙ×÷¡£
¡¡¡¡Îª±ÜÃâÎ¥·´ÄÚºËÉÏËø´ÎÐò»òÔì³ÉµÝ¹éÉÏËø£¬²ßÂÔÄ£¿éÔÚµ÷ÓÃÆäËûÄÚºË×Óϵͳ֮ǰ£¬Í¨³£ÒªÊÍ·ÅËùÓÐÔÚ²ßÂÔÄÚ²¿ÉêÇëµÄËø¡£ ÕâÑù×öµÄ½á¹ûÊÇ£¬ÔÚÈ«¾ÖÉÏËø´ÎÐòÐγɵÄÍØÆÓ½á¹¹ÖУ¬²ßÂÔÄÚ²¿µÄËø×ÜÊÇ×÷ΪҶ×ӽڵ㣬 ´Ó¶ø±£Ö¤ÁËÕâÐ©ËøµÄʹÓò»»áµ¼ÖÂÓÉÓÚÉÏËø´ÎÐò»ìÂÒÔì³ÉµÄËÀËø¡£
¡¡¡¡ÎªÁ˼Ǽµ±Ç°Ê¹ÓõIJßÂÔÄ£¿é¼¯ºÏ£¬MAC ¿ò¼Üά»¤Á½¸öÁ´±í£ºÒ»¸ö¾²Ì¬Á´±íºÍÒ»¸ö¶¯Ì¬Á´±í¡£ Á½¸öÁ´±íµÄÊý¾Ý½á¹¹ºÍ²Ù×÷»ù±¾Ïàͬ£¬Ö»ÊǶ¯Ì¬Á´±í»¹¶îÍâʹÓÃÁËÒ»¸ö"ÒýÓüÆÊý"ÒÔͬ²½¶ÔÆäµÄ·ÃÎʲÙ×÷¡£ µ±°üº¬ MAC ¿ò¼Ü²ßÂÔµÄÄÚºËÄ£¿é±»¼ÓÔØÊ±£¬¸Ã²ßÂÔÄ£¿é»áͨ¹ý SYSINIT µ÷ÓÃÒ»¸ö×¢²áº¯Êý£» Ïà¶ÔÓ¦µÄ£¬Ã¿µ±Ò»¸ö²ßÂÔÄ£¿é±»Ð¶ÔØ£¬SYSINIT Ò²»áµ÷ÓÃÒ»¸ö×¢Ïúº¯Êý¡£ Ö»Óе±Óöµ½ÏÂÁÐÇé¿ö֮һʱ£¬×¢²á¹ý³Ì²Å»áʧ°Ü£º Ò»¸ö²ßÂÔÄ£¿é±»¼ÓÔØ¶à´Î£¬»òÕßϵͳ×ÊÔ´²»×ã²»ÄÜÂú×ã×¢²á¹ý³ÌµÄÐèÒª£¨ ÀýÈ磬²ßÂÔÄ£¿éÐèÒª¶ÔÄں˶ÔÏóÌí¼Ó±ê¼Ç¶ø¿ÉÓÃ×ÊÔ´²»×㣩£¬»òÕ߯äËûµÄ²ßÂÔ¼ÓÔØÇ°ÌáÌõ¼þ²»Âú×㣨ÓÐЩ²ßÂÔÒªÇóÖ»ÄÜÔÚϵͳÒýµ¼Ö®Ç°¼ÓÔØ£©¡£ ÀàËÆµÄ£¬Èç¹ûÒ»¸ö²ßÂÔ±»±ê¼ÇΪ²»¿ÉÐ¶ÔØµÄ£¬¶ÔÆäµ÷ÓÃ×¢Ïú¹ý³Ì½«»áʧ°Ü¡£
¡¡¡¡Äں˷þÎñÓë MAC ¿ò¼ÜÖ®¼ä½øÐн»»¥ÓÐÁ½ÖÖ;¾¶£º Ò»ÊÇ£¬Äں˷þÎñµ÷ÓÃһϵÁÐ API ֪ͨ MAC ¿ò¼Ü°²È«Ê¼þµÄ·¢Éú£» ¶þÊÇ£¬Äں˷þÎñÏò MAC ¿ò¼ÜÌṩһ¸öÖ¸Ïò°²È«¶ÔÏóµÄ²ßÂÔÎ޹ذ²È«±ê¼ÇÊý¾Ý½á¹¹µÄÖ¸Õë¡£ ±ê¼ÇÖ¸ÕëÓÉ MAC ¿ò¼Ü¾Óɱê¼Ç¹ÜÀíÈë¿Úº¯Êý½øÐÐά»¤£¬ ²¢ÇÒ£¬Ö»Òª¶Ô¹ÜÀíÏà¹Ø¶ÔÏóµÄÄÚºË×ÓϵͳÉÔ×÷Ð޸ģ¬¾Í¿ÉÒÔÔÊÐí MAC ¿ò¼ÜÏò²ßÂÔÄ£¿éÌṩ±ê¼Ç·þÎñ¡£ ÀýÈ磬ÔÚ½ø³Ì¡¢½ø³ÌÐÅÈÎ×´¡¢Ì×½Ó×Ö¡¢¹ÜµÀ¡¢Mbuf¡¢ÍøÂç½Ó¿Ú¡¢IP ÖØ×é¶ÓÁÐºÍÆäËû¸÷ÖÖ°²È«Ïà¹ØµÄÊý¾Ý½á¹¹ÖоùÔö¼ÓÁËÖ¸Ïò°²È«±ê¼ÇµÄÖ¸Õë¡£ ÁíÍ⣬µ±ÐèÒª×ö³öÖØÒªµÄ°²È«¾ö²ßʱ£¬Äں˷þÎñÒ²»áµ÷Óà MAC ¿ò¼Ü£¬ÒÔ±ã¸÷¸ö²ßÂÔÄ£¿é¸ù¾ÝÆä×Ô¼ºµÄ±ê×¼£¨¿ÉÒÔʹÓô洢ÔÚ°²È«±ê¼ÇÖеÄÊý¾Ý£©ÍêÉÆÕâЩ¾ö²ß¡£ ¾ø´ó¶àÊý°²È«Ïà¹ØµÄ¹Ø¼ü¾ö²ßÊÇÏÔʽµÄ·ÃÎÊ¿ØÖƼì²é£» Ò²ÓÐÉÙÊýÉæ¼°¸ü¼ÓÒ»°ãµÄ¾ö²ßº¯Êý£¬±ÈÈ磬Ì×½Ó×ÖµÄÊý¾Ý°üÆ¥ÅäºÍ³ÌÐòÖ´ÐÐʱ¿ÌµÄ±ê¼Çת»»¡£
¡¡¡¡Èç¹ûÄÚºËÖÐͬʱ¼ÓÔØÁ˶à¸ö²ßÂÔÄ£¿é£¬ÕâЩ²ßÂԵľö²ß½á¹û½«ÓÉ¿ò¼ÜʹÓÃÒ»¸öºÏ³ÉÔËËã×ÓÀ´½øÐÐ×éºÏ»ã×Ü£¬µÃ³ö×îÖյĽá¹û¡£ Ŀǰ£¬¸ÃËã×ÓÊÇÓ²±àÂëµÄ£¬²¢ÇÒÖ»Óе±ËùÓеĻîÔ¾²ßÂÔ¾ù¶ÔÇëÇó±íʾͬÒâʱ²Å»á·µ»Ø³É¹¦¡£ ÓÉÓÚ¸÷¸ö²ßÂÔ·µ»ØµÄ³ö´íÌõ¼þ¿ÉÄܲ¢²»Ïàͬ£¨³É¹¦¡¢·ÃÎʱ»¾Ü¾ø¡¢ÇëÇó¶ÔÏó²»´æÔڵȵȣ©£¬ ÐèҪʹÓÃÒ»¸öÑ¡Ôñ×ÓÏÈ´Ó¸÷¸ö²ßÂÔ·µ»ØµÄ´íÎóÌõ¼þ¼¯ºÏÖÐÑ¡Ôñ³öÒ»¸ö×÷Ϊ×îÖÕ·µ»Ø½á¹û¡£ Ò»°ãÇé¿öÏ£¬Óë¡°·ÃÎʱ»¾Ü¾ø¡±Ïà±È£¬½«¸üÇãÏòÓÚÑ¡Ôñ¡°ÇëÇó¶ÔÏó²»´æÔÚ¡±¡£ ¾¡¹Ü²»ÄÜ´ÓÀíÂÛÉϱ£Ö¤ºÏ³É½á¹ûµÄÓÐЧÐÔÓ밲ȫÐÔ£¬µ«ÊÔÑé½á¹û±íÃ÷£¬¶ÔÓÚÐí¶àʵÓõIJßÂÔ¼¯ºÏÀ´Ëµ£¬ÊÂʵµÄÈ·Èç´Ë¡£ ÀýÈ磬´«Í³µÄ¿ÉÐÅϵͳ³£³£²ÉÓÃÀàËÆµÄ·½·¨¶Ô¶à¸ö°²È«²ßÂÔ½øÐÐ×éºÏ¡£
¡¡¡¡ÓëÐí¶àÐèÒª¸ø¶ÔÏóÌí¼Ó°²È«±ê¼ÇµÄ·ÃÎÊ¿ØÖÆÀ©Õ¹Ò»Ñù£¬MAC ¿ò¼ÜΪ¸÷ÖÖÓû§¿É¼ûµÄ¶ÔÏóÌṩÁËÒ»×éÓÃÓÚ¹ÜÀí²ßÂÔÎ޹رê¼ÇµÄϵͳµ÷Óᣠ³£Óõıê¼ÇÀàÐÍÓУ¬partition±êʶ·û¡¢»úÃÜÐÔ±ê¼Ç¡¢ÍêÕûÐÔ±ê¼Ç¡¢Çø¼ä£¨·ÇµÈ¼¶Àà±ð£©¡¢Óò¡¢½ÇÉ«ºÍÐÍ¡£ ¡°²ßÂÔÎ޹ء±µÄÒâ˼ÊÇÖ¸£¬±ê¼ÇµÄÓï·¨ÓëʹÓÃËüµÄ¾ßÌå²ßÂÔÄ£¿éÎ޹أ¬¶øÍ¬Ê±²ßÂÔÄ£¿éÄܹ»ÍêÈ«¶ÀÁ¢µØ¶¨ÒåºÍʹÓÃÓë¶ÔÏóÏà¹ØÁªµÄÔªÊý¾ÝµÄÓïÒå¡£ Óû§Ó¦ÓóÌÐòÌṩͳһ¸ñʽµÄ»ùÓÚ×Ö·û´®µÄ±ê¼Ç£¬ÓÉʹÓÃËüµÄ²ßÂÔÄ£¿é¸ºÔð½âÎöÆäÄÚÔÚº¬Òå²¢¾ö¶¨ÆäÍâÔÚ±íʾ¡£ Èç¹ûÐèÒª£¬Ó¦ÓóÌÐò¿ÉÒÔʹÓöàÖØ±ê¼ÇÔªËØ¡£
¡¡¡¡ÄÚ´æÖеıê¼ÇʵÀý±»´æ·ÅÔÚÓÉ slab ·ÖÅäµÄstruct
label
Êý¾Ý½á¹¹ÖС£ ¸Ã½á¹¹ÊÇÒ»¸ö¹Ì¶¨³¤¶ÈµÄÊý×飬ÿ¸öÔªËØÊÇÓÉÒ»¸ö void * Ö¸ÕëºÍÒ»¸ö long×é³ÉµÄÁªºÏ½á¹¹¡£
ÉêÇë±ê¼Ç´æ´¢µÄ²ßÂÔÄ£¿éÔÚÏò MAC
×¢²áʱ£¬½«±»·ÖÅäÒ»¸ö¡°slot¡±Öµ£¬×÷Ϊ¿ò¼Ü·ÖÅ䏸ÆäʹÓõIJßÂÔ±ê¼ÇÔªËØÔÚÕû¸ö±ê¼Ç´æ´¢½á¹¹ÖеÄλÖÃË÷Òý¡£
¶øËù·ÖÅäµÄ´æ´¢¿Õ¼äµÄÓïÒåÔòÍêÈ«ÓɸòßÂÔÄ£¿éÀ´¾ö¶¨£ºMAC
¿ò¼ÜÏò²ßÂÔÄ£¿éÌṩÁËһϵÁÐÈë¿Úº¯ÊýÓÃÓÚ¶ÔÄں˶ÔÏóÉúÃüÖÜÆÚµÄ¸÷ÖÖʼþ½øÐпØÖÆ£¬°üÀ¨£¬
¶ÔÏóµÄ³õʼ»¯¡¢±ê¼ÇµÄ¹ØÁª/´´½¨ºÍ¶ÔÏóµÄ×¢Ïú¡£Ê¹ÓÃÕâЩ½Ó¿Ú£¬¿ÉÒÔʵÏÖÖîÈç·ÃÎʼÆÊýµÈ´æ´¢Ä£ÐÍ¡£
MAC
¿ò¼Ü×ÜÊǸøÈë¿Úº¯Êý´«ÈëÒ»¸öÖ¸ÏòÏà¹Ø¶ÔÏóµÄÖ¸ÕëºÍÒ»¸öÖ¸Ïò¸Ã¶ÔÏó±ê¼ÇµÄÖ¸Õ룬Òò´Ë£¬²ßÂÔÄ£¿éÄܹ»Ö±½Ó·ÃÎʱê¼Ç¶øÎÞÐè֪Ϥ¸Ã¶ÔÏóµÄÄÚ²¿½á¹¹¡£
ΨһµÄÀýÍâÊǽø³ÌÐÅÈÎ×´½á¹¹£¬Ö¸ÏòÆä±ê¼ÇµÄÖ¸Õë±ØÐëÓɲßÂÔÄ£¿éÊÖ¶¯½âÎö¼ÆËã¡£½ñºóµÄ MAC
¿ò¼ÜʵÏÖ¿ÉÄÜ»á¶Ô´Ë½øÐиĽø¡£
¡¡¡¡³õʼ»¯Èë¿Úº¯Êýͨ³£ÓÐÒ»¸ö˯Ãß±ê־룬ÓÃÀ´±íÃ÷Ò»¸ö³õʼ»¯²Ù×÷ÊÇ·ñÔÊÐíÖÐ;˯Ãߵȴý£» Èç¹û²»ÔÊÐí£¬Ôò¿ÉÄÜ»áʧ°Ü·µ»Ø£¬²¢ÒªÇó³·Ïú´Ë´Î±ê¼Ç·ÖÅä²Ù×÷£¨ÄËÖÁ¶ÔÏó·ÖÅä²Ù×÷£©¡£ ÀýÈ磬Èç¹ûÔÚÍøÂçÕ»ÉÏ´¦ÀíÖжÏʱÒòΪ²»ÔÊÐí˯Ãß»òÕßµ÷ÓÃÕß³ÖÓÐÒ»¸ö»¥³âËø£¬¾Í¿ÉÄܳöÏÖÕâÖÖÇé¿ö¡£ ¿¼Âǵ½ÔÚ´¦ÀíÖеÄÍøÂçÊý¾Ý°ü£¨Mbufs£©ÉÏά»¤±ê¼ÇµÄÐÔÄÜËðʧ̫´ó£¬²ßÂÔ±ØÐë¾Í×Ô¼º¶Ô Mbuf ½øÐбê¼ÇµÄÒªÇóÏò MAC ¿ò¼Ü×ö³öÌØ±ðÉùÃ÷¡£ ¶¯Ì¬¼ÓÔØµ½ÏµÍ³ÖжøÓÖʹÓñê¼ÇµÄ²ßÂÔ±ØÐëΪ´¦Àíδ±»Æä³õʼ»¯º¯Êý´¦Àí¹ýµÄ¶ÔÏó×÷ºÃ×¼±¸£¬ ÕâЩ¶ÔÏóÔÚ²ßÂÔ¼ÓÔØÖ®Ç°¾ÍÒѾ´æÔÚ,¹Ê¶øÎÞ·¨ÔÚ³õʼ»¯Ê±µ÷ÓòßÂÔµÄÏà¹Øº¯Êý½øÐд¦Àí¡£ MAC ¿ò¼ÜÏò²ßÂÔ±£Ö¤£¬Ã»Óб»³õʼ»¯µÄ±ê¼Ç slot µÄÖµ±ØÎª0»òÕß NULL£¬²ßÂÔ¿ÉÒÔ½è´Ë¼ì²âµ½Î´³õʼ»¯µÄ±ê¼Ç¡£ ÐèҪעÒâµÄÊÇ£¬ÒòΪ¶Ô Mbuf ±ê¼ÇµÄ´æ´¢·ÖÅäÊÇÓÐÌõ¼þµÄ£¬Òò´ËÐèҪʹÓÃÆä±ê¼ÇµÄ¶¯Ì¬¼ÓÔØ²ßÂÔ»¹¿ÉÄÜÐèÒª´¦Àí Mbuf ÖÐֵΪ NULL µÄ±ê¼ÇÖ¸Õë¡£
¡¡¡¡¶ÔÓÚÎļþϵͳ¶ÔÏóµÄ±ê¼Ç£¬MAC ¿ò¼ÜÔÚÎļþµÄÀ©Õ¹ÊôÐÔÖÐΪÆä·ÖÅäÓÀ¾Ã´æ´¢¡£ Ö»Òª¿ÉÄÜ£¬À©Õ¹ÊôÐÔµÄÔ×Ó»¯µÄÊÂÎñ²Ù×÷¾Í±»ÓÃÓÚ±£Ö¤¶Ô vnode Éϰ²È«±ê¼ÇµÄ¸´ºÏ¸üвÙ×÷µÄÒ»ÖÂÐÔ££Ä¿Ç°£¬¸ÃÌØÐÔÖ»±» UFS2 Îļþϵͳ֧³Ö¡£ ΪÁËʵÏÖϸÁ£¶ÈµÄÎļþϵͳ¶ÔÏó±ê¼Ç£¨¼´Ã¿¸öÎļþϵͳ¶ÔÏóÒ»¸ö±ê¼Ç£©£¬²ßÂÔ±àдÕß¿ÉÄÜÑ¡ÔñʹÓÃÒ»¸ö£¨»òÕßÈô¸É£©À©Õ¹ÊôÐÔ¿é¡£ ΪÁËÌá¸ßÐÔÄÜ£¬ vnode Êý¾Ý½á¹¹ÖÐÓÐÒ»¸ö±ê¼Ç (v_label)×ֶΣ¬ÓÃ×÷´ÅÅ̱ê¼ÇµÄ»º³å£» vnode ½á¹¹ÊµÀý»¯Ê±£¬²ßÂÔ¿ÉÒÔ½«±ê¼ÇÖµ×°Èë¸Ã»º³å£¬²¢ÔÚÐèҪʱ¶ÔÆä½øÐиüС£ Èç´Ë£¬²»±ØÔÚÿ´Î½øÐзÃÎÊ¿ØÖƼì²éʱ£¬¾ùÎÞÌõ¼þµØ·ÃÎÊ´ÅÅÌÉϵÄÀ©Õ¹ÊôÐÔ¡£
×¢Òâ: Ŀǰ£¬Èç¹ûÒ»¸öʹÓñê¼ÇµÄ²ßÂÔÔÊÐí±»¶¯Ì¬Ð¶ÔØ£¬ÔòÐ¶ÔØ¸ÃÄ£¿éÖ®ºó,Æä״̬ slot ÉÐÎÞ·¨±»ÏµÍ³»ØÊÕÖØÓ㬠Óɴ˵¼ÖÂÁË MAC ¿ò¼Ü¶Ô±ê¼Ç²ßÂÔÐ¶ÔØ£ÖØÔزÙ×÷ÊýÄ¿ÉϵÄÑϸñÏÞÖÆ¡£
¡¡¡¡MAC ¿ò¼ÜÏòÓ¦ÓóÌÐòÌṩÁËÒ»×éϵͳµ÷ÓãºÆäÖдó¶àÊýÓÃÓÚÏò½øÐвéѯºÍÐ޸IJßÂÔÎ޹رê¼Ç²Ù×÷µÄÓ¦Óà APIÌṩ֧³Ö¡£
¡¡¡¡ÕâЩ±ê¼Ç¹ÜÀíϵͳµ÷Ó㬽ÓÊÜÒ»¸ö±ê¼ÇÃèÊö½á¹¹£¬ struct
mac
£¬×÷ΪÊäÈë²ÎÊý¡£ Õâ¸ö½á¹¹µÄÖ÷ÌåÊÇÒ»¸öÊý×飬ÆäÖÐÿ¸öÔªËØ°üº¬ÁËÒ»¸öÓ¦Óü¶µÄ MAC
±ê¼ÇÐÎʽ¡£Ã¿¸öÔªËØÓÖÓÉÁ½²¿·Ö×é³É:Ò»¸ö×Ö·û´®Ãû×Ö£¬ºÍÆä¶ÔÓ¦µÄÖµ¡£
ÿ¸ö²ßÂÔ¿ÉÒÔÏòϵͳÉùÃ÷Ò»¸öÌØ¶¨µÄÔªËØÃû×Ö£¬ÕâÑùÒ»À´£¬Èç¹ûÐèÒª£¬¾Í¿ÉÒÔ½«Èô¸É¸öÏ໥¶ÀÁ¢µÄÔªËØ×÷Ϊһ¸öÕûÌå½øÐд¦Àí¡£
²ßÂÔÄ£¿é¾ÓÉÈë¿Úº¯Êý£¬ÔÚÄں˱ê¼ÇºÍÓû§ÌṩµÄ±ê¼ÇÖ®¼ä×÷·Òëת»»µÄ¹¤×÷£¬ÕâÖÖʵÏÖÌṩÁ˱ê¼ÇÔªËØÓïÒåÉϵĸ߶ÈÁé»îÐÔ¡£
±ê¼Ç¹ÜÀíϵͳµ÷ÓÃͨ³£ÓжÔÓ¦µÄ¿âº¯Êý°ü×°£¬ÕâЩ°ü×°º¯Êý¿ÉÒÔÌṩÄÚ´æ·ÖÅäºÍ´íÎó´¦Àí¹¦ÄÜ£¬´Ó¶ø¼ò»¯ÁËÓû§Ó¦ÓóÌÐòµÄ±ê¼Ç¹ÜÀí¹¤×÷¡£
¡¡¡¡Ä¿Ç°µÄFreeBSD ÄÚºËÌṩÁËÏÂÁÐ MAC Ïà¹ØµÄϵͳµ÷Óãº
mac_get_proc()
ÓÃÓÚ²éѯµ±Ç°½ø³ÌµÄ°²È«±ê¼Ç¡£
mac_set_proc()
ÓÃÓÚÇëÇó¸Ä±äµ±Ç°½ø³ÌµÄ°²È«±ê¼Ç¡£
mac_get_fd()
ÓÃÓÚ²éѯÓÉÎļþÃèÊö·ûËùÒýÓõĶÔÏó£¨ Îļþ¡¢
Ì×½Ó×Ö¡¢ ¹ÜµÀÎļþµÈµÈ£© µÄ°²È«±ê¼Ç¡£
mac_get_file()
ÓÃÓÚ²éѯÓÉÎļþϵͳ·¾¶ËùÃèÊöµÄ¶ÔÏóµÄ°²È«±ê¼Ç¡£
mac_set_fd()
ÓÃÓÚÇëÇó¸Ä±äÓÉÎļþÃèÊö·ûËùÒýÓõĶÔÏó£¨
Îļþ¡¢Ì×½Ó×Ö¡¢ ¹ÜµÀÎļþµÈµÈ£© µÄ°²È«±ê¼Ç¡£
mac_set_file()
ÓÃÓÚÇëÇó¸Ä±äÓÉÎļþϵͳ·¾¶ËùÃèÊöµÄ¶ÔÏóµÄ°²È«±ê¼Ç¡£
mac_syscall()
ͨ¹ý¸´ÓøÃϵͳµ÷ÓÃ,²ßÂÔÄ£¿éÄܹ»ÔÚ²»ÐÞ¸Äϵͳµ÷ÓñíµÄǰÌáÏ´´½¨ÐµÄϵͳµ÷Óã»
Æäµ÷ÓòÎÊý°üÀ¨£ºÄ¿±ê²ßÂÔÃû×Ö¡¢ ²Ù×÷±àºÅºÍ½«±»¸Ã²ßÂÔÄÚ²¿Ê¹ÓõIJÎÊý¡£
mac_get_pid()
ÓÃÓÚ²éѯÓɽø³ÌºÅÖ¸¶¨µÄÁíÒ»¸ö½ø³ÌµÄ°²È«±ê¼Ç¡£
mac_get_link()
Óë mac_get_file()
¹¦ÄÜÏàͬ£¬ Ö»Êǵ±Â·¾¶²ÎÊýµÄ×îºóÒ»ÏîΪ·ûºÅÁ´½Óʱ£¬
ǰÕß½«·µ»Ø¸Ã·ûºÅÁ´½ÓµÄ°²È«±ê¼Ç£¬ ¶øºóÕß½«·µ»ØÆäËùÖ¸ÎļþµÄ°²È«±ê¼Ç¡£
mac_set_link()
Óë mac_set_file()
¹¦ÄÜÏàͬ£¬ Ö»Êǵ±Â·¾¶²ÎÊýµÄ×îºóÒ»ÏîΪ·ûºÅÁ´½Óʱ£¬
ǰÕß½«ÉèÖø÷ûºÅÁ´½ÓµÄ°²È«±ê¼Ç£¬ ¶øºóÕß½«ÉèÖÃÆäËùÖ¸ÎļþµÄ°²È«±ê¼Ç¡£
mac_execve()
Óë execve()
¹¦ÄÜÀàËÆ£¬
Ö»ÊÇǰÕß»¹¿ÉÒÔÔÚ¿ªÊ¼Ö´ÐÐÒ»¸öгÌÐòʱ,¸ù¾Ý´«ÈëµÄÇëÇó²ÎÊý,ÉèÖÃÖ´Ðнø³ÌµÄ°²È«±ê¼Ç¡£
ÓÉÓÚÖ´ÐÐÒ»¸öгÌÐò¶øµ¼ÖµĽø³Ì°²È«±ê¼ÇµÄ¸Ä±ä,±»³ÆÎª¡°×ª»»¡±¡£
mac_get_peer()
£¬ ͨ¹ýÒ»¸öÌ×½Ó×ÖÑ¡Ïî×Ô¶¯ÊµÏÖ£¬
ÓÃÓÚ²éѯһ¸öÔ¶³ÌÌ×½Ó×Ö¶ÔµÈʵÌåµÄ°²È«±ê¼Ç¡£
¡¡¡¡³ýÁËÉÏÊöϵͳµ÷ÓÃÖ®Í⣬ Ò²¿ÉÒÔͨ¹ý SIOCSIGMAC ºÍ SIOCSIFMAC ÍøÂç½Ó¿ÚµÄ ioctl Ààϵͳµ÷ÓÃÀ´²éѯºÍÉèÖÃÍøÂç½Ó¿ÚµÄ°²È«±ê¼Ç¡£
¡¡¡¡°²È«²ßÂÔ¿ÉÒÔÖ±½Ó±àÈëÄںˣ¬Ò²¿ÉÒÔ±àÒë³É¶ÀÁ¢µÄÄÚºËÄ£¿é£¬ÔÚϵͳÒýµ¼Ê±»òÕßÔËÐÐʱʹÓÃÄ£¿é¼ÓÔØÃüÁî¼ÓÔØ¡£ ²ßÂÔÄ£¿éͨ¹ýÒ»×éÔ¤Ïȶ¨ÒåºÃµÄÈë¿Úº¯ÊýÓëϵͳ½»»¥¡£Í¨¹ýËüÃÇ£¬²ßÂÔÄ£¿éÄܹ»ÕÆÎÕijЩϵͳʼþµÄ·¢Éú£¬²¢ÇÒÔÚ±ØÒªµÄʱºòÓ°ÏìϵͳµÄ·ÃÎÊ¿ØÖƾö²ß¡£ ÿ¸ö²ßÂÔÄ£¿é°üº¬ÏÂÁÐ×é³É²¿·Ö£º
¿ÉÑ¡£º²ßÂÔÅäÖòÎÊý
²ßÂÔÂß¼ºÍ²ÎÊýµÄ¼¯ÖÐʵÏÖ
¿ÉÑ¡£º²ßÂÔÉúÃüÖÜÆÚʼþµÄʵÏÖ£¬±ÈÈ磬²ßÂԵijõʼ»¯ºÍÏú»Ù
¿ÉÑ¡£º¶ÔËùÑ¡Äں˶ÔÏóµÄ°²È«±ê¼Ç½øÐгõʼ»¯¡¢Î¬»¤ºÍÏú»ÙµÄÖ§³Ö
¿ÉÑ¡£º¶ÔËùÑ¡¶ÔÏóµÄʹÓýø³Ì½øÐÐ¼à¿ØÒÔ¼°Ð޸ĶÔÏó°²È«±ê¼ÇµÄÖ§³Ö
²ßÂÔÏà¹ØµÄ·ÃÎÊ¿ØÖÆÈë¿Úº¯ÊýµÄʵÏÖ
¶Ô²ßÂÔ±êÖ¾¡¢Ä£¿éÈë¿Úº¯ÊýºÍ²ßÂÔÌØÐÔµÄÉùÃ÷
¡¡¡¡²ßÂÔÄ£¿é¿ÉÒÔʹÓà MAC_POLICY_SET()
ºêÀ´ÉùÃ÷¡£
¸ÃºêÍê³ÉÒÔϹ¤×÷£ºÎª¸Ã²ßÂÔÃüÃû£¨ÏòϵͳÉùÃ÷¸Ã²ßÂÔÌṩµÄÃû×Ö£©£»Ìá½»²ßÂÔ¶¨ÒåµÄ MAC
Èë¿Úº¯ÊýÏòÁ¿µÄµØÖ·£» °´ÕÕ²ßÂÔµÄÒªÇóÉèÖøòßÂԵļÓÔØ±ê־룬±£Ö¤ MAC
¿ò¼Ü½«ÒÔ²ßÂÔËùÆÚÍûµÄ·½Ê½¶ÔÆä½øÐвÙ×÷£» ÁíÍ⣬»¹¿ÉÄÜÇëÇó¿ò¼ÜΪ²ßÂÔ·ÖÅä±ê¼Ç״̬ slot
Öµ¡£
static struct mac_policy_ops mac_policy_ops = { .mpo_destroy = mac_policy_destroy, .mpo_init = mac_policy_init, .mpo_init_bpfdesc_label = mac_policy_init_bpfdesc_label, .mpo_init_cred_label = mac_policy_init_label, /* ... */ .mpo_check_vnode_setutimes = mac_policy_check_vnode_setutimes, .mpo_check_vnode_stat = mac_policy_check_vnode_stat, .mpo_check_vnode_write = mac_policy_check_vnode_write, };
¡¡¡¡ÈçÉÏËùʾ£¬MAC ²ßÂÔÈë¿Úº¯ÊýÏòÁ¿£¬mac_policy_ops
£¬
½«²ßÂÔÄ£¿éÖж¨ÒåµÄ¹¦Äܺ¯Êý¹Ò½Óµ½Ìض¨µÄÈë¿Úº¯ÊýµØÖ·ÉÏ¡£
ÔÚÉÔºóµÄ¡°Èë¿Úº¯Êý²Î¿¼¡±Ð¡½ÚÖУ¬½«Ìṩ¿ÉÓÃÈë¿Úº¯Êý¹¦ÄÜÃèÊöºÍÔÐ͵ÄÍêÕûÁÐ±í¡£
ÓëÄ£¿é×¢²áÏà¹ØµÄÈë¿Úº¯ÊýÓÐÁ½¸ö£º.mpo_destroy
ºÍ.mpo_init
¡£ µ±Ä³¸ö²ßÂÔÏòÄ£¿é¿ò¼Ü×¢²á²Ù×÷³É¹¦Ê±£¬.mpo_init
½«±»µ÷Ó㬴˺óÆäËûµÄÈë¿Úº¯Êý²ÅÄܱ»Ê¹Óá£
ÕâÖÖÌØÊâµÄÉè¼ÆÊ¹µÃ²ßÂÔÓлú»á¸ù¾Ý×Ô¼ºµÄÐèÒª£¬½øÐÐÌØ¶¨µÄ·ÖÅäºÍ³õʼ»¯²Ù×÷£¬±ÈÈç¶ÔÌØÊâÊý¾Ý»òËøµÄ³õʼ»¯¡£
Ð¶ÔØÒ»¸ö²ßÂÔÄ£¿éʱ£¬½«µ÷Óà .mpo_destroy
ÓÃÀ´ÊͷŲßÂÔ·ÖÅäµÄÄÚ´æ¿Õ¼ä»ò×¢ÏúÆäÉêÇëµÄËø¡£
Ŀǰ£¬ÎªÁË·ÀÖ¹ÆäËûÈë¿Úº¯Êý±»Í¬Ê±µ÷Ó㬵÷ÓÃÉÏÊöÁ½¸öÈë¿Úº¯ÊýµÄ½ø³Ì±ØÐë³ÖÓÐ MAC
²ßÂÔÁ´±íµÄ»¥³âËø£ºÕâÖÖÏÞÖÆ½«±»·Å¿ª£¬
µ«Óë´Ëͬʱ£¬½«ÒªÇó²ßÂÔ±ØÐë½÷É÷ʹÓÃÄÚºËÔÓï,ÒÔ±ÜÃâÓÉÓÚÉÏËø´ÎÐò»ò˯ÃßÔì³ÉËÀËø¡£
¡¡¡¡Ö®ËùÒÔÏò²ßÂÔÉùÃ÷Ìṩģ¿éÃû×ÖÓò£¬ÊÇΪÁËÄܹ»Î¨Ò»±êʶ¸ÃÄ£¿é£¬ÒÔ±ã½âÎöÄ£¿éÒÀÀµ¹ØÏµ¡£Ñ¡ÔñʹÓÃÇ¡µ±µÄ×Ö·û´®×÷ΪÃû×Ö¡£ ÔÚ²ßÂÔ¼ÓÔØºÍÐ¶ÔØÊ±£¬²ßÂÔµÄÍêÕû×Ö·û´®Ãû×Ö½«¾ÓÉÄÚºËÈÕÖ¾ÏÔʾ¸øÓû§¡£ÁíÍ⣬µ±ÏòÓû§½ø³Ì±¨¸æ×´Ì¬ÐÅϢʱҲ»á°üº¬¸Ã×Ö·û´®¡£
¡¡¡¡ÔÚÉùÃ÷ʱÌṩ±êÖ¾²ÎÊýÓòµÄ»úÖÆ£¬ÔÊÐí²ßÂÔÄ£¿éÔÚ×÷Ϊģ¿é±»¼ÓÔØÊ±£¬¾Í×ÔÉíÌØÐÔÏò MAC ¿ò¼ÜÌṩ˵Ã÷¡£ Ŀǰ£¬ÒѾ¶¨ÒåµÄ±êÖ¾ÓÐÈý¸ö£º
±íʾ¸Ã²ßÂÔÄ£¿é¿ÉÒÔ±»Ð¶ÔØ¡£ Èç¹ûδÌṩ¸Ã±êÖ¾£¬Ôò±íʾ¸Ã²ßÂÔÄ£¿é¾Ü¾ø±»Ð¶ÔØ¡£ ÄÇЩʹÓð²È«±ê¼ÇµÄ״̬£¬¶øÓÖ²»ÄÜÔÚÔËÐÐʱÊͷŸÃ״̬µÄÄ£¿é¿ÉÄÜ»áÉèÖøñêÖ¾¡£
±íʾ¸Ã²ßÂÔÄ£¿é±ØÐëÔÚϵͳÒýµ¼¹ý³Ìʱ½øÐмÓÔØºÍ³õʼ»¯¡£ Èç¹û¸Ã±êÖ¾±»ÉèÖã¬ÄÇôÔÚϵͳÒýµ¼Ö®ºó×¢²á¸ÃÄ£¿éµÄÇëÇ󽫱» MAC ¿ò¼ÜËù¾Ü¾ø¡£ ÄÇЩÐèҪΪ´ó·¶Î§µÄϵͳ¶ÔÏó½øÐа²È«±ê¼Ç³õʼ»¯¹¤×÷£¬¶øÓÖ²»ÄÜ´¦Àíº¬ÓÐδ±»ÕýÈ·³õʼ»¯°²È«±ê¼ÇµÄ¶ÔÏóµÄ²ßÂÔÄ£¿é¿ÉÄÜ»áÉèÖøñêÖ¾¡£
±íʾ¸Ã²ßÂÔÄ£¿éÒªÇóΪ Mbuf Ö¸¶¨°²È«±ê¼Ç£¬²¢ÇÒΪ´æ´¢Æä±ê¼ÇËùÐèµÄÄÚ´æ¿Õ¼ä×ÜÊÇÌáǰ·ÖÅäºÃµÄ¡£ ȱʡÇé¿öÏ£¬MAC ¿ò¼Ü²¢²»»áΪ Mbuf ·ÖÅä±ê¼Ç´æ´¢£¬³ý·ÇϵͳÖÐ×¢²áµÄ²ßÂÔÄ£¿éÖÐÖÁÉÙÓÐÒ»¸öÉèÖÃÁ˸ñêÖ¾¡£ ÕâÖÖ×ö·¨ÔÚûÓвßÂÔÐèÒª¶Ô Mbuf ×ö±ê¼Çʱ£¬ÏÔÖøµØÌáÉýÁËÏµÍ³ÍøÂçÐÔÄÜ¡£ÁíÍ⣬ÔÚÄ³Ð©ÌØÊâ»·¾³Ï£¬¿ÉÒÔͨ¹ýÉèÖÃÄÚºËÑ¡Ï MAC_ALWAYS_LABEL_MBUF£¬Ç¿ÖÆ MAC ¿ò¼ÜΪ Mbuf µÄ°²È«±ê¼Ç·ÖÅä´æ´¢£¬¶ø²»ÂÛÉÏÊö±êÖ¾ÈçºÎÉèÖá£
×¢Òâ: ÄÇЩʹÓÃÁË MPC_LOADTIME_FLAG_LABELMBUFS ±êÖ¾µ«Ã»ÓÐÉèÖà MPC_LOADTIME_FLAG_NOTLATE ±êÖ¾µÄ ²ßÂÔÄ£¿é±ØÐëÄܹ»ÕýÈ·µØ´¦Àíͨ¹ýÈë¿Úº¯Êý´«ÈëµÄֵΪ NULL µÄ Mbuf °²È«±ê¼ÇÖ¸Õë¡£ ÕâÊÇÒòΪÄÇЩûÓзÖÅä±ê¼Ç´æ´¢µÄ´¦ÀíÖÐµÄ Mbuf ÔÚÒ»¸öÐèÒª Mbuf °²È«±ê¼ÇµÄ²ßÂÔÄ£¿é¼ÓÔØÖ®ºó£¬ Æä°²È«±ê¼ÇµÄÖ¸Õ뽫ÈÔȻΪ¿Õ¡£ Èç¹û²ßÂÔÔÚÍøÂç×Óϵͳ»îԾ֮ǰ±»¼ÓÔØ£¨¼´£¬¸Ã²ßÂÔ²»ÊDZ»ÍƳټÓÔØµÄ£©£¬ÄÇôËùÓÐµÄ Mbuf µÄ±ê¼Ç´æ´¢µÄ·ÖÅä¾Í¿ÉÒԵõ½±£Ö¤¡£
¡¡¡¡MAC ¿ò¼ÜΪע²áµÄ²ßÂÔÌṩËÄÖÖÀàÐ͵ÄÈë¿Úº¯Êý£º ²ßÂÔ×¢²áºÍ¹ÜÀíÈë¿Úº¯Êý£»
ÓÃÓÚ´¦ÀíÄں˶ÔÏóÉùÃ÷ÖÜÆÚʼþ£¬Èç³õʼ»¯¡¢ ´´½¨ºÍÏú»Ù£¬µÄÈë¿Úº¯Êý£»
´¦Àí¸Ã²ßÂÔÄ£¿é¸ÐÐËȤµÄ·ÃÎÊ¿ØÖƾö²ßʼþµÄÈë¿Úº¯Êý£»
ÒÔ¼°ÓÃÓÚ¹ÜÀí¶ÔÏó°²È«±ê¼ÇµÄµ÷ÓÃÈë¿Úº¯Êý¡£ ´ËÍ⣬ »¹ÓÐÒ»¸ö mac_syscall()
Èë¿Úº¯Êý£¬ ±»²ßÂÔÄ£¿éÓÃÓÚÔÚ²»×¢²áеÄϵͳµ÷ÓõÄǰÌáÏ£¬
À©Õ¹Äں˽ӿڡ£
¡¡¡¡²ßÂÔÄ£¿éµÄ±àдÈËÔ±³ýÁ˱ØÐëÇå³þÔÚ½øÈëÌØ¶¨Èë¿Úº¯ÊýÖ®ºó£¬ ÄÄЩ¶ÔÏóËøÊÇ¿ÉÓõÄÖ®Í⣬ »¹Ó¦¸ÃÊìÖªÄÚºËËù²ÉÓõļÓËø²ßÂÔ¡£ ±à³ÌÈËÔ±ÔÚÈë¿Úº¯ÊýÖ®ÄÚÓ¦¸Ã±ÜÃâʹÓ÷ÇÒ¶½ÚµãËø£¬ ²¢ÇÒ×ñÑ·ÃÎʺÍÐ޸ĶÔÏóʱµÄ¼ÓËø¹æ³Ì£¬ ÒÔ½µµÍµ¼ÖÂËÀËøµÄ¿ÉÄÜÐÔ¡£ ÌØ±ðµØ£¬ ³ÌÐòÔ±Ó¦¸ÃÇå³þ£¬ ËäÈ»ÔÚͨ³£Çé¿öÏ£¬ ½øÈëÈë¿Úº¯ÊýÖ®ºó£¬ ÒѾÉÏÁËÒ»Ð©Ëø£¬ ¿ÉÒÔ°²È«µØ·ÃÎʶÔÏó¼°Æä°²È«±ê¼Ç£¬ µ«ÊÇÕâ²¢²»Äܱ£Ö¤¶ÔËüÃǽøÐÐÐ޸ģ¨ °üÀ¨¶ÔÏó±¾ÉíºÍÆä°²È«±ê¼Ç£© Ò²Êǰ²È«µÄ¡£ Ïà¹ØµÄÉÏËøÐÅÏ¢£¬¿ÉÒԲο¼ MAC ¿ò¼ÜÈë¿Úº¯ÊýµÄÏà¹ØÎĵµ¡£
¡¡¡¡²ßÂÔÈë¿Úº¯Êý°ÑÁ½¸ö·Ö±ðÖ¸Ïò¶ÔÏó±¾ÉíºÍÆä°²È«±ê¼ÇµÄÖ¸Õë´«µÝ¸ø²ßÂÔÄ£¿é¡£ ÕâÑùÒ»À´£¬¼´Ê¹²ßÂÔ²¢²»ÊìϤ¶ÔÏóÄÚ²¿½á¹¹£¬Ò²ÄÜ»ùÓÚ±ê¼Ç×÷³öÕýÈ·¾ö²ß¡£ Ö»Óнø³ÌÐÅÈÎ×´Õâ¸ö¶ÔÏóÀýÍ⣺MAC ¿ò¼Ü×ÜÊǼÙÉèËùÓеIJßÂÔÄ£¿éÊÇÀí½âÆäÄÚ²¿½á¹¹µÄ¡£
mpo_init
¡¡¡¡²ßÂÔ¼ÓÔØÊ¼þ¡£µ±Ç°½ø³ÌÕý³ÖÓвßÂÔÁ´±íÉϵĻ¥³âËø£¬Òò´ËÊÇ·Ç˯Ãߵģ¬¶ÔÆäËûÄÚºË×ÓϵͳµÄµ÷ÓÃÒ²ÐëÉ÷ÖØ¡£ Èç¹ûÐèÒªÔÚ²ßÂÔ³õʼ»¯½×¶Î½øÐпÉÄÜÔì³É˯Ãß×èÈûµÄ´æ´¢·ÖÅä²Ù×÷£¬¿ÉÒÔ½«ËüÃÇ·ÅÔÚÒ»¸öµ¥¶ÀµÄÄ£¿é SYSINIT() ¹ý³ÌÖм¯ÖнøÐС£
mpo_syscall
¡¡¡¡¸ÃÈë¿Úº¯ÊýÌṩ²ßÂÔ¸´ÓõÄϵͳµ÷Óã¬ÕâÑù²ßÂÔÄ£¿é²»ÐèҪΪÆäÏòÓû§½ø³ÌÌṩµÄÿһ¸ö¶îÍâ·þÎñ¶ø×¢²áרÓõÄϵͳµ÷ÓᣠÓÉÓ¦ÓóÌÐòÌṩµÄ²ßÂÔ×¢²áÃû×ÖÀ´È·¶¨ÌṩÆäËùÉêÇë·þÎñµÄÌØ¶¨²ßÂÔ£¬ËùÓвÎÊý½«Í¨¹ý¸ÃÈë¿Úº¯Êý´«µÝ¸ø±»µ÷ÓõIJßÂÔ¡£ µ±ÊµÏÖзþÎñʱ£¬°²È«Ä£¿é±ØÐëÔÚ±ØÒªÊ±Í¨¹ý MAC ¿ò¼Üµ÷ÓÃÏàÓ¦µÄ·ÃÎÊ¿ØÖƼì²é»úÖÆ¡£ ±È·½Ëµ£¬¼ÙÈçÒ»¸ö²ßÂÔʵÏÖÁËijÖÖ¶îÍâµÄÐźŹ¦ÄÜ£¬ÄÇôËüÓ¦¸Ãµ÷ÓÃÏà¹ØµÄÐźŷÃÎÊ¿ØÖƼì²é£¬ÒÔ½ÓÊÜ MAC ¿ò¼ÜÖÐ×¢²áµÄÆäËû²ßÂԵļì²é¡£
×¢Òâ: ²»Í¬µÄÄ£¿éÐèÒª²¢·¢µØÊÖ¶¯½øÐÐ
copyin()
¿½±´ÏµÍ³µ÷ÓÃÊý¾Ý¡£
mpo_thread_userret
¡¡¡¡Ê¹ÓøÃÈë¿Úº¯Êý£¬²ßÂÔÄ£¿éÄܹ»ÔÚÏ̷߳µ»ØÓû§¿Õ¼äʱ£¨ÏµÍ³µ÷Ó÷µ»Ø¡¢Òì³£·µ»ØµÈµÈ£©½øÐÐ MAC Ïà¹ØµÄ´¦Àí¹¤×÷¡£ ʹÓö¯Ì¬½ø³Ì±ê¼ÇµÄ²ßÂÔÐèҪʹÓøÃÈë¿Úº¯Êý£¬ÒòΪÔÚ´¦Àíϵͳµ÷ÓõĹý³ÌÖУ¬²¢²»ÊÇÔÚÈÎÒâʱ¿Ì¶¼ÄÜÉêÇëµ½½ø³ÌËøµÄ£» ½ø³ÌµÄ±ê¼Ç¿ÉÄܱíʾ´«Í³µÄÈÏÖ¤ÐÅÏ¢¡¢½ø³ÌÀúÊ·¼Ç¼»òÕ߯äËûÊý¾Ý¡£ÎªÊ¹ÓøÃÈë¿Úº¯Êý£¬¶Ô½ø³ÌÐÅÈÎ×´Ëù×÷µÄÐÞ¸Ä ¿ÉÄܱ»´æ·ÅÔÚ p_label ,¸ÃÓòÊÜÒ»¸ö½ø³Ì¼¶×ÔÐýËøµÄ±£»¤£»½ÓÏÂÀ´£¬ÉèÖÃÏ̼߳¶µÄTDF_ASTPENDING ±ê־λºÍ½ø³Ì¼¶µÄPS_MACPENDM±ê־룬±íÃ÷½«µ÷¶ÈÒ»¸ö¶Ô userret Èë¿Úº¯ÊýµÄµ÷Óá£Í¨¹ý¸ÃÈë¿Úº¯Êý£¬ ²ßÂÔ¿ÉÒÔÔÚÏà¶Ô¼òµ¥µÄͬ²½ÉÏÏÂÎÄÖд´½¨ÐÅÈÎ×´µÄÌæ´úÆ·¡£²ßÂÔ±à³ÌÈËÔ±±ØÐëÇå³þ£¬ÐèÒª±£Ö¤Óëµ÷¶ÈÒ»¸ö AST Ïà¹ØµÄʼþÖ´ÐдÎÐò£¬ ͬʱËùÖ´ÐÐµÄ AST ¿ÉÄܸܺ´ÔÓ£¬¶øÇÒÔÚ´¦Àí¶àÏß³ÌÓ¦ÓóÌÐòʱ¿ÉÄܱ»ÖØÈë¡£
mpo_init_bpfdesc_label
¡¡¡¡ÎªÒ»¸öнüʵÀý»¯µÄ bpfdesc£¨BPF ÃèÊö×Ó£©³õʼ»¯±ê¼Ç¡£¿ÉÒÔ˯Ãß¡£
mpo_init_ipq_label
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»Ó¦ÓõÄбê¼Ç | |
flag |
˯Ãß/²»Ë¯Ãß malloc(9); ²Î¼ûÏÂÎÄ |
¡¡¡¡ÎªÒ»¸öнüʵÀý»¯µÄ IP ·ÖÆ¬ÖØ×é¶ÓÁгõʼ»¯±ê¼Ç¡£ÆäÖеÄflag
Óò¿ÉÄÜÈ¡M_WAITOK
»òM_NOWAIT
Ö®Ò»£¬ÓÃÀ´±ÜÃâÔڸóõʼ»¯µ÷ÓÃÖÐÒòΪ malloc(9) ¶ø½øÈë˯Ãß¡£IP
·ÖÆ¬ÖØ×é¶ÓÁеķÖÅä²Ù×÷ͨ³£ÊÇÔÚ
¶ÔÐÔÄÜÓÐÑϸñÒªÇóµÄ»·¾³Ï½øÐеģ¬Òò´ËʵÏÖ´úÂë±ØÐëСÐĵرÜÃâ˯Ãߺͳ¤Ê±¼äµÄ²Ù×÷¡£IP
·ÖÆ¬ÖØ×é¶ÓÁзÖÅä²Ù×÷ʧ°ÜʱÉÏÊöÈë¿Úº¯Êý½«Ê§°Ü·µ»Ø¡£
mpo_init_mbuf_label
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
flag |
˯Ãß/²»Ë¯Ãß malloc(9); ²Î¼ûÏÂÎÄ | |
label |
½«±»³õʼ»¯µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÎªÒ»¸öнüʵÀý»¯µÄ mbuf Êý¾Ý°üÍ·²¿£¨mbuf
£©³õʼ»¯±ê¼Ç¡£ ÆäÖеÄflag
µÄÖµ¿ÉÄÜÈ¡M_WAITOK
ºÍM_NOWAIT
Ö®Ò»£¬ ÓÃÀ´±ÜÃâÔڸóõʼ»¯µ÷ÓÃÖÐÒòΪ malloc(9) ¶ø½øÈë˯Ãß¡£Mbuf
Í·²¿µÄ·ÖÅä²Ù×÷³£³£ÔÚ¶ÔÐÔÄÜÓÐÑϸñÒªÇóµÄ»·¾³Ï±»Æµ·±Ö´ÐУ¬
Òò´ËʵÏÖ´úÂë±ØÐëСÐĵرÜÃâ˯Ãߺͳ¤Ê±¼äµÄ²Ù×÷¡£ÉÏÊöÈë¿Úº¯ÊýÔÚ Mbuf
Í·²¿·ÖÅä²Ù×÷ʧ°Üʱ½«Ê§°Ü·µ»Ø¡£
mpo_init_socket_label
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»³õʼ»¯µÄбê¼Ç | |
flag |
malloc(9) flags |
¡¡¡¡ÎªÒ»¸ö¸Õ¸ÕʵÀý»¯µÄÌ×½Ó×Ö³õʼ»¯°²È«±ê¼Ç¡£ÆäÖÐµÄ flag
ÓòµÄÖµ±ØÐë±»Ö¸¶¨Îª M_WAITOK
ºÍM_NOWAIT
Ö®Ò»£¬ÒÔ±ÜÃâÔڸóõʼ»¯³ÌÖÐʹÓÿÉÄÜ˯ÃßµÄmalloc(9) ¡£
mpo_init_socket_peer_label
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»³õʼ»¯µÄбê¼Ç | |
flag |
malloc(9) flags |
¡¡¡¡Îª¸Õ¸ÕʵÀý»¯µÄÌ×½Ó×Ö¶ÔµÈÌå½øÐбê¼ÇµÄ³õʼ»¯¡£ÆäÖÐµÄ flag
ÓòµÄÖµ±ØÐë±»Ö¸¶¨Îª M_WAITOK
ºÍ
M_NOWAIT
Ö®Ò»£¬ÒÔ±ÜÃâÔڸóõʼ»¯³ÌÖÐʹÓÿÉÄÜ˯ÃßµÄ malloc(9)¡£
mpo_destroy_bpfdesc_label
¡¡¡¡Ïú»ÙÒ»¸ö BPF ÃèÊö×ÓÉϵıê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäÓë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_cred_label
¡¡¡¡Ïú»ÙÒ»¸öÐÅÈÎ×´Éϵıê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄÓë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_devfsdirent_label
¡¡¡¡Ïú»ÙÒ»¸ö devfs ±íÏîÉϵıê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄÓë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_ifnet_label
¡¡¡¡Ïú»ÙÓëÒ»¸öÒÑɾ³ý½Ó¿ÚÏà¹ØÁªµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄÓë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_ipq_label
¡¡¡¡Ïú»ÙÓëÒ»¸ö IP ·ÖƬ¶ÓÁÐÏà¹ØÁªµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄÓë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_mbuf_label
¡¡¡¡Ïú»ÙÓëÒ»¸ö Mbuf Ïà¹ØÁªµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄÓë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_mount_label
¡¡¡¡Ïú»ÙÓëÒ»¸ö mount µãÏà¹ØÁªµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄÓë
mntlabel
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_mount_label
¡¡¡¡Ïú»ÙÓëÒ»¸ö mount µãÏà¹ØÁªµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄ£¬Óë
mntlabel
ºÍfslabel
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_socket_label
¡¡¡¡Ïú»ÙÓëÒ»¸öÌ×½Ó×ÖÏà¹ØÁªµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄ£¬Óë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_socket_peer_label
¡¡¡¡Ïú»ÙÓëÒ»¸öÌ×½Ó×ÖÏà¹ØÁªµÄ¶ÔµÈʵÌå±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄ£¬Óë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_pipe_label
¡¡¡¡Ïú»ÙÒ»¸ö¹ÜµÀµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄ£¬Óë label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_proc_label
¡¡¡¡Ïú»ÙÒ»¸ö½ø³ÌµÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄ£¬Óë label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_destroy_vnode_label
¡¡¡¡Ïú»ÙÒ»¸ö vnode µÄ±ê¼Ç¡£ÔÚ¸ÃÈë¿Úº¯ÊýÖУ¬²ßÂÔÓ¦µ±ÊÍ·ÅËùÓÐÔÚÄÚ²¿·ÖÅäµÄ£¬Óë
label
Ïà¹ØÁªµÄ´æ´¢¿Õ¼ä£¬ÒÔ±ãÏú»Ù¸Ã±ê¼Ç¡£
mpo_externalize_cred_label
int mpo_externalize_cred_label
(struct label *label,
char *element_name, struct sbuf *sb, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«ÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç | |
element_name |
ÐèÒªÍⲿ±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
sb |
ÓÃÀ´´æ·Å±ê¼ÇµÄÎı¾±íʾÐÎʽµÄ×Ö·ûbuffer | |
claimed |
Èç¹û¿ÉÒÔÌî³äelement_data Óò£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç½á¹¹£¬²úÉúÒ»¸öÒÔÍⲿÐÎʽ±íʾµÄ±ê¼Ç¡£ Ò»¸öÍⲿÐÎʽ±ê¼Ç£¬ÊDZê¼ÇÄÚÈݵÄÎı¾±íʾ£¬ËüÓÉÓû§¼¶µÄÓ¦ÓóÌÐòʹÓã¬ÊÇÓû§¿É¶ÁµÄ¡£ ĿǰµÄMACʵÏÖ·½°¸½«ÒÀ´Îµ÷ÓòßÂÔµÄÏàÓ¦Èë¿Úº¯Êý£¬Òò´Ë£¬ ¾ßÌå²ßÂÔµÄʵÏÖ´úÂ룬ÐèÒªÔÚÌîдsb֮ǰ£¬Ïȼì²éelement_nameÖÐÖ¸¶¨µÄÃû×Ö¡£ Èç¹ûelement_nameÖеÄÄÚÈÝÓëÄãµÄ²ßÂÔÃû×Ö²»Ïà·û£¬ÔòÖ±½Ó·µ»Ø0¡£ ½öµ±×ª»»±ê¼ÇÊý¾ÝµÄ¹ý³ÌÖгöÏÖ´íÎóʱ£¬²Å·µ»Ø·Ç0Öµ¡£ Ò»µ©²ßÂÔ¾ö¶¨Ìîдelement_data£¬µÝÔö*claimµÄÊýÖµ¡£
mpo_externalize_ifnet_label
int mpo_externalize_ifnet_label
(struct label
*label, char *element_name, struct sbuf *sb, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«ÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç | |
element_name |
ÐèÒªÍⲿ±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
sb |
ÓÃÀ´´æ·Å±ê¼ÇµÄÎı¾±íʾÐÎʽµÄ×Ö·ûbuffer | |
claimed |
Èç¹û¿ÉÒÔÌî³äelement_data Óò£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç½á¹¹£¬²úÉúÒ»¸öÒÔÍⲿÐÎʽ±íʾµÄ±ê¼Ç¡£ Ò»¸öÍⲿÐÎʽ±ê¼Ç£¬ÊDZê¼ÇÄÚÈݵÄÎı¾±íʾ£¬ËüÓÉÓû§¼¶µÄÓ¦ÓóÌÐòʹÓã¬ÊÇÓû§¿É¶ÁµÄ¡£ ĿǰµÄMACʵÏÖ·½°¸½«ÒÀ´Îµ÷ÓòßÂÔµÄÏàÓ¦Èë¿Úº¯Êý£¬Òò´Ë£¬ ¾ßÌå²ßÂÔµÄʵÏÖ´úÂ룬ÐèÒªÔÚÌîдsb֮ǰ£¬Ïȼì²éelement_nameÖÐÖ¸¶¨µÄÃû×Ö¡£ Èç¹ûelement_nameÖеÄÄÚÈÝÓëÄãµÄ²ßÂÔÃû×Ö²»Ïà·û£¬ÔòÖ±½Ó·µ»Ø0¡£ ½öµ±×ª»»±ê¼ÇÊý¾ÝµÄ¹ý³ÌÖгöÏÖ´íÎóʱ£¬²Å·µ»Ø·Ç0Öµ¡£ Ò»µ©²ßÂÔ¾ö¶¨Ìîдelement_data£¬µÝÔö*claimµÄÊýÖµ¡£
mpo_externalize_pipe_label
int mpo_externalize_pipe_label
(struct label *label,
char *element_name, struct sbuf *sb, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«ÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç | |
element_name |
ÐèÒªÍⲿ±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
sb |
ÓÃÀ´´æ·Å±ê¼ÇµÄÎı¾±íʾÐÎʽµÄ×Ö·ûbuffer | |
claimed |
Èç¹û¿ÉÒÔÌî³äelement_data Óò£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç½á¹¹£¬²úÉúÒ»¸öÒÔÍⲿÐÎʽ±íʾµÄ±ê¼Ç¡£ Ò»¸öÍⲿÐÎʽ±ê¼Ç£¬ÊDZê¼ÇÄÚÈݵÄÎı¾±íʾ£¬ËüÓÉÓû§¼¶µÄÓ¦ÓóÌÐòʹÓã¬ÊÇÓû§¿É¶ÁµÄ¡£ ĿǰµÄMACʵÏÖ·½°¸½«ÒÀ´Îµ÷ÓòßÂÔµÄÏàÓ¦Èë¿Úº¯Êý£¬Òò´Ë£¬ ¾ßÌå²ßÂÔµÄʵÏÖ´úÂ룬ÐèÒªÔÚÌîдsb֮ǰ£¬Ïȼì²éelement_nameÖÐÖ¸¶¨µÄÃû×Ö¡£ Èç¹ûelement_nameÖеÄÄÚÈÝÓëÄãµÄ²ßÂÔÃû×Ö²»Ïà·û£¬ÔòÖ±½Ó·µ»Ø0¡£ ½öµ±×ª»»±ê¼ÇÊý¾ÝµÄ¹ý³ÌÖгöÏÖ´íÎóʱ£¬²Å·µ»Ø·Ç0Öµ¡£ Ò»µ©²ßÂÔ¾ö¶¨Ìîдelement_data£¬µÝÔö*claimµÄÊýÖµ¡£
mpo_externalize_socket_label
int mpo_externalize_socket_label
(struct label
*label, char *element_name, struct sbuf *sb, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«ÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç | |
element_name |
ÐèÒªÍⲿ±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
sb |
ÓÃÀ´´æ·Å±ê¼ÇµÄÎı¾±íʾÐÎʽµÄ×Ö·ûbuffer | |
claimed |
Èç¹û¿ÉÒÔÌî³äelement_data Óò£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç½á¹¹£¬²úÉúÒ»¸öÒÔÍⲿÐÎʽ±íʾµÄ±ê¼Ç¡£ Ò»¸öÍⲿÐÎʽ±ê¼Ç£¬ÊDZê¼ÇÄÚÈݵÄÎı¾±íʾ£¬ËüÓÉÓû§¼¶µÄÓ¦ÓóÌÐòʹÓã¬ÊÇÓû§¿É¶ÁµÄ¡£ ĿǰµÄMACʵÏÖ·½°¸½«ÒÀ´Îµ÷ÓòßÂÔµÄÏàÓ¦Èë¿Úº¯Êý£¬Òò´Ë£¬ ¾ßÌå²ßÂÔµÄʵÏÖ´úÂ룬ÐèÒªÔÚÌîдsb֮ǰ£¬Ïȼì²éelement_nameÖÐÖ¸¶¨µÄÃû×Ö¡£ Èç¹ûelement_nameÖеÄÄÚÈÝÓëÄãµÄ²ßÂÔÃû×Ö²»Ïà·û£¬ÔòÖ±½Ó·µ»Ø0¡£ ½öµ±×ª»»±ê¼ÇÊý¾ÝµÄ¹ý³ÌÖгöÏÖ´íÎóʱ£¬²Å·µ»Ø·Ç0Öµ¡£ Ò»µ©²ßÂÔ¾ö¶¨Ìîдelement_data£¬µÝÔö*claimµÄÊýÖµ¡£
mpo_externalize_socket_peer_label
int mpo_externalize_socket_peer_label
(struct label
*label, char *element_name, struct sbuf *sb, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«ÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç | |
element_name |
ÐèÒªÍⲿ±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
sb |
ÓÃÀ´´æ·Å±ê¼ÇµÄÎı¾±íʾÐÎʽµÄ×Ö·ûbuffer | |
claimed |
Èç¹û¿ÉÒÔÌî³äelement_data Óò£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç½á¹¹£¬²úÉúÒ»¸öÒÔÍⲿÐÎʽ±íʾµÄ±ê¼Ç¡£ Ò»¸öÍⲿÐÎʽ±ê¼Ç£¬ÊDZê¼ÇÄÚÈݵÄÎı¾±íʾ£¬ËüÓÉÓû§¼¶µÄÓ¦ÓóÌÐòʹÓã¬ÊÇÓû§¿É¶ÁµÄ¡£ ĿǰµÄMACʵÏÖ·½°¸½«ÒÀ´Îµ÷ÓòßÂÔµÄÏàÓ¦Èë¿Úº¯Êý£¬Òò´Ë£¬ ¾ßÌå²ßÂÔµÄʵÏÖ´úÂ룬ÐèÒªÔÚÌîдsb֮ǰ£¬Ïȼì²éelement_nameÖÐÖ¸¶¨µÄÃû×Ö¡£ Èç¹ûelement_nameÖеÄÄÚÈÝÓëÄãµÄ²ßÂÔÃû×Ö²»Ïà·û£¬ÔòÖ±½Ó·µ»Ø0¡£ ½öµ±×ª»»±ê¼ÇÊý¾ÝµÄ¹ý³ÌÖгöÏÖ´íÎóʱ£¬²Å·µ»Ø·Ç0Öµ¡£ Ò»µ©²ßÂÔ¾ö¶¨Ìîдelement_data£¬µÝÔö*claimµÄÊýÖµ¡£
mpo_externalize_vnode_label
int mpo_externalize_vnode_label
(struct label
*label, char *element_name, struct sbuf *sb, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«ÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç | |
element_name |
ÐèÒªÍⲿ±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
sb |
ÓÃÀ´´æ·Å±ê¼ÇµÄÎı¾±íʾÐÎʽµÄ×Ö·ûbuffer | |
claimed |
Èç¹û¿ÉÒÔÌî³äelement_data Óò£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç½á¹¹£¬²úÉúÒ»¸öÒÔÍⲿÐÎʽ±íʾµÄ±ê¼Ç¡£ Ò»¸öÍⲿÐÎʽ±ê¼Ç£¬ÊDZê¼ÇÄÚÈݵÄÎı¾±íʾ£¬ËüÓÉÓû§¼¶µÄÓ¦ÓóÌÐòʹÓã¬ÊÇÓû§¿É¶ÁµÄ¡£ ĿǰµÄMACʵÏÖ·½°¸½«ÒÀ´Îµ÷ÓòßÂÔµÄÏàÓ¦Èë¿Úº¯Êý£¬Òò´Ë£¬ ¾ßÌå²ßÂÔµÄʵÏÖ´úÂ룬ÐèÒªÔÚÌîдsb֮ǰ£¬Ïȼì²éelement_nameÖÐÖ¸¶¨µÄÃû×Ö¡£ Èç¹ûelement_nameÖеÄÄÚÈÝÓëÄãµÄ²ßÂÔÃû×Ö²»Ïà·û£¬ÔòÖ±½Ó·µ»Ø0¡£ ½öµ±×ª»»±ê¼ÇÊý¾ÝµÄ¹ý³ÌÖгöÏÖ´íÎóʱ£¬²Å·µ»Ø·Ç0Öµ¡£ Ò»µ©²ßÂÔ¾ö¶¨Ìîдelement_data£¬µÝÔö*claimµÄÊýÖµ¡£
mpo_internalize_cred_label
int mpo_internalize_cred_label
(struct label *label,
char *element_name, char *element_data, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»Ìî³äµÄ±ê¼Ç | |
element_name |
ÐèÒªÄÚ²¿±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
element_data |
ÐèÒª±»×ª»»µÄÎı¾Êý¾Ý | |
claimed |
Èç¹ûÊý¾Ý±»Õýȷת»»£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾ÝÒ»¸öÎı¾ÐÎʽµÄÍⲿ±íʾ±ê¼ÇÊý¾Ý£¬´´½¨Ò»¸öÄÚ²¿ÐÎʽµÄ±ê¼Ç½á¹¹¡£ ĿǰµÄMAC·½°¸½«ÒÀ´Îµ÷ÓÃËùÓвßÂÔµÄÏà¹ØÈë¿Úº¯Êý£¬À´ÏìÓ¦±ê¼ÇµÄÄÚ²¿×ª»»ÇëÇó£¬ Òò´Ë£¬ÊµÏÖ´úÂë±ØÐëÊ×ÏÈͨ¹ý±È½Ïelement_nameÖеÄÄÚÈݺÍ×Ô¼ºµÄ²ßÂÔÃû×Ö£¬ À´È·¶¨ÊÇ·ñÐèҪת»»element_dataÖдæ·ÅµÄÊý¾Ý¡£ ÀàËÆµÄ£¬Èç¹ûÃû×Ö²»Æ¥Åä»òÕßÊý¾Ýת»»²Ù×÷³É¹¦£¬¸Ãº¯Êý·µ»Ø0£¬²¢µÝÔö*claimedµÄÖµ¡£
mpo_internalize_ifnet_label
int mpo_internalize_ifnet_label
(struct label
*label, char *element_name, char *element_data, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»Ìî³äµÄ±ê¼Ç | |
element_name |
ÐèÒªÄÚ²¿±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
element_data |
ÐèÒª±»×ª»»µÄÎı¾Êý¾Ý | |
claimed |
Èç¹ûÊý¾Ý±»Õýȷת»»£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾ÝÒ»¸öÎı¾ÐÎʽµÄÍⲿ±íʾ±ê¼ÇÊý¾Ý£¬´´½¨Ò»¸öÄÚ²¿ÐÎʽµÄ±ê¼Ç½á¹¹¡£ ĿǰµÄMAC·½°¸½«ÒÀ´Îµ÷ÓÃËùÓвßÂÔµÄÏà¹ØÈë¿Úº¯Êý£¬À´ÏìÓ¦±ê¼ÇµÄÄÚ²¿×ª»»ÇëÇó£¬ Òò´Ë£¬ÊµÏÖ´úÂë±ØÐëÊ×ÏÈͨ¹ý±È½Ïelement_nameÖеÄÄÚÈݺÍ×Ô¼ºµÄ²ßÂÔÃû×Ö£¬ À´È·¶¨ÊÇ·ñÐèҪת»»element_dataÖдæ·ÅµÄÊý¾Ý¡£ ÀàËÆµÄ£¬Èç¹ûÃû×Ö²»Æ¥Åä»òÕßÊý¾Ýת»»²Ù×÷³É¹¦£¬¸Ãº¯Êý·µ»Ø0£¬²¢µÝÔö*claimedµÄÖµ¡£
mpo_internalize_pipe_label
int mpo_internalize_pipe_label
(struct label *label,
char *element_name, char *element_data, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»Ìî³äµÄ±ê¼Ç | |
element_name |
ÐèÒªÄÚ²¿±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
element_data |
ÐèÒª±»×ª»»µÄÎı¾Êý¾Ý | |
claimed |
Èç¹ûÊý¾Ý±»Õýȷת»»£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾ÝÒ»¸öÎı¾ÐÎʽµÄÍⲿ±íʾ±ê¼ÇÊý¾Ý£¬´´½¨Ò»¸öÄÚ²¿ÐÎʽµÄ±ê¼Ç½á¹¹¡£ ĿǰµÄMAC·½°¸½«ÒÀ´Îµ÷ÓÃËùÓвßÂÔµÄÏà¹ØÈë¿Úº¯Êý£¬À´ÏìÓ¦±ê¼ÇµÄÄÚ²¿×ª»»ÇëÇó£¬ Òò´Ë£¬ÊµÏÖ´úÂë±ØÐëÊ×ÏÈͨ¹ý±È½Ïelement_nameÖеÄÄÚÈݺÍ×Ô¼ºµÄ²ßÂÔÃû×Ö£¬ À´È·¶¨ÊÇ·ñÐèҪת»»element_dataÖдæ·ÅµÄÊý¾Ý¡£ ÀàËÆµÄ£¬Èç¹ûÃû×Ö²»Æ¥Åä»òÕßÊý¾Ýת»»²Ù×÷³É¹¦£¬¸Ãº¯Êý·µ»Ø0£¬²¢µÝÔö*claimedµÄÖµ¡£
mpo_internalize_socket_label
int mpo_internalize_socket_label
(struct label
*label, char *element_name, char *element_data, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»Ìî³äµÄ±ê¼Ç | |
element_name |
ÐèÒªÄÚ²¿±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
element_data |
ÐèÒª±»×ª»»µÄÎı¾Êý¾Ý | |
claimed |
Èç¹ûÊý¾Ý±»Õýȷת»»£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾ÝÒ»¸öÎı¾ÐÎʽµÄÍⲿ±íʾ±ê¼ÇÊý¾Ý£¬´´½¨Ò»¸öÄÚ²¿ÐÎʽµÄ±ê¼Ç½á¹¹¡£ ĿǰµÄMAC·½°¸½«ÒÀ´Îµ÷ÓÃËùÓвßÂÔµÄÏà¹ØÈë¿Úº¯Êý£¬À´ÏìÓ¦±ê¼ÇµÄÄÚ²¿×ª»»ÇëÇó£¬ Òò´Ë£¬ÊµÏÖ´úÂë±ØÐëÊ×ÏÈͨ¹ý±È½Ïelement_nameÖеÄÄÚÈݺÍ×Ô¼ºµÄ²ßÂÔÃû×Ö£¬ À´È·¶¨ÊÇ·ñÐèҪת»»element_dataÖдæ·ÅµÄÊý¾Ý¡£ ÀàËÆµÄ£¬Èç¹ûÃû×Ö²»Æ¥Åä»òÕßÊý¾Ýת»»²Ù×÷³É¹¦£¬¸Ãº¯Êý·µ»Ø0£¬²¢µÝÔö*claimedµÄÖµ¡£
mpo_internalize_vnode_label
int mpo_internalize_vnode_label
(struct label
*label, char *element_name, char *element_data, int *claimed);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
label |
½«±»Ìî³äµÄ±ê¼Ç | |
element_name |
ÐèÒªÄÚ²¿±íʾ±ê¼ÇµÄ²ßÂÔµÄÃû×Ö | |
element_data |
ÐèÒª±»×ª»»µÄÎı¾Êý¾Ý | |
claimed |
Èç¹ûÊý¾Ý±»Õýȷת»»£¬ÔòÆäÊýÖµµÝÔö |
¡¡¡¡¸ù¾ÝÒ»¸öÎı¾ÐÎʽµÄÍⲿ±íʾ±ê¼ÇÊý¾Ý£¬´´½¨Ò»¸öÄÚ²¿ÐÎʽµÄ±ê¼Ç½á¹¹¡£ ĿǰµÄMAC·½°¸½«ÒÀ´Îµ÷ÓÃËùÓвßÂÔµÄÏà¹ØÈë¿Úº¯Êý£¬À´ÏìÓ¦±ê¼ÇµÄÄÚ²¿×ª»»ÇëÇó£¬ Òò´Ë£¬ÊµÏÖ´úÂë±ØÐëÊ×ÏÈͨ¹ý±È½Ïelement_nameÖеÄÄÚÈݺÍ×Ô¼ºµÄ²ßÂÔÃû×Ö£¬ À´È·¶¨ÊÇ·ñÐèҪת»»element_dataÖдæ·ÅµÄÊý¾Ý¡£ ÀàËÆµÄ£¬Èç¹ûÃû×Ö²»Æ¥Åä»òÕßÊý¾Ýת»»²Ù×÷³É¹¦£¬¸Ãº¯Êý·µ»Ø0£¬²¢µÝÔö*claimedµÄÖµ¡£
¡¡¡¡²ßÂÔÄ£¿éʹÓÃMAC ¿ò¼ÜÌṩµÄ¡°±ê¼Çʼþ¡±ÀàÈë¿Úº¯Êý£¬¶ÔÄں˶ÔÏóµÄ±ê¼Ç½øÐвÙ×÷¡£²ßÂÔÄ£¿é½«¸ÐÐËȤµÄ±»±ê¼ÇÄں˶ÔÏóµÄÏà¹ØÉúÃüÖÜÆÚʼþ ×¢²áÔÚÇ¡µ±µÄÈë¿ÚµãÉÏ¡£¶ÔÏóµÄ³õʼ»¯¡¢´´½¨ºÍÏú»Ùʼþ¾ùÌṩÁ˹³×ӵ㡣ÔÚijЩ¶ÔÏóÉÏ»¹¿ÉÒÔʵÏÖÖØÐ±ê¼Ç£¬¼´£¬ÔÊÐíÓû§½ø³Ì¸Ä±ä¶ÔÏóÉϵıê¼ÇÖµ¡£ ¶ÔijЩ¶ÔÏó¿ÉÒÔʵÏÖÆäÌØ¶¨µÄ¶ÔÏóʼþ£¬±ÈÈçÓë IP ÖØ×éÏà¹ØµÄ±ê¼Çʼþ¡£Ò»¸öµäÐ͵ı»±ê¼Ç¶ÔÏóÔÚÆäÉúÃüÖÜÆÚÖн«ÓµÓÐÏÂÁÐÈë¿Úº¯Êý£º
±ê¼Ç³õʼ»¯ o £¨¶ÔÏóÏà¹ØµÄµÈ´ý£© \ ±ê¼Ç´´½¨ o \ ÖØÐ±ê¼Çʼþ£¬ o--<--. ¸÷ÖÖ¶ÔÏóÏà¹ØµÄ£¬ | | ·ÃÎÊ¿ØÖÆÊ¼þ ~-->--o \ ±ê¼ÇÏú»Ù o
¡¡¡¡Ê¹Óñê¼Ç³õʼ»¯Èë¿Úº¯Êý£¬²ßÂÔ¿ÉÒÔÒÔÒ»ÖÖͳһµÄ¡¢Óë¶ÔÏóʹÓû·¾³Î޹صķ½Ê½ÉèÖñê¼ÇµÄ³õʼֵ¡£ ·ÖÅä¸øÒ»¸ö²ßÂÔµÄȱʡ slot ֵΪ0£¬ÕâÑù²»Ê¹Óñê¼ÇµÄ²ßÂÔ¿ÉÄܲ¢²»ÐèÒªÖ´ÐÐרÃŵijõʼ»¯²Ù×÷¡£
¡¡¡¡±ê¼ÇµÄ´´½¨Ê¼þ·¢ÉúÔÚ½«Ò»¸öÄÚºËÊý¾Ý½á¹¹Í¬Ò»¸öÕæÊµµÄÄں˶ÔÏóÏà¹ØÁª£¨Äں˶ÔÏóʵÀý»¯£©µÄʱ¿Ì¡£ ÀýÈ磬ÔÚÕæÕý±»Ê¹ÓÃ֮ǰ£¬ÔÚÒ»¸ö»º³å³ØÄÚÒÑ·ÖÅäµÄ mbuf Êý¾Ý½á¹¹£¬½«±£³ÖΪ¡°Î´Ê¹Óá±×´Ì¬¡£ Òò´Ë£¬mbuf µÄ·ÖÅä²Ù×÷½«µ¼ÖÂÕë¶Ô¸Ã mbuf µÄ±ê¼Ç³õʼ»¯²Ù×÷£¬¶ø mbuf µÄ´´½¨²Ù×÷Ôò±»ÍƳٵ½¸Ã mbuf ÕæÕýÓëÒ»¸öÊý¾Ý±¨Ïà¹ØÁªµÄʱ¿Ì¡£ ͨ³££¬µ÷ÓÃÕß½«»áÌṩ´´½¨Ê¼þµÄÉÏÏÂÎÄ£¬°üÀ¨´´½¨»·¾³¡¢´´½¨¹ý³ÌÖÐÉæ¼°µÄÆäËû¶ÔÏóµÄ±ê¼ÇµÈ¡£ÀýÈ磬µ±Ò»¸öÌ×½Ó×Ö´´½¨Ò»¸ö mbuf ʱ£¬ ³ýÁËд´½¨µÄ mbuf ¼°Æä±ê¼ÇÖ®Í⣬×÷Ϊ´´½¨ÕßµÄÌ×½Ó×ÖÓëÆä±ê¼ÇÒ²±»Ìá½»¸ø²ßÂÔ¼ì²é¡£ ²»ÌᳫÔÚ´´½¨¶ÔÏóʱ¾ÍΪÆä·ÖÅäÄÚ´æµÄÔÒòÓÐÁ½¸ö£º´´½¨²Ù×÷¿ÉÄÜ·¢ÉúÔÚ¶ÔÐÔÄÜÓÐÑϸñÒªÇóµÄÄں˽ӿÚÉÏ£» ¶øÇÒ£¬ÒòΪ´´½¨µ÷Óò»ÔÊÐíʧ°Ü£¬ËùÒÔÎÞ·¨±¨¸æÄÚ´æ·ÖÅäʧ°Ü¡£
¡¡¡¡¶ÔÏóÌØÓеÄʼþÒ»°ã²»»áÒý·¢ÆäËûµÄ±ê¼Çʼþ£¬µ«ÊÇÔÚ¶ÔÏóÉÏÏÂÎÄ·¢Éú¸Ä±äʱ£¬²ßÂÔʹÓÃËüÃÇ¿ÉÒÔ¶ÔÏà¹Ø±ê¼Ç½øÐÐÐ޸Ļò¸üвÙ×÷¡£
ÀýÈ磬ÔÚMAC_UPDATE_IPQ
Èë¿Úº¯ÊýÖ®ÄÚ£¬Ä³¸ö IP
·ÖÆ¬ÖØ×é¶ÓÁеıê¼Ç¿ÉÄÜ»áÒòΪ¶ÓÁÐÖнÓÊÕÁËÐ嵀 mbuf ¶ø±»¸üС£
¡¡¡¡·ÃÎÊ¿ØÖÆÊ¼þ½«ÔÚºóÐøÕ½ÚÖÐÏêϸÌÖÂÛ¡£
¡¡¡¡²ßÂÔͨ¹ýÖ´Ðбê¼ÇÏú»Ù²Ù×÷£¬ÊÍ·ÅΪÆä·ÖÅäµÄ´æ´¢¿Õ¼ä»òά»¤µÄ״̬£¬Ö®ºóÄں˲ſÉÒÔÖØÓûòÕßÊͷŶÔÏóµÄÄÚºËÊý¾Ý½á¹¹¡£
¡¡¡¡³ýÁËÓëÌØ¶¨Äں˶ÔÏó°ó¶¨µÄÆÕͨ±ê¼ÇÖ®Í⣬»¹ÓÐÒ»ÖÖ¶îÍâµÄ±ê¼ÇÀàÐÍ£ºÁÙʱ±ê¼Ç¡£ÕâЩ±ê¼ÇÓÃÓÚ´æ·ÅÓÉÓû§½ø³ÌÌá½»µÄ¸üÐÂÐÅÏ¢¡£
ËüÃǵijõʼ»¯ºÍÏú»Ù²Ù×÷ÓëÆäËû±ê¼ÇÒ»Ñù£¬Ö»ÊÇ´´½¨Ê¼þ£¬MAC_INTERNALIZE
£¬ÂÔÓв»Í¬£º
¸Ãº¯Êý½ÓÊÜÓû§Ìá½»µÄ±ê¼Ç£¬¸ºÔð½«Æäת»¯ÎªÄں˱íʾÐÎʽ¡£
mpo_associate_vnode_devfs
void mpo_associate_vnode_devfs
(struct mount *mp,
struct label *fslabel, struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
struct label *vlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
mp |
Devfs ¹ÒÔØµã | |
fslabel |
Devfs Îļþϵͳ±ê¼Ç (mp->mnt_fslabel ) |
|
de |
Devfs Ŀ¼Ïî | |
delabel |
Óë de Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
vp |
Óë de Ïà¹ØÁªµÄ vnode |
|
vlabel |
Óë vp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ý²ÎÊý de
´«ÈëµÄ devfs
Ŀ¼Ïî¼°Æä±ê¼ÇÐÅÏ¢£¬ÎªÒ»¸öнü´´½¨µÄ devfs vnode Ìî³ä±ê¼Ç£¨vlabel
£©¡£
mpo_associate_vnode_extattr
int mpo_associate_vnode_extattr
(struct mount *mp,
struct label *fslabel, struct vnode *vp, struct label *vlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
mp |
Îļþϵͳ¹ÒÔØµã | |
fslabel |
Îļþϵͳ±ê¼Ç | |
vp |
½«±»±ê¼ÇµÄ vnode | |
vlabel |
Óë vp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡´ÓÎļþϵͳÀ©Õ¹ÊôÐÔÖжÁÈ¡ vp
µÄ±ê¼Ç¡£³É¹¦£¬·µ»Ø
0¡£ ²»³É¹¦£¬ÔòÔÚ errno
Ö¸¶¨µÄÏàÓ¦µÄ´íÎó±àÂë¡£ Èç¹ûÎļþϵͳ²»Ö§³ÖÀ©Õ¹ÊôÐԵĶÁÈ¡²Ù×÷£¬Ôò¿ÉÒÔ¿¼Âǽ« fslabel
¿½±´ÖÁ vlabel
¡£
mpo_associate_vnode_singlelabel
void mpo_associate_vnode_singlelabel
(struct mount
*mp, struct label *fslabel, struct vnode *vp, struct label *vlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
mp |
Îļþϵͳ¹ÒÔØµã | |
fslabel |
Îļþϵͳ±ê¼Ç | |
vp |
½«±»±ê¼ÇµÄ vnode | |
vlabel |
Óë vp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÔڷǶàÖØ±ê¼ÇÎļþϵͳÉÏ£¬Ê¹ÓøÃÈë¿Úº¯Êý£¬¸ù¾ÝÎļþϵͳ±ê¼Ç£¬fslabel
£¬ Ϊ vp
ÉèÖòßÂÔ±ê¼Ç¡£
mpo_create_devfs_device
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
dev |
devfs_dirent ¶ÔÓ¦µÄÉ豸 |
|
devfs_dirent |
½«±»±ê¼ÇµÄ Devfs Ŀ¼Ïî | |
label |
½«±»ÌîдµÄ devfs_dirent ±ê¼Ç |
¡¡¡¡Îª´«ÈëÉ豸н¨µÄ devfs_dirent Ìîд±ê¼Ç¡£¸Ãº¯Êý½«ÔÚÉ豸Îļþϵͳ¼ÓÔØ¡¢Öع¹»òÌí¼ÓÐÂÉ豸ʱ±»µ÷Óá£
mpo_create_devfs_directory
void mpo_create_devfs_directory
(char *dirname, int
dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
dirname |
н¨Ä¿Â¼µÄÃû×Ö | |
namelen |
×Ö·û´® dirname µÄ³¤¶È |
|
devfs_dirent |
н¨Ä¿Â¼ÔÚ Devfs ÖжÔÓ¦µÄĿ¼Ïî |
¡¡¡¡Îª´«ÈëĿ¼²ÎÊýµÄн¨ devfs_dirent Ìîд±ê¼Ç¡£¸Ãº¯Êý½«ÔÚ¼ÓÔØ¡¢Öع¹É豸Îļþϵͳ£¬»òÕßÌí¼ÓÒ»¸öÐèÒªÖ¸¶¨Ä¿Â¼½á¹¹µÄÐÂÉ豸ʱ±»µ÷Óá£
mpo_create_devfs_symlink
void mpo_create_devfs_symlink
(struct ucred *cred,
struct mount *mp, struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent
*de, struct label *delabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
mp |
devfs ¹ÒÔØµã | |
dd |
Á´½ÓÄ¿±ê | |
ddlabel |
Óë dd Ïà¹ØÁªµÄ±ê¼Ç |
|
de |
·ûºÅÁ´½ÓÏî | |
delabel |
Óë de Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÎªÐ½ü´´½¨µÄ
devfs(5)
·ûºÅÁ´½ÓÏîÌîд±ê¼Ç£¨delabel
£©¡£
mpo_create_vnode_extattr
int mpo_create_vnode_extattr
(struct ucred *cred,
struct mount *mp, struct label *fslabel, struct vnode *dvp, struct label *dlabel, struct
vnode *vp, struct label *vlabel, struct componentname *cnp);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
mount |
Îļþϵͳ¹ÒÔØµã | |
label |
Îļþϵͳ±ê¼Ç | |
dvp |
¸¸Ä¿Â¼ vnode | |
dlabel |
Óë dvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
vp |
д´½¨µÄ vnode | |
vlabel |
Óë vp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
cnp |
vp ÖеÄ×ÓÓòÃû×Ö |
¡¡¡¡½« vp
µÄ±ê¼ÇдÈëÎļþÀ©Õ¹ÊôÐÔ¡£³É¹¦£¬½«±ê¼ÇÌîÈë
vlabel
£¬ ²¢·µ»Ø 0¡£·ñÔò£¬·µ»Ø¶ÔÓ¦µÄ´íÎó±àÂë¡£
mpo_create_mount
void mpo_create_mount
(struct ucred *cred, struct
mount *mp, struct label *mnt, struct label *fslabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
mp |
¿ÍÌ壻½«±»¹ÒÔØµÄÎļþϵͳ | |
mntlabel |
½«±»ÌîдµÄ mp µÄ²ßÂÔ±ê¼Ç |
|
fslabel |
½«±»¹ÒÔØµ½ mp µÄÎļþϵͳµÄ²ßÂÔ±ê¼Ç¡£ |
¡¡¡¡Îª´«ÈëµÄÖ÷ÌåÐÅÈÎ×´Ëù´´½¨µÄ¹ÒÔØµãÌîд±ê¼Ç¡£¸Ãº¯Êý½«ÔÚÎļþϵͳ¹ÒÔØÊ±±»µ÷Óá£
mpo_create_root_mount
void mpo_create_root_mount
(struct ucred *cred,
struct mount *mp, struct label *mntlabel, struct label *fslabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
¼û µÚ 6.7.3.1.8 ½Ú. |
¡¡¡¡Îª´«ÈëµÄÖ÷ÌåÐÅÈÎ×´Ëù´´½¨µÄ¹ÒÔØµãÌîд±ê¼Ç¡£¸Ãº¯Êý½«ÔÚ¹ÒÔØ¸ùÎļþϵͳʱ£¬mpo_create_mount; Ö®ºó±»µ÷Óá£
mpo_relabel_vnode
void mpo_relabel_vnode
(struct ucred *cred, struct
vnode *vp, struct label *vnodelabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
½«±»ÖØÐ±ê¼ÇµÄ vnode | |
vnodelabel |
vp ÏÖÓеIJßÂÔ±ê¼Ç |
|
newlabel |
½«È¡´úvnodelabel µÄУ¨¿ÉÄÜÖ»ÊDz¿·Ö£©±ê¼Ç |
¡¡¡¡¸ù¾Ý´«ÈëµÄбê¼ÇºÍÖ÷ÌåÐÅÈÎ×´£¬¸üвÎÊý vnode µÄ±ê¼Ç¡£
mpo_setlabel_vnode_extattr
int mpo_setlabel_vnode_extattr
(struct ucred *cred,
struct vnode *vp, struct label *vlabel, struct label *intlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
д³ö±ê¼ÇËù¶ÔÓ¦µÄ vnode | |
vlabel |
vp µÄ²ßÂÔ±ê¼Ç |
|
intlabel |
½«±»Ð´Èë´ÅÅ̵ıê¼Ç |
¡¡¡¡½«²ÎÊý intlabel
¸ø³öµÄ±ê¼ÇÐÅϢдÈëÖ¸¶¨ vnode
µÄÀ©Õ¹ÊôÐÔ¡£ ¸Ãº¯Êý±» vop_stdcreatevnode_ea
Ëùµ÷Óá£
mpo_update_devfsdirent
void mpo_update_devfsdirent
(struct devfs_dirent
*devfs_dirent, struct label *direntlabel, struct vnode *vp, struct label
*vnodelabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
devfs_dirent |
¿ÍÌ壻devfs Ŀ¼Ïî | |
direntlabel |
½«±»¸üеÄdevfs_dirent µÄ²ßÂÔ±ê¼Ç |
|
vp |
¸¸ vnode | ÒÑËø¶¨ |
vnodelabel |
vp µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾ÝËù´«ÈëµÄ devfs vnode ±ê¼Ç£¬¶Ô devfs_dirent
µÄ±ê¼Ç½øÐиüС£ ÖØÐ±ê¼ÇÒ»¸ö devfs vnode
µÄ²Ù×÷³É¹¦Ö®ºó£¬½«µ÷Óøú¯ÊýÀ´È·Èϱê¼ÇµÄ¸Ä±ä£¬Èç´Ë£¬¼´Ê¹ÏàÓ¦µÄ vnode
Êý¾Ý½á¹¹±»Äں˻ØÊÕÖØÓ㬠Ҳ²»»á¶ªÊ§±ê¼ÇµÄÐÂ״̬¡£ÁíÍ⣬ÔÚ devfs
ÖÐн¨Ò»¸ö·ûºÅÁ´½Óʱ£¬½ô½Ó×Åmac_vnode_create_from_vnode
£¬
Ò²½«µ÷Óøú¯Êý£¬¶Ô vnode ±ê¼Ç½øÐгõʼ»¯²Ù×÷¡£
mpo_create_mbuf_from_socket
void mpo_create_mbuf_from_socket
(struct socket *so,
struct label *socketlabel, struct mbuf *m, struct label *mbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
socket |
Ì×½Ó×Ö | Ì×½Ó×ÖËø¶¨ WIP |
socketlabel |
socket µÄ²ßÂÔ±ê¼Ç |
|
m |
¿ÍÌ壻mbuf | |
mbuflabel |
½«±»ÌîдµÄ m µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ý´«ÈëµÄÌ×½Ó×Ö±ê¼ÇΪд´½¨µÄmbufÍ·²¿ÉèÖñê¼Ç¡£ ÿµ±Ì×½Ó×Ö²úÉúÒ»¸öеÄÊý¾Ý±¨»òÕßÏûÏ¢£¬²¢½«Æä´æ´¢ÔÚ²ÎÊý mbuf ÖÐʱ£¬½«µ÷Óøú¯Êý¡£
mpo_create_pipe
¡¡¡¡¸ù¾Ý´«ÈëµÄÖ÷ÌåÐÅÈÎ×´²ÎÊý£¬ÉèÖÃн¨¹ÜµÀµÄ±ê¼Ç¡£Ã¿µ±Ò»¸öйܵÀ±»´´½¨£¬¸Ãº¯Êý½«±»µ÷Óá£
mpo_create_socket
¡¡¡¡¸ù¾Ý´«ÈëµÄÖ÷ÌåÐÅÈÎ×´²ÎÊý£¬ÉèÖÃн¨Ì×½Ó×ֵıê¼Ç¡£Ã¿µ±Ð½¨Ò»¸öÌ×½Ó×Ö£¬¸Ãº¯Êý½«±»µ÷Óá£
mpo_create_socket_from_socket
void mpo_create_socket_from_socket
(struct socket
*oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label
*newsocketlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
oldsocket |
¼àÌýÌ×½Ó×Ö | |
oldsocketlabel |
oldsocket µÄ²ßÂÔ±ê¼Ç |
|
newsocket |
н¨Ì×½Ó×Ö | |
newsocketlabel |
newsocket µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ý listen(2) Ì×½Ó×Ö
oldsocket
£¬ Ϊн¨ accept(2) µÄÌ×½Ó×Ö
newsocket
£¬ÉèÖñê¼Ç¡£
mpo_relabel_pipe
void mpo_relabel_pipe
(struct ucred *cred, struct
pipe *pipe, struct label *oldlabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
pipe |
¹ÜµÀ | |
oldlabel |
pipe µÄµ±Ç°²ßÂÔ±ê¼Ç |
|
newlabel |
½«Îªpipe ÉèÖõÄеIJßÂÔ±ê¼Ç |
¡¡¡¡Îªpipe
ÉèÖÃбê¼Çnewlabel
¡£
mpo_relabel_socket
void mpo_relabel_socket
(struct ucred *cred, struct
socket *so, struct label *oldlabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | ²»¿É¸Ä±ä |
so |
¿ÍÌ壻Ì×½Ó×Ö | |
oldlabel |
so µÄµ±Ç°±ê¼Ç |
|
newlabel |
½«Îªsocket ÉèÖõÄбê¼Ç |
¡¡¡¡¸ù¾Ý´«ÈëµÄ±ê¼Ç²ÎÊý£¬¶ÔÌ×½Ó×ֵĵ±Ç°±ê¼Ç½øÐиüС£
mpo_set_socket_peer_from_mbuf
void mpo_set_socket_peer_from_mbuf
(struct mbuf
*mbuf, struct label *mbuflabel, struct label *oldlabel, struct label
*newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
mbuf |
´ÓÌ×½Ó×Ö½ÓÊÕµ½µÄµÚÒ»¸öÊý¾Ý±¨ | |
mbuflabel |
mbuf µÄ±ê¼Ç |
|
oldlabel |
Ì×½Ó×ֵĵ±Ç°±ê¼Ç | |
newlabel |
½«ÎªÌ×½Ó×ÖÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ý´«ÈëµÄ mbuf ±ê¼Ç£¬ÉèÖÃij¸ö stream Ì×½Ó×ֵĶԵȱêÖ¾¡£ ³ýUnixÓòµÄÌ×½Ó×ÖÖ®Í⣬ÿµ±Ò»¸ö stream Ì×½Ó×Ö½ÓÊÕµ½µÚÒ»¸öÊý¾Ý±¨Ê±£¬¸Ãº¯Êý½«±»µ÷Óá£
mpo_set_socket_peer_from_socket
void mpo_set_socket_peer_from_socket
(struct socket
*oldsocket, struct label *oldsocketlabel, struct socket *newsocket, struct label
*newsocketpeerlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
oldsocket |
±¾µØÌ×½Ó×Ö | |
oldsocketlabel |
oldsocket µÄ²ßÂÔ±ê¼Ç |
|
newsocket |
¶ÔµÈÌ×½Ó×Ö | |
newsocketpeerlabel |
½«Îªnewsocket ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ý´«ÈëµÄÔ¶³ÌÌ×½Ó×ֶ˵㣬Ϊһ¸ö stream UNIX ÓëÌ×½Ó×ÖÉèÖöԵȱê¼Ç¡£ ÿµ±ÏàÓ¦µÄÌ×½Ó×Ö¶ÔÖ®¼ä½øÐÐÁ¬½Óʱ£¬¸Ãº¯Êý½«ÔÚÁ½¶Ë·Ö±ð±»µ÷Óá£
mpo_create_bpfdesc
¡¡¡¡¸ù¾Ý´«ÈëµÄÖ÷ÌåÐÅÈÎ×´²ÎÊý£¬ÎªÐ½¨µÄ BPF ÃèÊö×ÓÉèÖñê¼Ç¡£ µ±½ø³Ì´ò¿ª BPF É豸½Úµãʱ£¬¸Ãº¯Êý½«±»µ÷Óá£
mpo_create_ifnet
¡¡¡¡ÎªÐ½¨µÄÍøÂç½Ó¿ÚÉèÖñê¼Ç¡£¸Ãº¯ÊýÔÚÒÔÏÂÇé¿öϱ»µ÷Ó㺠µ±Ò»¸öеÄÎïÀí½Ó¿Ú±äΪ¿ÉÓÃʱ£¬»òÕßµ±Ò»¸öα½Ó¿ÚÔÚÒýµ¼Ê±»òÓÉÓÚij¸öÓû§²Ù×÷¶øÊµÀý»¯Ê±¡£
mpo_create_ipq
void mpo_create_ipq
(struct mbuf *fragment, struct
label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
fragment |
µÚÒ»¸ö±»½ÓÊÕµÄ IP ·ÖƬ | |
fragmentlabel |
fragment µÄ²ßÂÔ±ê¼Ç |
|
ipq |
½«±»±ê¼ÇµÄ IP ÖØ×é¶ÓÁÐ | |
ipqlabel |
½«Îªipq ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾ÝµÚÒ»¸ö½ÓÊÕµ½µÄ·ÖƬµÄ mbuf Í·²¿ÐÅÏ¢£¬ÎªÐ½¨µÄ IP ·ÖÆ¬ÖØ×é¶ÓÁÐÉèÖñê¼Ç¡£
mpo_create_datagram_from_ipq
void mpo_create_create_datagram_from_ipq
(struct ipq
*ipq, struct label *ipqlabel, struct mbuf *datagram, struct label
*datagramlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
ipq |
IP ÖØ×é¶ÓÁÐ | |
ipqlabel |
ipq µÄ²ßÂÔ±ê¼Ç |
|
datagram |
½«±»±ê¼ÇµÄÊý¾Ý±¨ | |
datagramlabel |
½«Îªdatagramlabel ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ý IP ·ÖÆ¬ÖØ×é¶ÓÁУ¬Îª¸Õ¸ÕÖØ×éÍê±ÏµÄ IP Êý¾Ý±¨ÉèÖñê¼Ç¡£
mpo_create_fragment
void mpo_create_fragment
(struct mbuf *datagram,
struct label *datagramlabel, struct mbuf *fragment, struct label
*fragmentlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
datagram |
Êý¾Ý±¨ | |
datagramlabel |
datagram µÄ²ßÂÔ±ê¼Ç |
|
fragment |
½«±»±ê¼ÇµÄ·ÖƬ | |
fragmentlabel |
½«Îªdatagram ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾ÝÊý¾Ý±¨Ëù¶ÔÓ¦µÄ mbuf Í·²¿ÐÅÏ¢£¬ÎªÆäн¨µÄ·ÖƬµÄ mbuf Í·²¿ÉèÖñê¼Ç¡£
mpo_create_mbuf_from_mbuf
void mpo_create_mbuf_from_mbuf
(struct mbuf
*oldmbuf, struct label *oldmbuflabel, struct mbuf *newmbuf, struct label
*newmbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
oldmbuf |
ÒÑÓеģ¨Ô´£©mbuf | |
oldmbuflabel |
oldmbuf µÄ²ßÂÔ±ê¼Ç |
|
newmbuf |
½«±»±ê¼ÇµÄн¨ mbuf | |
newmbuflabel |
½«Îªnewmbuf ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾Ýij¸öÏÖÓÐÊý¾Ý±¨µÄ mbuf Í·²¿ÐÅÏ¢£¬ÎªÐ½¨Êý¾Ý±¨µÄ mbuf Í·²¿ÉèÖñê¼Ç¡£ÔÚÐí¶àÌõ¼þϽ«»áµ÷Óøú¯Êý£¬ ±ÈÈ磬ÓÉÓÚ¶ÔÆëÒªÇó¶øÖØÐ·ÖÅäij¸ö mbuf ʱ¡£
mpo_create_mbuf_linklayer
void mpo_create_mbuf_linklayer
(struct ifnet *ifnet,
struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
ifnet |
ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet µÄ²ßÂÔ±ê¼Ç |
|
mbuf |
н¨Êý¾Ý±¨µÄ mbuf Í·²¿ | |
mbuflabel |
½«Îªmbuf ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÎªÔÚ¸ø¶¨½Ó¿ÚÉÏÓÉÓÚij¸öÁ´Â·²ãÏìÓ¦¶øÐ½¨µÄÊý¾Ý±¨µÄmbufÍ·²¿ÉèÖñê¼Ç¡£ ¸Ãº¯Êý½«ÔÚÈô¸ÉÌõ¼þϱ»µ÷Ó㬱ÈÈçµ±IPv4ºÍIPv6ÐÒéÕ»ÔÚÏìÓ¦ARP»òÕßND6ʱ¡£
mpo_create_mbuf_from_bpfdesc
void mpo_create_mbuf_from_bpfdesc
(struct bpf_d
*bpf_d, struct label *bpflabel, struct mbuf *mbuf, struct label *mbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
bpf_d |
BPF ÃèÊö×Ó | |
bpflabel |
bpflabel µÄ²ßÂÔ±ê¼Ç |
|
mbuf |
½«±»±ê¼ÇµÄн¨ mbuf | |
mbuflabel |
½«Îªmbuf ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÎªÊ¹ÓòÎÊý BPF ÃèÊö×Ó´´½¨µÄÐÂÊý¾Ý±¨µÄ mbuf Í·²¿ÉèÖñê¼Ç¡£ µ±¶Ô²ÎÊý BPF ÃèÊö×ÓËù¹ØÁªµÄ BPF É豸½øÐÐд²Ù×÷ʱ£¬¸Ãº¯Êý½«±»µ÷Óá£
mpo_create_mbuf_from_ifnet
void mpo_create_mbuf_from_ifnet
(struct ifnet
*ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
ifnet |
ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnetlabel µÄ²ßÂÔ±ê¼Ç |
|
mbuf |
н¨Êý¾Ý±¨µÄ mbuf Í·²¿ | |
mbuflabel |
½«Îªmbuf ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡Îª´ÓÍøÂç½Ó¿Ú²ÎÊý´´½¨µÄÊý¾Ý±¨µÄ mbuf Í·²¿ÉèÖñê¼Ç¡£
mpo_create_mbuf_multicast_encap
void mpo_create_mbuf_multicast_encap
(struct mbuf
*oldmbuf, struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
struct mbuf *newmbuf, struct label *newmbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
oldmbuf |
ÏÖÓÐÊý¾Ý±¨µÄ mbuf Í·²¿ | |
oldmbuflabel |
oldmbuf µÄ²ßÂÔ±ê¼Ç |
|
ifnet |
ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet µÄ²ßÂÔ±ê¼Ç |
|
newmbuf |
½«±»±ê¼ÇµÄн¨Êý¾Ý±¨ mbuf Í·²¿ | |
newmbuflabel |
½«Îªnewmbuf ÌîдµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡µ±´«ÈëµÄÒÑÓÐÊý¾Ý±¨±»¸ø¶¨¶à²¥·â×°½Ó¿Ú£¨multicast encapsulation interface£©´¦Àíʱ±»µ÷Ó㬠Ϊд´½¨µÄÊý¾Ý±¨ËùÔÚ mbuf Í·²¿ÉèÖñê¼Ç¡£ ÿµ±Ê¹ÓøÃÐéÄâ½Ó¿Ú´«µÝÒ»¸ömbufʱ£¬½«µ÷Óøú¯Êý¡£
mpo_create_mbuf_netlayer
void mpo_create_mbuf_netlayer
(struct mbuf *oldmbuf,
struct label *oldmbuflabel, struct mbuf *newmbuf, struct label *newmbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
oldmbuf |
½ÓÊÕµÄÊý¾Ý±¨ | |
oldmbuflabel |
oldmbuf µÄ²ßÂÔ±ê¼Ç |
|
newmbuf |
н¨Êý¾Ý±¨ | |
newmbuflabel |
newmbuf µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÎªÓÉ IP ¶ÑÕ»ÒòΪÏìÓ¦½ÓÊÕÊý¾Ý±¨£¨oldmbuf
£©¶øÐ½¨µÄÊý¾Ý±¨ÉèÖÃÆä mbuf Í·²¿µÄ±ê¼Ç¡£
Ðí¶àÇé¿öÏÂÐèÒªµ÷Óøú¯Êý£¬±ÈÈ磬ÏìÓ¦ ICMP ÇëÇóÊý¾Ý±¨Ê±¡£
mpo_fragment_match
int mpo_fragment_match
(struct mbuf *fragment,
struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
fragment |
IP Êý¾Ý±¨·ÖƬ | |
fragmentlabel |
fragment µÄ²ßÂÔ±ê¼Ç |
|
ipq |
IP ·ÖÆ¬ÖØ×é¶ÓÁÐ | |
ipqlabel |
ipq µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾ÝËù´«ÈëµÄ IP ·ÖÆ¬ÖØ×é¶ÓÁУ¨ipq
£©µÄ±ê¼Ç£¬
¼ì²é°üº¬Ò»¸ö IP Êý¾Ý±¨£¨fragment
£©µÄ mbuf
µÄÍ·²¿ÊÇ·ñ·ûºÏÆäÒªÇó¡£ ·ûºÏ£¬Ôò·µ»Ø1¡£·ñÔò£¬·µ»Ø0¡£ ÿµ± IP
¶ÑÕ»³¢ÊÔ½«Ò»¸ö¸Õ¸Õ½ÓÊÕµ½µÄ·ÖƬ·ÅÈëij¸öÒÑÓÐµÄ·ÖÆ¬ÖØ×é¶ÓÁÐÖÐʱ£¬½«µ÷Óøú¯Êý½øÐа²È«¼ì²é£»
Èç¹ûʧ°Ü£¬½«Îª·ÖÆ¬ÖØÐÂʵÀý»¯Ò»¸öÐ嵀ᅮ¬ÖØ×é¶ÓÁС£
²ßÂÔ¿ÉÒÔÀûÓøÃÈë¿Úº¯Êý£¬¸ù¾Ý±ê¼Ç»òÕ߯äËûÐÅÏ¢×èÖ¹²»ÆÚÍûµÄ IP ·ÖÆ¬ÖØ×é¡£
mpo_relabel_ifnet
void mpo_relabel_ifnet
(struct ucred *cred, struct
ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
ifnet |
¿ÍÌå£»ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet µÄ²ßÂÔ±ê¼Ç |
|
newlabel |
½«Îªifnet ÉèÖõÄбê¼Ç |
¡¡¡¡¸ù¾ÝËù´«ÈëµÄбê¼Ç£¬newlabel
£¬ÒÔ¼°Ö÷ÌåÐÅÈÎ×´£¬
cred
£¬¶ÔÍøÂç½Ó¿ÚµÄ±ê¼Ç½øÐиüС£
mpo_update_ipq
void mpo_update_ipq
(struct mbuf *fragment, struct
label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
mbuf |
IP ·ÖƬ | |
mbuflabel |
mbuf µÄ²ßÂÔ±ê¼Ç |
|
ipq |
IP ·ÖÆ¬ÖØ×é¶ÓÁÐ | |
ipqlabel |
½«±»¸üеÄipq µÄµ±Ç°²ßÂÔ±ê¼Ç |
¡¡¡¡¸ù¾ÝËù´«ÈëµÄ IP ·ÖƬ mbuf Í·²¿£¨mbuf
£©Îª½ÓÊÕ ËüµÄ
IP ·ÖÆ¬ÖØ×é¶ÓÁУ¨ipq
£©µÄ±ê¼Ç½øÐиüС£
mpo_create_cred
¡¡¡¡¸ù¾ÝËù´«ÈëµÄÖ÷ÌåÐÅÈÎ×´£¬ÎªÐ½¨µÄÖ÷ÌåÐÅÈÎ×´ÉèÖñê¼Ç¡£ ÿµ±ÎªÒ»¸öн¨µÄ struct ucredµ÷Óà crcopy(9) ʱ£¬½«µ÷Óô˺¯Êý¡£ ¸Ãº¯Êý²»Ó¦Óë½ø³Ì¸´ÖÆ£¨forking£©»òÕß´´½¨Ê¼þ»ìΪһ̸¡£
mpo_execve_transition
void mpo_execve_transition
(struct ucred *old,
struct ucred *new, struct vnode *vp, struct label *vnodelabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
old |
ÒÑÓеÄÖ÷ÌåÐÅÈÎ×´ | ²»¿É¸Ä±ä |
new |
½«±»±ê¼ÇµÄÐÂÖ÷ÌåÐÅÈÎ×´ | |
vp |
½«±»Ö´ÐеÄÎļþ | Òѱ»Ëø¶¨ |
vnodelabel |
vp µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡Ò»¸öÓµÓÐÐÅÈÎ×´old
µÄÖ÷ÌåÓÉÓÚÖ´ÐÐ(vp
Îļþ¶øµ¼Ö±ê¼Çת»»Ê±£¬
¸Ãº¯Êý¸ù¾Ývnode±ê¼ÇΪ¸ÃÖ÷ÌåÖØÐ±ê¼ÇΪnew
¡£
ÿµ±Ò»¸ö½ø³ÌÇëÇóÖ´ÐÐvnodeÎļþ£¬¶øÍ¨¹ý Èë¿Úº¯Êýmpo_execve_will_transition
Óгɹ¦·µ»ØµÄ²ßÂÔʱ£¬½«µ÷Óøú¯Êý¡£
²ßÂÔÄ£¿é¿ÉÒÔͨ¹ý´«ÈëÁ½¸öÖ÷ÌåÐÅÈÎ×´ºÍ¼òµ¥µØµ÷Óà mpo_create_cred
À´ÊµÏÖ¸ÃÈë¿Úº¯Êý£¬ so as not to implement a
transitioning event. Ò»µ©²ßÂÔʵÏÖÁËmpo_create_cred
º¯Êý£¬¼´Ê¹Ã»ÓÐʵÏÖ mpo_execve_will_transition
£¬Ò²Ó¦¸ÃʵÏָú¯Êý¡£
mpo_execve_will_transition
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
old |
ÔÚÖ´ÐÐexecve(2)֮ǰµÄÖ÷ÌåÐÅÈÎ×´ | ²»¿É¸Ä±ä |
vp |
½«±»Ö´ÐеÄÎļþ | |
vnodelabel |
vp µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡ÓɲßÂÔ¾ö¶¨£¬µ±²ÎÊýÖ÷ÌåÐÅÈÎ×´Ö´ÐвÎÊý vnode
ʱ£¬ÊÇ·ñÐèÒª½øÐÐÒ»¸ö±ê¼Çת»»²Ù×÷¡£Èç¹ûÐèÒª£¬·µ»Ø1£»
·ñÔò£¬·µ»Ø0¡£¼´Ê¹Ò»¸ö²ßÂÔ·µ»Ø0£¬ËüÒ²±ØÐëΪ×Ô¼º²»ÆÚÍûµÄ¶Ô mpo_execve_transition
µÄµ÷ÓÃ×÷ºÃ×¼±¸£¬ÒòΪֻҪÓÐÆäËûÈκÎÒ»¸ö²ßÂÔÒªÇóת»»£¬¾Í½«Ö´Ðд˺¯Êý¡£
¡¡¡¡Í¨¹ý·ÃÎÊ¿ØÖÆÈë¿Úº¯Êý£¬²ßÂÔÄ£¿éÄÜÓ°ÏìÄں˵ķÃÎÊ¿ØÖƾö²ß¡£
ͨ³£Çé¿öÏ£¬²»ÊǾø¶Ô£¬Ò»¸ö·ÃÎÊ¿ØÖÆÈë¿Úº¯ÊýµÄ²ÎÊýÓУ¬Ò»¸ö»òÕßÈô¸É¸öÊÚȨÐÅÈÎ×´£¬ºÍÏà¹Ø²Ù×÷Éæ¼°µÄÆäËûÈκζÔÏóµÄÐÅÏ¢£¨ÆäÖпÉÄܰüº¬±ê¼Ç£©¡£
·ÃÎÊ¿ØÖÆÈë¿Úº¯Êý·µ»Ø0£¬±íʾÔÊÐí¸Ã²Ù×÷£»·ñÔò£¬·µ»ØÒ»¸ö errno(2)
´íÎó±àÂë¡£µ÷ÓøÃÈë¿Úº¯Êý£¬½«±éÀúËùÓÐϵͳע²áµÄ²ßÂÔÄ£¿é£¬ÖðÒ»½øÐÐ
²ßÂÔÏà¹ØµÄ¼ì²éºÍ¾ö²ß£¬Ö®ºó°´ÕÕÏÂÊö·½·¨×éºÏ²»Í¬²ßÂԵķµ»Ø½á¹û£ºÖ»Óе±ËùÓеÄÄ£¿é¾ùÔÊÐí¸Ã²Ù×÷ʱ£¬²Å³É¹¦·µ»Ø¡£
·ñÔò£¬Èç¹ûÓÐÒ»¸ö»òÕßÈô¸ÉÄ£¿éʧ°Ü·µ»Ø£¬ÔòÕû¸ö¼ì²é²»Í¨¹ý¡£Èç¹ûÓжà¸öÄ£¿éµÄ¼ì²é³ö´í·µ»Ø£¬½«Óɶ¨ÒåÔÚkern_mac.c
ÖÐµÄ error_select()
º¯Êý´ÓËüÃÇ·µ»ØµÄ´íÎó±àÂëÖУ¬Ñ¡ÔñÒ»¸öºÏÊʵ쬷µ»Ø¸øÓû§¡£
¡¡¡¡Èç¹ûËùÓвßÂÔÄ£¿é·µ»ØµÄ´íÎó±àÂë¾ùûÓгöÏÖÔÚÉÏÊöÓÅÏȼ¶ÐòÁбíÖУ¬ÔòÈÎÒâÑ¡ÔñÒ»¸ö·µ»Ø¡£ Ñ¡Ôñ´íÎó±àÂëµÄÒ»°ã´ÎÐòΪ£ºÄں˴íÎó£¬ÎÞЧµÄ²ÎÊý£¬¶ÔÏó²»´æÔÚ£¬·ÃÎʱ»¾Ü¾ø£¬ºÍÆäËû´íÎó¡£
mpo_check_bpfdesc_receive
int mpo_check_bpfdesc_receive
(struct bpf_d *bpf_d,
struct label *bpflabel, struct ifnet *ifnet, struct label *ifnetlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
bpf_d |
Ö÷Ì壻BPF ÃèÊö×Ó | |
bpflabel |
bpf_d µÄ²ßÂÔ±ê¼Ç |
|
ifnet |
¿ÍÌå£»ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡¾ö¶¨ MAC ¿ò¼ÜÊÇ·ñÓ¦¸ÃÔÊÐí½«ÓɲÎÊý½Ó¿Ú½ÓÊÕµ½µÄÊý¾Ý±¨´«µÝ¸øÓÉ BPF
ÃèÊö×ÓËù¶ÔÓ¦µÄ»º³åÇø¡£³É¹¦£¬Ôò·µ»Ø0£»
·ñÔò£¬·µ»Ø´íÎó±àÂëÐÅÏ¢errno
¡£½¨ÒéʹÓõĴíÎó±àÂëÓУºEACCES£¬ÓÃÓÚ±ê¼Ç²»·ûµÄÇé¿ö£» EPERM£¬ÓÃÓÚȱÉÙÌØÈ¨µÄÇé¿ö¡£
mpo_check_pipe_ioctl
int mpo_check_pipe_ioctl
(struct ucred *cred, struct
pipe *pipe, struct label *pipelabel, unsigned long cmd, void *data);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
pipe |
¹ÜµÀ | |
pipelabel |
pipe µÄ²ßÂÔ±ê¼Ç |
|
cmd |
ioctl(2) ÃüÁî | |
data |
ioctl(2) Êý¾Ý |
¡¡¡¡¾ö¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨµ÷ÓÃÖ¸¶¨µÄ ioctl(2) ϵͳµ÷Óá£
mpo_check_pipe_relabel
int mpo_check_pipe_relabel
(struct ucred *cred,
struct pipe *pipe, struct label *pipelabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
pipe |
¹ÜµÀ | |
pipelabel |
pipe µÄµ±Ç°²ßÂÔ±ê¼Ç |
|
newlabel |
½«Îªpipelabel ÉèÖõÄбê¼Ç |
¡¡¡¡¾ö¶¨¸ÃÖ÷ÌåÊÇ·ñÓÐȨΪpipe
ÖØÐÂÉèÖñê¼Ç¡£
mpo_check_socket_bind
mpo_check_socket_connect
int mpo_check_socket_connect
(struct ucred *cred,
struct socket *socket, struct label *socketlabel, struct sockaddr *sockaddr);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
socket |
½«±»Á¬½ÓµÄÌ×½Ó×Ö | |
socketlabel |
socket µÄ²ßÂÔ±ê¼Ç |
|
sockaddr |
socket µÄµØÖ· |
¡¡¡¡¾ö¶¨¸ÃÖ÷Ì壨cred
£©ÊÇ·ñÓÐȨ½«Ì×½Ó×Ö£¨socket
£©°ó¶¨µ½µØÖ· sockaddr
¡£³É¹¦£¬·µ»Ø0£¬·ñÔò·µ»ØÒ»¸ö´íÎó±àÂëerrno
¡£
½¨Òé²ÉÓõĴíÎó±àÂëÓУºEACCES£¬ÓÃÓÚ±ê¼Ç²»·ûµÄÇé¿ö£»EPERM£¬ÓÃÓÚÌØÈ¨²»×ãµÄÇé¿ö¡£
mpo_check_cred_visible
¡¡¡¡È·¶¨¸ÃÖ÷ÌåÐÅÈÎ×´u1
ÊÇ·ñÓÐȨ ¡°see¡±
¾ßÓÐÐÅÈÎ×´u2
µÄÆäËûÖ÷Ìå¡£ ³É¹¦£¬·µ»Ø0£»·ñÔò£¬·µ»Ø´íÎó±àÂëerrno
¡£½¨Òé²ÉÓõĴíÎó±àÂëÓУº EACCES£¬ÓÃÓÚ±ê¼Ç²»·ûµÄÇé¿ö£»EPERM£¬ÓÃÓÚÌØÈ¨²»×ãµÄÇé¿ö£»ESRCH£¬
ÓÃÀ´Ìṩ²»¿É¼ûÐÔ¡£¸Ãº¯Êý¿ÉÔÚÐí¶à»·¾³ÏÂʹÓ㬰üÀ¨ÃüÁîpsËùʹÓõĽø³Ì¼äµÄ״̬ sysctl£¬ÒÔ¼°Í¨¹ýprocfs µÄ״̬²éѯ²Ù×÷¡£
mpo_check_ifnet_relabel
int mpo_check_ifnet_relabel
(struct ucred *cred,
struct ifnet *ifnet, struct label *ifnetlabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
ifnet |
¿ÍÌå£»ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet ÏÖÓеIJßÂÔ±ê¼Ç |
|
newlabel |
½«±»Ó¦Óõ½ifnet ÉϵÄеIJßÂÔ±ê¼Ç |
¡¡¡¡¾ö¶¨¸ÃÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨʹÓô«ÈëµÄ±ê¼Ç¸üвÎÊý¶Ô¸ø¶¨µÄÍøÂç½Ó¿ÚµÄ±ê¼Ç½øÐÐÖØÐÂÉèÖá£
mpo_check_socket_relabel
int mpo_check_socket_relabel
(struct ucred *cred,
struct socket *socket, struct label *socketlabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
socket |
¿ÍÌ壻Ì×½Ó×Ö | |
socketlabel |
socket ÏÖÓеIJßÂÔ±ê¼Ç |
|
newlabel |
½«±»Ó¦Óõ½socketlabel Éϵĸüбê¼Ç |
¡¡¡¡¾ö¶¨¸ÃÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ²ÉÓô«ÈëµÄ±ê¼Ç¶ÔÌ×½Ó×Ö²ÎÊýµÄ±ê¼Ç½øÐÐÖØÐÂÉèÖá£
mpo_check_vnode_relabel
int mpo_check_vnode_relabel
(struct ucred *cred,
struct vnode *vp, struct label *vnodelabel, struct label *newlabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | ²»¿É¸Ä±ä |
vp |
¿ÍÌ壻vnode | Òѱ»Ëø¶¨ |
vnodelabel |
vp ÏÖÓеIJßÂÔ±ê¼Ç |
|
newlabel |
½«±»Ó¦Óõ½vp ÉϵIJßÂÔ±ê¼Ç |
¡¡¡¡¾ö¶¨¸ÃÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ½«²ÎÊý vnode µÄ±ê¼ÇÖØÐÂÉèÖÃΪָ¶¨±ê¼Ç¡£
mpo_check_mount_stat
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ²é¿´ÔÚ¸ø¶¨ÎļþϵͳÉÏÖ´ÐÐ statfs µÄ½á¹û¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£ ¸Ãº¯Êý¿ÉÄÜÔÚÏÂÁÐÇé¿öϱ»µ÷Ó㺠ÔÚ statfs(2)
ºÍÆäËûÏà¹Øµ÷ÓÃÆÚ¼ä£¬»òÕßµ±ÐèÒª´ÓÎļþϵͳÁбíÖÐÑ¡ÔñÅųýÄĸöÎļþϵͳʱ£¬±ÈÈ磬 µ÷ÓÃ
getfsstat(2)ʱ¡£
mpo_check_proc_debug
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ debug ¸ø¶¨½ø³Ì¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»£» ESRCH£¬ÓÃÓÚÒþÂ÷Ä¿±êµÄ´æÔÚ¡£ ptrace(2) ºÍ ktrace(2) API£¬ÒÔ¼°Ä³Ð©
procfs ²Ù×÷½«µ÷Óøú¯Êý¡£
mpo_check_vnode_access
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
flags |
access(2) ±êÖ¾ |
¡¡¡¡¸ù¾ÝÏà¹ØÖ÷ÌåÐÅÈÎ×´¾ö¶¨Æä¶Ô¸ø¶¨ vnode ÒÔ¸ø¶¨·ÃÎʱêÖ¾Ö´ÐÐµÄ access(2)
ºÍÆäËûÏà¹Øµ÷Óõķµ»ØÖµ¡£Ò»°ã£¬Ó¦²ÉÓÃÓëmpo_check_vnode_open
ÏàͬµÄÓïÒåÀ´ÊµÏָú¯Êý¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_chdir
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
dvp |
¿ÍÌ壻chdir(2) µÄÄ¿µÄ vnode | |
dlabel |
dvp µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ½«½ø³Ì¹¤×÷Ŀ¼Çл»µ½¸ø¶¨ vnode¡£³É¹¦£¬Ôò·µ»Ø
0£» ·ñÔò£¬·µ»ØÒ»¸ö errno
Öµ¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_create
int mpo_check_vnode_create
(struct ucred *cred,
struct vnode *dvp, struct label *dlabel, struct componentname *cnp, struct vattr
*vap);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
dvp |
¿ÍÌ壻vnode | |
dlabel |
dvp µÄ²ßÂÔ±ê¼Ç |
|
cnp |
dvp ÖеijÉÔ±Ãû |
|
vap |
vap µÄ vnode ÊôÐÔ |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÔÚ¸ø¶¨¸¸Ä¿Â¼£¬ÒÔ¸ø¶¨µÄÃû×ÖºÍÊôÐÔ£¬ ³£¼ûÒ»¸ö
vnode¡£³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬ ·µ»ØÒ»¸öerrno
Öµ¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES
À´±íʾÓÃÓÚ±ê¼Ç²»Æ¥Å䣬 ¶øÓà EPERM£¬ÓÃÓÚȨÏÞ²»×ã¡£
ÒÔO_CREAT
Ϊ²ÎÊýµ÷Óà open(2)£¬»ò¶Ô mknod(2)£¬mkfifo(2)
µÈµÄµ÷Óý«µ¼Ö¸ú¯Êý±»µ÷Óá£
mpo_check_vnode_delete
int mpo_check_vnode_delete
(struct ucred *cred,
struct vnode *dvp, struct label *dlabel, struct vnode *vp, void *label, struct
componentname *cnp);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
dvp |
¸¸Ä¿Â¼ vnode | |
dlabel |
dvp µÄ²ßÂÔ±ê¼Ç |
|
vp |
¿ÍÌ壻½«±»É¾³ýµÄ vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
cnp |
vp ÖеijÉÔ±Ãû |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ´Ó¸ø¶¨µÄ¸¸Ä¿Â¼ÖУ¬É¾³ý¸ø¶¨Ãû×ÖµÄ vnode¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£ ʹÓà unlink(2) ºÍ rmdir(2)£¬½«µ¼Ö¸ú¯Êý±»µ÷Óá£
Ìṩ¸ÃÈë¿Úº¯ÊýµÄ²ßÂÔ»¹±ØÐëʵÏÖÒ»¸ö mpo_check_rename_to
£¬
ÓÃÀ´ÊÚȨÓÉÓÚÖØÃüÃû²Ù×÷µ¼ÖµÄÄ¿±êÎļþµÄɾ³ý¡£
mpo_check_vnode_deleteacl
int mpo_check_vnode_deleteacl
(struct ucred *cred,
struct vnode *vp, struct label *label, acl_type_t type);
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨɾ³ý¸ø¶¨ vnode µÄ¸ø¶¨ÀàÐ굀 ACL¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_exec
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨִÐиø¶¨ vnode¡£
¶ÔÓÚÖ´ÐÐÌØÈ¨µÄ¾ö²ßÓëÈκÎ˲ʱʼþµÄ¾ö²ßÊÇÑϸñ·Ö¿ªµÄ¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_getacl
int mpo_check_vnode_getacl
(struct ucred *cred,
struct vnode *vp, struct label *label, acl_type_t type);
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ²éѯ¸ø¶¨ vnode Éϵĸø¶¨ÀàÐ굀 ACL¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_getextattr
int mpo_check_vnode_getextattr
(struct ucred *cred,
struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio
*uio);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
attrnamespace |
À©Õ¹ÊôÐÔÃû×Ö¿Õ¼ä | |
name |
À©Õ¹ÊôÐÔÃû | |
uio |
I/O ½á¹¹Ö¸Õ룻²Î¼û uio(9) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ²éѯ¸ø¶¨ vnode Éϸø¶¨Ãû×Ö¿Õ¼äºÍÃû×ÖµÄÀ©Õ¹ÊôÐÔ¡£
ʹÓÃÀ©Õ¹ÊôÐÔʵÏÖ±ê¼Ç´æ´¢µÄ²ßÂÔÄ£¿é¿ÉÄÜ»áÐèÒª¶ÔÕâЩÀ©Õ¹ÊôÐԵIJÙ×÷½øÐÐÌØÊâ´¦Àí¡£
³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_link
int mpo_check_vnode_link
(struct ucred *cred, struct
vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct
componentname *cnp);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
dvp |
Ŀ¼ vnode | |
dlabel |
Óëdvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
vp |
Á´½ÓÄ¿µÄ vnode | |
label |
Óëvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
cnp |
½«±»´´½¨µÄÁ´½Ó¶ÔÓ¦µÄ³ÉÔ±Ãû |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨΪ²ÎÊývp
¸ø¶¨µÄ vnode
´´½¨Ò»¸öÓɲÎÊýcnp
¸ø¶¨Ãû×ÖµÄÁ´½Ó¡£
mpo_check_vnode_mmap
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
½«±»Ó³ÉäµÄ vnode | |
label |
Óëvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
prot |
mmap ±£»¤ (²Î¼û mmap(2)) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨ½«¸ø¶¨ vnode vp
ÒÔ prot
Ö¸¶¨µÄ±£»¤·½Ê½½øÐÐÓ³Éä.
mpo_check_vnode_mmap_downgrade
void mpo_check_vnode_mmap_downgrade
(struct ucred
*cred, struct vnode *vp, struct label *label, int *prot);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
See µÚ 6.7.4.37 ½Ú. | |
vp |
||
label |
||
prot |
½«±»½µ¼¶µÄ mmap protections |
¡¡¡¡¸ù¾ÝÖ÷ÌåºÍ¿ÍÌå±ê¼Ç£¬½µµÍ mmap protections¡£
mpo_check_vnode_mprotect
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨ½«¸ø¶¨ vnodevp
Ó³ÉäÄÚ´æ¿Õ¼äµÄ´æ´¢±£»¤²ÎÊýÉèÖÃΪָ¶¨Öµ¡£
mpo_check_vnode_poll
int mpo_check_vnode_poll
(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp, struct label *label);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
active_cred |
Ö÷ÌåÐÅÈÎ×´ | |
file_cred |
Óëstruct fileÏà¹ØÁªµÄÐÅÈÎ×´ | |
vp |
½«±»Ö´ÐÐ poll ²Ù×÷µÄ vnode | |
label |
Óëvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨ¶Ô¸ø¶¨ vnode vp
Ö´ÐÐ poll
²Ù×÷¡£
mpo_check_vnode_rename_from
int mpo_vnode_rename_from
(struct ucred *cred,
struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, struct
componentname *cnp);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
dvp |
Ŀ¼ vnode | |
dlabel |
Óëdvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
vp |
½«±»ÖØÃüÃûµÄ vnode | |
label |
Óëvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
cnp |
vp ÖеijÉÔ±Ãû |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐÈ¨ÖØÃüÃû¸ø¶¨vnode£¬vp
¡£
mpo_check_vnode_rename_to
int mpo_check_vnode_rename_to
(struct ucred *cred,
struct vnode *dvp, struct label *dlabel, struct vnode *vp, struct label *label, int
samedir, struct componentname *cnp);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
dvp |
Ŀ¼ vnode | |
dlabel |
Óëdvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
vp |
±»¸²¸ÇµÄ vnode | |
label |
Óëvp Ïà¹ØÁªµÄ²ßÂÔ±ê¼Ç |
|
samedir |
²¼¶ûÐͱäÁ¿£»Èç¹ûÔ´ºÍÄ¿µÄĿ¼ÊÇÏàͬµÄ£¬Ôò±»ÖÃΪ1 | |
cnp |
Ä¿±êcomponentÃû |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐÈ¨ÖØÃüÃû¸ø¶¨ vnode vp
£¬ÖÁÖ¸¶¨Ä¿Â¼
dvp
£¬»ò¸üÃûΪcnp
¡£Èç¹ûÎÞÐ踲¸ÇÒÑÓÐÎļþ£¬ Ôòvp
ºÍ
label
µÄÖµ½«Îª NULL.
mpo_check_socket_listen
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨ¼àÌý¸ø¶¨Ì×½Ó×Ö¡£ ³É¹¦£¬Ôò·µ»Ø0£»·ñÔò£¬·µ»Ø´íÎó±àÂëÖµerrno
¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_lookup
int mpo_check_vnode_lookup
(struct ucred *cred,
struct vnode *dvp, struct label *dlabel, struct componentname *cnp);
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÔÚ¸ø¶¨µÄĿ¼ vnode ÖÐΪ²éÕÒ¸ø¶¨Ãû×ÖÖ´ÐÐlookup²Ù×÷¡£
³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸ö errno
Öµ¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_open
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
acc_mode |
open(2) ·ÃÎÊģʽ |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÔÚ¸ø¶¨ vnode ÉÏÒÔ¸ø¶¨µÄ·ÃÎÊģʽִÐÐ open ²Ù×÷¡£ Èç¹û³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸ö´íÎó±àÂë¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_readdir
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÔÚ¸ø¶¨µÄĿ¼ vnode ÉÏÖ´ÐÐ readdir
²Ù×÷¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸ö´íÎó±àÂë errno
¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_readlink
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÔÚ¸ø¶¨·ûºÅÁ´½Ó vnode ÉÏÖ´ÐÐ readlink
²Ù×÷¡£³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
¸Ãº¯Êý¿ÉÄÜÔÚÈô¸É»·¾³Ï±»µ÷Ó㬰üÀ¨ÓÉÓû§½ø³ÌÏÔʽִÐÐµÄ readlink
µ÷Ó㬠»òÕßÊÇÔÚ½ø³ÌÖ´ÐÐÃû×Ö²éѯʱÒþʽִÐÐµÄ readlink
¡£
mpo_check_vnode_revoke
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ³·Ïú¶Ô¸ø¶¨ vnode µÄ·ÃÎÊ¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_setacl
int mpo_check_vnode_setacl
(struct ucred *cred,
struct vnode *vp, struct label *label, acl_type_t type, struct acl *acl);
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÉèÖøø¶¨ vnode µÄ¸ø¶¨ÀàÐ굀 ACL¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_setextattr
int mpo_check_vnode_setextattr
(struct ucred *cred,
struct vnode *vp, struct label *label, int attrnamespace, const char *name, struct uio
*uio);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
attrnamespace |
À©Õ¹ÊôÐÔÃû×Ö¿Õ¼ä | |
name |
À©Õ¹ÊôÐÔÃû | |
uio |
I/O ½á¹¹Ö¸Õ룻²Î¼û uio(9) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÉèÖøø¶¨ vnode Éϸø¶¨Ãû×Ö¿Õ¼äÖиø¶¨Ãû×ÖµÄÀ©Õ¹ÊôÐÔµÄÖµ¡£
ʹÓÃÀ©Õ¹ÊôÐÔ±¸·Ý°²È«±ê¼ÇµÄ²ßÂÔÄ£¿é¿ÉÄÜÐèÒª¶ÔÆäʹÓõÄÊôÐÔʵʩ¶îÍâµÄ±£»¤¡£ÁíÍ⣬
ÓÉÓÚÔÚ¼ì²éºÍʵ¼Ê²Ù×÷ʱ¼ä¿ÉÄÜ´æÔڵľºÕù£¬ ²ßÂÔÄ£¿éÓ¦¸Ã±ÜÃâ¸ù¾ÝÀ´×Ôuio
ÖеÄÊý¾Ý×ö³ö¾ö²ß¡£ Èç¹ûÕýÔÚÖ´ÐÐÒ»¸öɾ³ý²Ù×÷£¬Ôò²ÎÊý uio
µÄÖµÒ²¿ÉÄÜΪ NULL¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_setflags
int mpo_check_vnode_setflags
(struct ucred *cred,
struct vnode *vp, struct label *label, u_long flags);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
flags |
Îļþ±êÖ¾£»²Î¼û chflags(2) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨΪ¸ø¶¨µÄ vnode ÉèÖøø¶¨µÄ±êÖ¾¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_setmode
int mpo_check_vnode_setmode
(struct ucred *cred,
struct vnode *vp, struct label *label, mode_t mode);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vnode | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
mode |
Îļþģʽ£»²Î¼û chmod(2) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ½«¸ø¶¨ vnode µÄģʽÉèÖÃΪ¸ø¶¨Öµ¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_setowner
int mpo_check_vnode_setowner
(struct ucred *cred,
struct vnode *vp, struct label *label, uid_t uid, gid_t gid);
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ½«¸ø¶¨ vnode µÄÎļþ uid ºÍÎļþ gid
ÉèÖÃΪ¸ø¶¨Öµ¡£Èç¹ûÎÞÐè¸üУ¬ Ïà¹Ø²ÎÊýÖµ¿ÉÄܱ»ÉèÖÃΪ(-1)¡£
³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_vnode_setutimes
int mpo_check_vnode_setutimes
(struct ucred *cred,
struct vnode *vp, struct label *label, struct timespec atime, struct timespec
mtime);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
¿ÍÌ壻vp | |
label |
vp µÄ²ßÂÔ±ê¼Ç |
|
atime |
·ÃÎÊʱ¼ä£»²Î¼û utimes(2) | |
mtime |
ÐÞ¸Äʱ¼ä£»²Î¼û utimes(2) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ½«¸ø¶¨ vnode µÄ·ÃÎÊʱ¼ä±êÇ©ÉèÖÃΪ¸ø¶¨Öµ¡£ ³É¹¦£¬Ôò·µ»Ø
0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_proc_sched
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨ¸Ä±ä¸ø¶¨½ø³ÌµÄµ÷¶È²ÎÊý¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»£» ESRCH£¬ÓÃÓÚÌṩ²»¿É¼ûÐÔÖÊ¡£
¡¡¡¡See setpriority(2) for more information.
mpo_check_proc_signal
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
proc |
¿ÍÌ壻½ø³Ì | |
signal |
Ðźţ»²Î¼û kill(2) |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÏò¸ø¶¨½ø³Ì·¢Ë͸ø¶¨Ðźš£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻EPERM£¬ÓÃÓÚȨÏÞ²»¹»£» ESRCH£¬ÓÃÓÚÌṩ²»¿É¼ûÐÔÖÊ¡£
mpo_check_vnode_stat
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´ÊÇ·ñÓÐȨÔÚ¸ø¶¨ vnode ÉÏÖ´ÐÐ stat
²Ù×÷¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£ ½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
¡¡¡¡See stat(2) for more information.
mpo_check_ifnet_transmit
int mpo_check_ifnet_transmit
(struct ucred *cred,
struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label
*mbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
ifnet |
ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet µÄ²ßÂÔ±ê¼Ç |
|
mbuf |
¿ÍÌ壻½«±»·¢Ë굀 mbuf | |
mbuflabel |
mbuf µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡È·¶¨Ïà¹ØÍøÂç½Ó¿ÚÊÇ·ñÓÐȨ´«Ë͸ø¶¨µÄ mbuf¡£³É¹¦£¬Ôò·µ»Ø 0£» ·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_socket_deliver
int mpo_check_socket_deliver
(struct ucred *cred,
struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *mbuf, struct label
*mbuflabel);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
ifnet |
ÍøÂç½Ó¿Ú | |
ifnetlabel |
ifnet µÄ²ßÂÔ±ê¼Ç |
|
mbuf |
¿ÍÌ壻½«±»´«Ë굀 mbuf | |
mbuflabel |
mbuf µÄ²ßÂÔ±ê¼Ç |
¡¡¡¡È·¶¨Ïà¹ØÌ×½Ó×ÖÊÇ·ñÓÐȨ´Ó¸ø¶¨µÄ mbuf ÖнÓÊÕÊý¾Ý±¨¡£ ³É¹¦£¬Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»¡£
mpo_check_socket_visible
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÐÅÈÎ×´cred ÊÇ·ñÓÐȨʹÓÃϵͳ¼à¿Øº¯Êý£¬±ÈÈ磬 ÓÉnetstat(8) ºÍ sockstat(1)ʹÓõijÌÐòÀ´¹Û²ì
¸ø¶¨µÄÌ×½Ó×Ö(socket
)¡£³É¹¦£¬ Ôò·µ»Ø 0£»·ñÔò£¬·µ»ØÒ»¸öerrno
Öµ¡£
½¨ÒéʹÓõĴíÎó±àÂ룺EACCES£¬ÓÃÓÚ±ê¼Ç²»Æ¥Å䣻 EPERM£¬ÓÃÓÚȨÏÞ²»¹»£» ESRCH£¬ÓÃÓÚÌṩ²»¿É¼ûÐÔÖÊ¡£
mpo_check_system_acct
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
ucred |
Ö÷ÌåÐÅÈÎ×´ | |
vp |
Éó¼ÆÎļþ£»acct(5) | |
vlabel |
Óëvp Ïà¹ØÁªµÄ±ê¼Ç |
¡¡¡¡¸ù¾ÝÖ÷Ìå±ê¼ÇºÍÉó¼ÆÈÕÖ¾ÎļþµÄ±ê¼Ç£¬È·¶¨¸ÃÖ÷ÌåÊÇ·ñÓÐȨÆô¶¯É󼯡£
mpo_check_system_reboot
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
howto |
À´×Ô reboot(2)µÄhowto ²ÎÊý |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓÐȨÒÔÖ¸¶¨·½Ê½ÖØÆôϵͳ¡£
mpo_check_system_sysctl
int mpo_check_system_sysctl
(struct ucred *cred, int
*name, u_int *namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t
newlen);
²ÎÊý | ˵Ã÷ | Ëø¶¨ |
---|---|---|
cred |
Ö÷ÌåÐÅÈÎ×´ | |
name |
²Î¼û sysctl(3) | |
namelen |
||
old |
||
oldlenp |
||
inkernel |
²¼¶ûÐͱäÁ¿£»Èç¹û´ÓÄں˱»µ÷Óã¬ÆäÖµ±»ÖÃΪ1 | |
new |
²Î¼û sysctl(3) | |
newlen |
¡¡¡¡È·¶¨Ïà¹ØÖ÷ÌåÊÇ·ñÓ¦¸Ã±»ÔÊÐíÖ´ÐÐÖ¸¶¨µÄ sysctl(3) ÊÂÎñ¡£
¡¡¡¡µ±Óû§½ø³ÌÇëÇó¶Ôij¸ö¶ÔÏóµÄ±ê¼Ç½øÐÐÐÞ¸Äʱ£¬½«Òý·¢ÖØÐ±ê¼Çʼþ¡£¶ÔÓ¦µÄ¸üвÙ×÷·ÖÁ½²½½øÐУº Ê×ÏÈ£¬½øÐзÃÎÊ¿ØÖƼì²é£¬È·Èϴ˴θüвÙ×÷ÊÇÓÐЧÇÒ±»ÔÊÐíµÄ£»È»ºó£¬µ÷ÓÃÁíÒ»¸ö¶ÀÁ¢µÄÈë¿Úº¯Êý¶Ô±ê¼Ç½øÐÐÐ޸ġ£ ÖØÐ±ê¼ÇÈë¿Úº¯Êýͨ³£½ÓÊÕÓÉÇëÇó½ø³ÌÌá½»µÄ¶ÔÏó¡¢¶ÔÏó±ê¼ÇÖ¸ÕëºÍÇëÇóбê¼Ç£¬×÷ΪÊäÈë²ÎÊý¡£ ¶ÔÏóÖØÐ±ê¼Ç²Ù×÷µÄʧ°Ü½«ÓÉÏÈÆÚµÄ±ê¼Ç¼ì²é±¨¸æ£¬ËùÒÔ£¬²»ÔÊÐíÔÚ½ÓÏÂÀ´µÄ±ê¼ÇÐ޸Ĺý³ÌÖб¨¸æÊ§°Ü£¬¹Ê¶ø²»ÌᳫÔڴ˹ý³ÌÖÐзÖÅäÄÚ´æ¡£
¡¡¡¡TrustedBSD MAC ¿ò¼Ü°üº¬ÁËÒ»×é²ßÂÔÎ޹صÄ×é³ÉÔªËØ£¬°üÀ¨¹ÜÀí³éÏó±ê¼ÇµÄ MAC ½Ó¿Ú¿â£¬ ¶ÔϵͳÐÅÈÎ×´¹ÜÀíÌåϵµÄÐÞ¸Ä, ΪÓû§·ÖÅä MAC ±ê¼ÇÌṩ֧³ÖµÄ login ¿âº¯Êý£¬ ÒÔ¼°Èô¸É¸ºÔðά»¤ºÍ¸üÐÂÄں˶ÔÏó(½ø³Ì¡¢ÎļþºÍÍøÂç½Ó¿ÚµÈ)°²È«±ê¼ÇµÄ¹¤¾ß¡£ ²»¾Ã£¬½«Óиü¶à¹ØÓÚÓ¦ÓòãÌåϵ½á¹¹µÄÏêϸÐÅÏ¢±»°üº¬½øÀ´¡£
¡¡¡¡TrustedBSD MAC ÌṩµÄ´óÁ¿¿âº¯ÊýºÍϵͳµ÷Óã¬ÔÊÐíÓ¦ÓóÌÐòʹÓÃÒ»ÖÖͳһµÄ¡¢²ßÂÔÎ޹صĽӿÚÀ´´¦Àí¶ÔÏóµÄ MAC ±ê¼Ç¡£ Èç´Ë£¬Ó¦ÓóÌÐò¿ÉÒÔÇáËɹÜÀí¸÷ÖÖ²ßÂԵıê¼Ç£¬ÎÞÐèΪÔö¼Ó¶Ôij¸öÌØ¶¨²ßÂÔµÄÖ§³Ö¶øÖØÐ±àÂë¡£Ðí¶àͨÓù¤¾ß£¬±ÈÈç ifconfig(8)£¬ls(1) ºÍ ps(1)£¬Ê¹ÓÃÕâЩ²ßÂÔÎ޹صĽӿڲéÑ¯ÍøÂç½á¹¹¡¢ÎļþºÍ½ø³ÌµÄ±ê¼ÇÐÅÏ¢¡£ ÕâЩ API Ò²±»ÓÃÓÚÖ§³Ö MAC ¹ÜÀí¹¤¾ß£¬±ÈÈ磬getfmac(8)£¬getpmac(8)£¬ setfmac(8)£¬ setfsmac(8)£¬ºÍ setpmac(8)¡£ MAC APIµÄÉè¼ÆÏ¸½Ú¿É²Î¿¼ mac(3).
¡¡¡¡Ó¦ÓóÌÐò´¦ÀíµÄ MAC ±ê¼ÇÓÐÁ½ÖÖ´æÔÚÐÎʽ£ºÄÚ²¿ÐÎʽ£¬ÓÃÀ´·µ»ØºÍÉèÖýø³ÌºÍ¶ÔÏóµÄ±ê¼Ç£¨mac_t£©£» »ùÓÚ C ×Ö·û´®µÄÍⲿÐÎʽ£¬×÷Ϊ±ê¼ÇÔÚÅäÖÃÎļþÖеĴæ·ÅÐÎʽ£¬ÓÃÓÚÏòÓû§ÏÔʾ»òÕßÓÉÓû§ÊäÈë¡£ ÿһ¸ö MAC ±ê¼ÇÓÉÒ»×é±ê¼ÇÔªËØ×é³É£¬ÆäÖÐÿ¸öÔªËØÊÇÒ»¸öÐÎÈ磨Ãû×Ö£¬Öµ£©µÄ¶þÔª×é¡£ ÄÚºËÖеÄÿ¸ö²ßÂÔÄ£¿é·Ö±ð±»Ö¸¶¨Ò»¸öÌØ¶¨µÄÃû×Ö£¬ÓÉËüÃǶԱê¼ÇÖÐÓë¸ÃÃû×Ö¶ÔÓ¦µÄÖµ²ÉÓÃÆä²ßÂÔÌØÓеķ½Ê½½øÐнâÎö¡£ ²ÉÓÃÍⲿÐÎʽ±íʾµÄ±ê¼Ç£¬Æä±ê¼ÇÔªËØ±íʾΪÃû×Ö / Öµ£¬ÔªËØÖ®¼äÒÔ¶ººÅ·Ö¸ô¡£ Ó¦ÓóÌÐò¿ÉÒÔʹÓà MAC ¿ò¼ÜÌṩµÄ API ½«Ò»¸ö°²È«±ê¼ÇÔÚÄÚ²¿ÐÎʽºÍÎı¾ÐÎʽ֮¼ä½øÐÐת»»¡£ ÿµ±ÏòÄں˲éѯij¸ö¶ÔÏóµÄ°²È«±ê¼Çʱ£¬ÄÚ²¿ÐÎʽµÄ±ê¼Ç±ØÐëÕë¶ÔËùÐèµÄÔªËØ¼¯ºÏ×÷ºÃÄÚ²¿±ê¼Ç´æ´¢×¼±¸¡£ Ϊ´Ë£¬Í¨³£²ÉÓÃÏÂÃæÁ½ÖÖ·½Ê½Ö®Ò»£ºÊ¹Óà mac_prepare(3) ºÍÒ»¸ö°üº¬ËùÐè±ê¼ÇÔªËØµÄÈÎÒâÁÐ±í£»»òÕߣ¬ ʹÓôÓmac.conf(5) ÅäÖÃÎļþÖмÓÔØÈ±Ê¡ÔªËØ¼¯ºÏµÄij¸öϵͳµ÷Óá£ÔÚ¶ÔÏó¼¶±ðÉèÖÃȱʡ±ê¼Ç£¬½«ÔÊÐíÓ¦ÓóÌÐòÔÚ²»È·¶¨ ϵͳÊÇ·ñ²ÉÓÃÏà¹Ø²ßÂÔµÄÇé¿öÏ£¬Ò²ÄÜÏòÓû§·µ»ØÓë¶ÔÏóÏà¹ØÁªµÄÓÐÒâÒåµÄ°²È«±ê¼Ç¡£
×¢Òâ: ĿǰµÄ MAC ¿â²»Ö§³ÖÖ±½ÓÐÞ¸ÄÄÚ²¿ÐÎʽµÄ±ê¼ÇÔªËØ£¬ËùÓеÄÐ޸ıØÐë°´ÕÕÏÂÁеIJ½Öè½øÐУº ½«ÄÚ²¿ÐÎʽµÄ±ê¼Çת»»³ÉÎı¾×Ö·û´®£¬¶Ô×Ö·û´®½øÐб༣¬×îºó½«Æäת»»³ÉÄÚ²¿ÐÎʽ±ê¼Ç¡£Èç¹ûÓ¦ÓóÌÐòµÄ×÷ÕßÖ¤Ã÷ȷʵÓÐÐèÒª£¬ ¿ÉÒÔÔÚ½«À´µÄ°æ±¾ÖмÓÈë¶ÔÄÚ²¿ÐÎʽ±ê¼Ç½øÐÐÖ±½ÓÐ޸ĵĽӿڡ£
¡¡¡¡Óû§ÉÏÏÂÎĹÜÀíµÄ±ê¼Ç½Ó¿Ú£¬ setusercontext(3) £¬µÄÐÐΪÒѾ±»ÐÞ¸ÄΪ£¬´Ó login.conf(5) ÖвéѯÓëij¸öÓû§µÇ¼Àà±ðÏà¹ØÁªµÄ MAC °²È«±ê¼Ç¡£ µ± LOGIN_SETALL ±»ÉèÖ㬻òÕßµ± LOGIN_SETMAC ±»Ã÷È·Ö¸¶¨Ê±£¬ÕâЩ°²È«±ê¼Ç½«ºÍÆäËûÓû§ÉÏÏÂÎIJÎÊýÒ»Æð±»ÉèÖá£
×¢Òâ: ¿ÉÒÔÔ¤ÆÚ£¬ÔÚ½ñºóµÄij¸ö°æ±¾ÖУ¬FreeBSD ½«°Ñ MAC ±ê¼Ç´Ó login.conf µÄÓû§Àà±ðÊý¾Ý¿âÖгé³ö£¬ÎªÆäά»¤Ò»¸ö¶ÀÁ¢µÄÊý¾Ý¿â¡£ ²»¹ýÔÚ´Ëǰºó£¬setusercontext(3) APIÓ¦¸Ã±£³Ö²»±ä¡£
¡¡¡¡TrustedBSD MAC ¿ò¼ÜʹµÃÄÚºËÄ£¿éÄÜÒÔÒ»ÖÖ¼¯Öеķ½Ê½£¬ÍêÉÆÏµÍ³µÄ°²È«²ßÂÔ¡£ ËüÃǼȿÉÀûÓÃÏÖÓеÄÄں˶ÔÏóÊôÐÔ£¬ÓÖÄÜʹÓÃÓÉ MAC ¿ò¼ÜÐÖúά»¤µÄ°²È«±ê¼ÇÊý¾Ý£¬À´ÊµÊ©·ÃÎÊ¿ØÖÆ¡£ ¿ò¼ÜÌṩµÄÁé»îÐÔʹµÃ¿ª·¢ÈËÔ±¿ÉÒÔÔÚÆäÉÏʵÏÖ¸÷ÖÖ²ßÂÔ£¬ÈçÀûÓà BSD ÏÖÓеÄÐÅÈÎ×´£¨credential£© ÓëÎļþ±£»¤»úÖÆµÄ²ßÂÔ£¬ÒÔ¼°ÐÅÏ¢Á÷°²È«²ßÂÔ£¨Èç MLS ºÍ Biba£©¡£ ʵÏÖа²È«·þÎñµÄ²ßÂÔ±à³ÌÈËÔ±£¬¿ÉÒԲο¼±¾Îĵµ£¬ÒÔÁ˽âÏÖÓа²È«Ä£¿éµÄÐÅÏ¢¡£
¡¡¡¡ÎïÀíÄÚ´æÍ¨¹ý½á¹¹Ìåvm_page_tÒÔҳΪ»ù´¡½øÐйÜÀí¡£ ÎïÀíÄÚ´æµÄÒ³ÓÉËüÃǸ÷×Ô¶ÔÓ¦µÄ½á¹¹Ìåvm_page_tËù´ú±í£¬ ÕâЩ½á¹¹Ìå´æ·ÅÔÚÈô¸É¸öÒ³¹ÜÀí¶ÓÁÐÖеÄÒ»¸öÀïÃæ¡£
¡¡¡¡Ò»Ò³¿ÉÒÔ´¦ÓÚÔÚÏß(wired)¡¢»î¶¯(active)£¬È¥»î(inactive)¡¢»º´æ(cache)¡¢ ×ÔÓÉ(free)״̬¡£³ýÁËÔÚÏß״̬£¬Ò³Ò»°ã±»·ÅÖÃÔÚÒ»¸öË«ÏòÁ´±í¶ÓÁÐÀ ´ú±íÁËËüËù´¦µÄ״̬¡£ÔÚÏßÒ³²»·ÅÖÃÔÚÈκζÓÁÐÀï¡£
¡¡¡¡FreeBSDΪ»º´æÒ³ºÍ×ÔÓÉҳʵÏÖÁËÒ»¸ö¸üΪ¸´ÔÓµÄÒ³¶ÓÁлúÖÆ£¬ ÒÔʵÏÖ¶ÔÒ³µÄ·ÖÀà¹ÜÀí¡£Ã¿Ò»ÖÖ״̬¶¼¶ÔÓ¦×Ŷà¸ö¶ÓÁУ¬ ¶ÓÁеݲÅŶÔÓ¦×Å´¦ÀíÆ÷µÄÒ»¼¶¡¢¶þ¼¶»º´æ¡£µ±ÐèÒª·ÖÅäÒ»¸öÐÂҳʱ£¬ FreeBSD»áÊÔͼ°ÑÒ»¸ö°´Ò»¼¶¡¢¶þ¼¶»º´æ¶ÔÆëµÄÒ³Ãæ·ÖÅ䏸ÐéÄâÄÚ´æ¶ÔÏó¡£
¡¡¡¡´ËÍ⣬һ¸öÒ³¿ÉÒÔÓÐÒ»¸öÒýÓüÆÊý£¬¿ÉÒÔ±»Ò»¸öæ¼ÆÊýËø¶¨¡£ ÐéÄâÄÚ´æÏµÍ³Ò²ÊµÏÖÁË¡°ÖÕ¼«Ëø¶¨¡±(ultimate locked)״̬£¬ Ò»¸öÒ³¿ÉÒÔÓÃÒ³±êÖ¾PG_BUSY±íʾÕâһ״̬¡£
¡¡¡¡×ÜÖ®£¬Ã¿¸öÒ³¶ÓÁж¼°´ÕÕLRU(Least-Recently Used)µÄÔÔò¹¤×÷¡£
ÒëÕß×¢: ¶ÌÓïLeast-Recently UsedÓÐÁ½ÖÖÀí½â·½Ê½£º 1.½«¡°least-recently¡±Àí½âΪ·´Ïò±È½Ï¼¶£¬ÒâÒåΪ¡°×îÔ硱£¬Õû¸ö¶ÌÓïÀí½âΪ ¡°×î½üµÄʹÓÃʱ¼ä×îÔ硱£»2.½«¡°least¡±ºÍ¡°recently¡±Àí½âΪ¸±´Ê£¬ ¶¼ÐÞÊΡ°used¡±£¬Õû¸ö¶ÌÓïÀí½âΪ¡°×î½ü×îÉÙʹÓᱡ£ ÕâÁ½ÖÖÀí½â·½Ê½µÄʵ¼ÊÒâÒå»ù±¾Ïàͬ¡£
¡¡¡¡Èç¹ûÒ»¸ö½ø³ÌÊÔͼ·ÃÎÊÒ»¸ö²»ÔÚÒ³±íÖжøÔÚijһ¶ÓÁÐÖеÄÒ³ (ÀýÈçÈ¥»î¶ÓÁлò»º´æ¶ÓÁÐ)£¬Ò»¸öÏà¶ÔºÄ·Ñ×ÊÔ´ÉÙµÄÒ³´íÎó·¢Éú£¬ µ¼ÖÂÒ³±»Öؼ¤»î¡£Èç¹ûÒ³¸ù±¾²»´æÔÚÓÚϵͳÄÚ´æÖ®ÖУ¬½ø³Ì±ØÐë±»×èÈû£¬ ´Ëʱҳ±»´Ó´ÅÅÌÖÐÔØÈë¡£
ÒëÕß×¢: IntelµÈ³§É̵ÄCPU¹¤×÷ÔÚ±£»¤Ä£Ê½Ê±£¬¿ÉÓÃÀ´ÊµÏÖÐéÄâÄÚ´æ¡£ µ±Ñ°Ö·µÄµØÖ·¿Õ¼ä¶ÔÓ¦×ÅÕæÊµÄÚ´æÊ±£¬ÔòÕý³£¶Áд£» µ±Ñ°Ö·µÄµØÖ·¿Õ¼äûÓжÔÓ¦µÄÕæÊµÄÚ´æÊ±£¬CPU»á²úÉúÒ»¸ö¡°´íÎó¡±£¬ ֪ͨ²Ù×÷ϵͳÓë´ÅÅ̵ÈÉ豸½øÐн»»»£¬¶ÁѰַÔòµ÷Èë´æ´¢ÄÚÈÝ£¬ дѰַÔòд³ö´æ´¢ÄÚÈÝ¡£Õâ¸ö¡°´íÎó¡± ²¢·Ç²Ù×÷ϵͳ»òÓ¦ÓóÌÐò¿ª·¢ÈËÔ±·¸ÏµĴíÎó£¬ ¾¡¹ÜÔÚCPUÓ²¼þʵÏÖÖÐÕâÓëÓ¦ÓóÌÐò»ò²Ù×÷ϵͳÄں˱ÀÀ£µÄ´íÎóµÄ·¢Éú»úÖÆÏàͬ¡£ ²Î¼ûIntelµÄCPU±£»¤Ä£Ê½¿ª·¢Êֲᡣ
¡¡¡¡FreeBSD¶¯Ì¬µÄµ÷ÕûÒ³¶ÓÁУ¬ÊÔͼ½«¸÷¸ö¶ÓÁÐÖеÄÒ³Êýά»¤ÔÚÒ»¸öÊʵ±µÄ±ÈÀýÉÏ£¬ ͬʱ¹ÜÀí³ÌÐò±ÀÀ£µÄÒÑÇåÀíºÍδÇåÀíÒ³¡£ÖØÐÂÆ½ºâµÄ±ÈÀýÊýÖµ¾ö¶¨ÓÚϵͳÄÚ´æµÄ¸ºµ£¡£ ÕâÖÖÖØÐÂÆ½ºâÓÉpageoutÊØ»¤½ø³ÌʵÏÖ£¬°üÀ¨ÇåÀíδÇåÀíÒ³(ÓëËûÃǵĺ󱸴洢ͬ²½)¡¢ ¼àÊÓÒ³±»ÒýÓõĻîÔ¾³Ì¶È (ÖØÖÃËüÃÇÔÚLRU¶ÓÁÐÖеÄλÖûòÔÚ²»Í¬»îÔ¾³Ì¶ÈµÄÒ³¶ÓÁмäÒÆ¶¯)¡¢ µ±±ÈÀý²»Æ½ºâʱÔÚ¶ÓÁмäÇ¨ÒÆÒ³£¬Èç´ËµÈµÈ¡£ FreeBSDµÄVMϵͳ»á½«Öؼ¤»îÒ³¶ø²úÉúµÄ´íÎóƵÂʵ÷µÍµ½Ò»¸öºÏÀíµÄÊýÖµ£¬ ÓÉ´ËÈ·¶¨Ä³Ò»Ò³»îÔ¾/ÏÐÖõÄʵ¼Ê³Ì¶È¡£ Õâ¿ÉÒÔΪ¸üºÃµÄ¾ö¶¨ºÎʱÇåÀí/·ÖÅäÒ»¸öÒ³×ö³ö¾ö²ß¡£
¡¡¡¡FreeBSDʵÏÖÁËͳһµÄ¡°ÐéÄâÄÚ´æ¶ÔÏó¡±(VM¶ÔÏó)µÄÉè¼ÆË¼Ïë¡£ VM¶ÔÏó¿ÉÒÔÓë¸÷ÖÖÀàÐ͵ÄÄÚ´æÊ¹Ó÷½Ê½Ïà½áºÏ©¤©¤Ö±½ÓʹÓÃ(unbacked)¡¢ ½»»»(swap)¡¢ÎïÀíÉ豸¡¢Îļþ¡£ ÓÉÓÚÎļþϵͳʹÓÃÏàͬµÄVM¶ÔÏó¹ÜÀíºËÄÚÊý¾Ý©¤©¤ÎļþµÄ»º´æ£¬ ËùÒÔÕâЩ»º´æµÄ½á¹¹Ò²ÊÇͳһµÄ¡£
¡¡¡¡VM¶ÔÏó¿ÉÒÔ±»Ó°¸´ÖÆ(shadowed)¡£ ËüÃÇ¿ÉÒÔ±»¶Ñ·Åµ½ÆäËüÀà±ðVM¶ÔÏó¶ÑÕ»µÄ¶¥¶Ë¡£ÀýÈ磬¿ÉÒÔÓÐÒ»¸ö½»»»VM¶ÔÏó£¬ ·ÅÖÃÔÚÎļþVM¶ÔÏó¶ÑÕ»µÄ¶¥¶Ë£¬ÒÔʵÏÖMAP_PRIVATEµÄmmap()²Ù×÷¡£ ÕâÑùµÄÈëÕ»²Ù×÷Ò²¿ÉÒÔÓÃÀ´ÊµÏÖ¸÷ÖÖ¸÷ÑùµÄ¹²ÏíÌØÐÔ£¬ °üÀ¨Ð´Èëʱ¸´ÖÆ(copy-on-write£¬ÓÃÓÚÈÕÖ¾Îļþϵͳ)£¬ÒÔÅÉÉú³öµØÖ·¿Õ¼ä¡£
¡¡¡¡Ó¦µ±×¢Ò⣬һ¸övm_page_t ½á¹¹ÌåÔÚÈÎÒ»¸öʱ¿ÌÖ»ÄÜÓëÒ»¸öVM¶ÔÏóÏà¹ØÁª¡£ VM¶ÔÏóÓ°¸´±¾¿ÉÒÔʵÏÖ¿çʵÀýµÄ¹²ÏíÏàͬµÄÒ³¡£
¡¡¡¡vnode VM¶ÔÏ󣬱ÈÈçÎļþVM¶ÔÏó£¬Ò»°ãÐèҪά»¤ËüÃÇ×Ô¼ºµÄÇåÀí(clean)/ δÇåÀí(dirty)ÐÅÏ¢£¬¶ø²»ÒÀÀµÓÚÎļþϵͳµÄÇåÀí/δÇåÀíά»¤¡£ ÀýÈ磬µ±VMϵͳҪͬ²½Ò»¸öÎïÀíÒ³ºÍÆä¶ÔÓ¦µÄʵ¼Ê´æ´¢Æ÷£¬ VMϵͳ¾ÍÐèÒªÔÚдÈ뵽ʵ¼Ê´æ´¢Æ÷ǰ½«¸ÃÒ³±ê¼ÇΪÒÑÇåÀí¡£ ÁíÍ⣬ÎļþϵͳҪÄܹ»½«Îļþ»òÎļþÔªÊý¾ÝµÄ¸÷²¿·ÖÓ³Éäµ½ÄÚºËÐéÄâÄÚ´æ (KVM)ÖÐÒÔ±ã²Ù×÷¡£
¡¡¡¡ÓÃÀ´½øÐÐÕâЩ¹ÜÀíµÄʵÌå¾ÍÊÇÖÚËùÖÜÖªµÄÎļþϵͳ»º´æ£¬ struct buf»òbp¡£ µ±ÎļþϵͳÐèÒª¶ÔÒ»¸öVM¶ÔÏóµÄÒ»²¿·Ö²Ù×÷ʱ£¬ Ëü³£»á½«Õâ¸ö¶ÔÏóµÄÕⲿ·ÖÓ³Éäµ½struct buf£¬ ²¢ÇÒ½«struct bufÖÐÒ³Ó³Éäµ½ÄÚºËÐéÄâÄÚ´æ(KVM)ÖС£ ͬÑùµÄ£¬´ÅÅÌÊäÈë/Êä³öͨ³£ÒªÏȽ«VM¶ÔÏóµÄ¸÷²¿·ÖÓ³Éäµ½buf½á¹¹ÌåÖУ¬ È»ºó¶Ôbuf½á¹¹Ìå½øÐÐÊäÈë/Êä³ö²Ù×÷¡£ ϲãµÄvm_page_tÔÚÊäÈë/Êä³öÆÚ¼äͨ³£±»±ê¼ÇΪ¡°Ã¦¡±¡£ Îļþϵͳ»º´æÒ²»á¡°Ã¦¡±£¬Õâ¶ÔÓÚÎļþϵͳÇý¶¯³ÌÐò·Ç³£ÓÐÓ㬠¶ÔÎļþϵͳ»º´æ²Ù×÷±È¶ÔVMÕæÊµÒ³(hard)²Ù×÷¸üºÃ¡£
¡¡¡¡FreeBSD±£ÁôÒ»¶¨ÊýÁ¿µÄÄÚºËÐéÄâÄÚ´æÀ´´æ·Åstruct bufµÄÓ³É䣬 µ«ÊÇÕâЩbuf½á¹¹ÌåÓ¦¸ÃÊDZ»ÇåÀí¹ýµÄ¡£ÕâЩÄÚºËÐéÄâÄÚ´æ½öÓÃÀ´´æ·ÅÓ³É䣬 ²¢²»ÏÞÖÆ»º´æÊý¾ÝµÄÄÜÁ¦¡£ÑϸñµÄ˵£¬ÎïÀíÊý¾Ý»º´æÊÇ vm_page_tµÄÒ»¸ö¹¦ÄÜ£¬²»ÊÇÎļþϵͳ»º´æµÄ¹¦ÄÜ¡£ È»¶ø£¬ÓÉÓÚÎļþϵͳ»º´æ±»ÓÃÀ´´¦ÀíÊäÈë/Êä³ö£¬ ËûÃǹÌÓеÄÏÞÖÆÁËͬʱ½øÐÐÊäÈë/Êä³ö¿ÉÄܵÄÊýÁ¿¡£ µ«ÊÇ£¬ÓÉÓÚͨ³£ÓÐÊýǧÎļþϵͳ»º´æ¿É¹©Ê¹Óã¬ËùÒÔÕâ²¢²»»áÔì³ÉÎÊÌâ¡£
¡¡¡¡FreeBSD½«ÎïÀíÒ³±í½á¹¹´ÓVMϵͳÖзÖÀëÁ˳öÀ´¡£¸÷½ø³ÌµÄËùÓÐÒ³±í¿ÉÒÔÍÑÀë½ø³Ì (on the fly)ÖØ½¨£¬²¢ÇÒͨ³£±»ÈÏΪÊÇÒ»´ÎÐԵġ£ÌØÊâµÄÒ³±í£¬ÈçÄÚºËÐéÄâÄÚ´æ(KVM)£¬ ³£³£ÊDZ»ÓÀ¾ÃÐÔÔ¤·ÖÅäµÄ£»ÕâЩҳ±í²»ÊÇÒ»´ÎÐԵġ£
¡¡¡¡FreeBSDͨ¹ývm_map_tºÍvm_entry_t ½á¹¹½«ÐéÄâÄÚ´æÖÐvm_objectsµÄ¸÷µØÖ··¶Î§²¿·Ö¹ØÁªÆðÀ´¡£ Ò³±í±»Ö±½ÓµÄ´Ó vm_map_t/vm_entry_t/vm_object_t ÖÐÓвã´ÎµÄºÏ³É³öÀ´¡£ÕâÀïÐèÒªÖØÉêһϣ¬ÎÒÔøÌáµ½µÄ¡°ÎïÀíÒ³½öÖ±½ÓÓë vm_objectÏà¹ØÁª¡±²¢²»ºÜÕýÈ·¡£vm_page_t Ò²±»»á±»Á´½Óµ½ÕýÔÚÓëÖ®Ïà¹ØÁªµÄÒ³±íÖС£µ±Ò³±í±»µ÷ÓÃʱ£¬ Ò»¸övm_page_t½á¹¹Ìå¿ÉÒÔ±»Á´½Óµ½¼¸¸öpmaps¡£ È»¶ø£¬ÓÉÓÚÓÐÁ˲ã´ÎµÄ¹ØÁª£¬Òò´ËÔÚ¶ÔÏóÖÐËùÓжÔͬһҳµÄÒýÓûáÒýÓÃͬһ vm_page_t½á¹¹Ì壬ÕâÑù¾ÍʵÏÖÁË¿çÇøÓò(board)µÄ»º´æµÄͳһ¡£
¡¡¡¡FreeBSDʹÓÃKVM´æ·Å¸÷ÖÖ¸÷ÑùµÄÄں˽ṹÌå¡£ÔÚKVMÖÐ×î´óµÄµ¥¸öʵÌåÊÇÎļþϵͳ»º´æ¡£ ÄÇÊÇÓëstruct bufʵÌåÓйصÄÓ³Éä¡£
¡¡¡¡²»ÏñLinux£¬FreeBSD²»½«ËùÓеÄÎïÀíÄÚ´æÓ³Éäµ½KVMÖС£ ÕâÒâζ×ÅFreeBSD¿ÉÒÔÔÚ32λƽ̨ÉϹÜÀí³¬¹ý4GBµÄÄÚ´æÅäÖá£ÊÂʵÉÏ£¬ Èç¹ûmmu(ÒëÕß×¢£º¿ÉÄÜÊÇÖ¸¡°ÄÚ´æ¹ÜÀíµ¥Ôª¡±£¬¡°Memory Management Unit¡±) ÓÐ×ã¹»µÄÄÜÁ¦£¬FreeBSDÀíÂÛÉÏ¿ÉÒÔÔÚ32λƽ̨ÉϹÜÀí×î¶à8TBµÄÄÚ´æÅäÖᣠȻ¶ø£¬´ó¶àÊý32ƽֻ̨ÄÜÓ³Éä4GBÄڴ棬ÕâÖ»ÄÜÊÇÒ»¸öÕùÂ۵㡣
¡¡¡¡Óм¸ÖÖ»úÖÆ¿ÉÒÔ¹ÜÀíKVM¡£¹ÜÀíKVMµÄÖ÷Òª»úÖÆÊÇÇøÓò·ÖÅäÆ÷ (zone allocator)¡£ÇøÓò·ÖÅäÆ÷¹ÜÀí×ÅKVMµÄ´ó¿é£¬ÔÙ½«´ó¿éÇзÖΪºã¶¨´óСµÄС¿é£¬ ÒԱ㰴ÕÕijһÖÖÀàÐ͵ĽṹÌå·ÖÅä¡£Äã¿ÉÒÔʹÓÃÃüÁîvmstat -m Ò»ÀÀµ±Ç°KVM·ÖÇøÊ¹ÓÃÇé¿ö¡£
¡¡¡¡¿ª·¢ÕßµÄÐͬŬÁ¦Ê¹µÃFreeBSD¿ÉÒÔ×ÔÐж¯Ì¬µ÷ÕûÄںˡ£Ò»°ãÀ´Ëµ£¬
³ýÁËÄÚºËÅäÖÃÑ¡Ïîmaxusers
ºÍNMBCLUSTERS
£¬
Äã²»ÐèÒª×öÈκÎÔÓÂÒµÄÊÂÇé¡£ÕâЩÄں˱àÒëÅäÖÃÑ¡Ïî(Ò»°ã)±»Ö¸¶¨ÔÚ /usr/src/sys/i386/conf/CONFIG_FILE
Ö®ÖС£ËùÓпÉÓÃÄÚºËÅäÖÃÑ¡ÏîµÄÃèÊö¿ÉÔÚ /usr/src/sys/i386/conf/LINTÖÐÕÒµ½¡£
¡¡¡¡ÔÚÒ»¸ö´óϵͳµÄÅäÖÃÖУ¬Äã¿ÉÄÜÐèÒªÔö¼Ómaxusers
掙歜
ÊýÖµ·¶Î§Í¨³£ÔÚ10µ½128¡£×¢Ò⣬¹ý¶ÈÔö¼Ómaxusers
µÄÖµ¿ÉÄܵ¼ÖÂϵͳ´Óʵ¼Ê¿ÉÓõÄKVMÖÐÒç³ö£¬´Ó¶øÒýÆðÎÞ·¨Ô¤ÖªµÄ²Ù×÷¡£ ×îºÃ½«maxusers
ÉèΪһ¸öºÏÀíµÄÊýÖµ£¬²¢ÇÒÌí¼ÓÆäËüÑ¡Ï ÈçNMBCLUSTERS
£¬À´Ôö¼ÓÌØ¶¨µÄ×ÊÔ´¡£
¡¡¡¡Èç¹ûÄãµÄϵͳҪ±»ÖظººÉµÄʹÓÃÍøÂ磬ÄãÐèÒªÔö¼Ó NMBCLUSTERS
µÄÖµ¡£ÊýÖµ·¶Î§Í¨³£ÔÚ1024µ½4096¡£
¡¡¡¡NBUFÒ²ÊÇ´«Í³µÄ¹æ»®ÏµÍ³µÄ²ÎÊý¡£ Õâ¸ö²ÎÊý¾ö¶¨ÏµÍ³¿ÉÓÃÀ´Ó³ÉäÎļþϵͳÊäÈë/Êä³ö»º´æµÄKVMµÄÊýÁ¿¡£ ×¢Ò⣺Õâ¸ö²ÎÊýÓëͳһµÄ»º´æÃ»ÓÐÈκιØÏµ¡£Õâ¸ö²ÎÊý¿ÉÔÚ3.0-CURRENT ºÍÒÔºóµÄÄÚºËÖб»¶¯Ì¬µÄµ÷½Ú£¬Í¨³£²»Ó¦µ±±»ÊÖ¶¯µÄµ÷½Ú¡£ ÎÒÃÇÍÆ¼öÄã²»ÒªÖ¸¶¨NBUF¡£ ÈÃϵͳ×ÔÐÐÈ·¶¨Ëü¡£Ì«Ð¡µÄÖµ»áµ¼Ö·dz£µÍЧµÄÎļþϵͳ²Ù×÷£» Ì«´óµÄÖµ»áʹÓÃÒ³¶ÓÁÐÖÐȱÉÙÒ³Ãæ£¬¶ø´óÁ¿µÄÒ³´¦ÓÚÔÚÏß״̬¡£
¡¡¡¡È±Ê¡Çé¿öÏ£¬FreeBSDÄں˱àÒëʱÊDz»±»ÓÅ»¯µÄ¡£ Äã¿ÉÒÔÔÚÄÚºËÅäÖÃÎļþÖÐÓÃmakeoptions
Ö¸¶¨ÅÅ´í(debugging)ºÍÓÅ»¯±êÖ¾¡£×¢Ò⣬ÄãÒ»°ã²»Ó¦Ê¹ÓÃ-g
£¬
³ý·ÇÄãÄܹ»Ó¦¸¶Óɴ˲úÉúµÄ´óÄÚºË(µäÐ͵ÄÊÇ7MB»ò¸ü¶à)¡£
makeoptions DEBUG="-g" makeoptions COPTFLAGS="-O -pipe"
¡¡¡¡SysctlÌṩÁËÔÚÔËÐÐʱµ÷ÕûÄں˵ķ½Ê½¡£Äãͨ³£²»ÐèÒªÖ¸¶¨ÈκÎsysctl±äÁ¿£¬ ÓÈÆäÊÇÓëVMÏà¹ØµÄÄÇЩ±äÁ¿¡£
¡¡¡¡ÔËÐÐʱVMºÍϵͳµ÷ÕûµÄÓ°ÏìÏà¶ÔÖ±½ÓһЩ¡£ Ê×ÏÈ£¬Ó¦µ±¾¡¿ÉÄÜÔÚUFS/FFSÎļþϵͳÉÏʹÓÃSoft Updates¡£ ÔÚ/usr/src/sys/ufs/ffs/README.softupdates ÀïÓйØÓÚÈçºÎÅäÖõÄָʾ¡£
¡¡¡¡Æä´Î£¬Ó¦µ±ÅäÖÃ×ã¹»¶àµÄ½»»»¿Õ¼ä¡£ ÄãÓ¦µ±ÔÚÿ¸öÎïÀí´ÅÅÌÉÏÅäÖÃÒ»¸ö½»»»·ÖÇø£¬×î¶à4¸ö£¬ ÉõÖÁÔÚÄãµÄ¡°¹¤×÷¡±´ÅÅÌÉÏ¡£ÄãÓ¦µ±ÓÐÖÁÉÙ2±¶ÓÚÖ÷ÄÚ´æµÄ½»»»¿Õ¼ä£» ¼ÙÈçÄãûÓÐ×ã¹»ÄÚ´æµÄ»°£¬½»»»·ÖÇø»¹Ó¦¸ü¶à¡£ ÄãÒ²Ó¦µ±°´ÕÕÄãÆÚÍûÖеÄ×î´óÄÚ´æÅäÖþö¶¨½»»»·ÖÇøµÄ´óС£¬ ÕâÑùÒÔºó¾Í²»ÔÙÐèÒªÖØÐ¸ø´ÅÅÌ·ÖÇøÁË¡£ Èç¹ûÄã´¦Àíϵͳ±ÀÀ£ºóµÄÄÚ´æÇãµ¹(crash dump)£¬ µÚÒ»¸ö½»»»·ÖÇø±ØÐëÖÁÉÙÓëÖ÷ÄÚ´æÒ»Ñù´ó£¬ /var/crash±ØÐëÓÐ×ã¹»µÄ¿Õ¼äÀ´³Ð×°Çãµ¹¡£
¡¡¡¡NFSÉϵĽ»»»·ÖÇø¿ÉÒԺܺõı»4.X»òºóÀ´µÄϵͳʹÓ㬠µ«ÊÇÄã±ØÐëÃ÷°×NFS·þÎñÆ÷½«Òª¾ÊÜÒ³×°ÔØ²Ù×÷ºÜÇ¿µÄ³å»÷¡£
¡¡¡¡Õâ·ÝÎĵµ¶ÔĿǰ SMPng ¼Ü¹¹µÄÉè¼ÆÓëʵÏÖ½øÐÐÁ˽éÉÜ¡£ ËüÊ×ÏȽéÉÜÁË»ù±¾µÄÔÓïºÍÏà¹Ø¹¤¾ß£¬ ÆäºóÊǹØÓÚ FreeBSD Äں˵Äͬ²½ÓëÖ´ÐÐÄ£ÐÍ£¬ ½ÓÏÂÀ´ÌÖÂÛÁ˾ßÌåϵͳÖеÄËø²ßÂÔ£¬ ²¢ÃèÊöÁËÔÚ¸÷¸ö×ÓϵͳÖÐÒýÈëϸÁ£¶ÈµÄͬ²½ºÍʵÏÖ²¢Ðл¯µÄ²½Ö裬 ×îºóÊÇÏêϸµÄʵÏÖ˵Ã÷£¬ ÓÃÒÔ½âÊÍ×î³õ×ö³öijЩÉè¼Æ¾ö²ßµÄ¶¯»ú£¬ ²¢Ê¹¶ÁÕßÁ˽âʹÓÃÌØ¶¨µÄÔÓïËù¿ÉÄܲúÉúµÄÖØ´óÓ°Ïì¡£
¡¡¡¡Õâ·ÝÎĵµÈÔÔÚ׫дµ±ÖУ¬ ²¢½«²»¶Ï¸üÐÂÒÔ·´Ó³Óë SMPng ÏîÄ¿ÓйصÄ×îÐÂÉè¼ÆÓëʵÏÖµÄÇé¿ö¡£ ÆäÖÐÓÐÐí¶àС½ÚĿǰ»¹Ö»ÊÇÌá¸Ù£¬ µ«ÎÒÃÇ»áÖð½¥ÎªÆä³äʵÄÚÈÝ¡£ ¹ØÓÚÕâ·ÝÎĵµµÄ¸üкͽ¨Ò飬 Çë·¢¸øÎĵµ±à¼¡£
¡¡¡¡SMPng µÄÄ¿±êÊÇʹÄÚºËÄܹ»²¢·¢Ö´ÐС£ »ù±¾ÉÏ£¬ ÄÚºËÊÇÒ»¸öºÜ´ó¶ø¸´ÔӵijÌÐò¡£ ÒªÈÃÄÚºËÄܹ»¶àÏ̵߳ØÖ´ÐУ¬ ÎÒÃÇÐèҪʹÓÃijЩÆäËü¶àÏ̳߳ÌÐòÔÚʵÏÖʱËùÓõ½µÄ¹¤¾ß£¬ Õâ°üÀ¨»¥³âÌå(mutex)¡¢ ¹²Ïí/ÅÅËûËø(shared/exclusive lock)¡¢ ÐźÅÁ¿(semaphores) ºÍÌõ¼þ±äÁ¿(condition variable)¡£ Èç¹ûÏ£ÍûÁ˽âËüÃÇÒÔ¼°ÆäËü SMP ÊõÓ Çë²ÎÔı¾ÎÄµÄ ÊõÓï±í Ò»½Ú¡£
¡¡¡¡¹ØÓÚÄÚ´æÕ¤ºÍÔ×Ó²Ù×÷Ö¸ÁîÒѾÓкܶà½éÉܲÄÁÏ£¬ Òò´ËÕâÒ»½Ú²¢²»´òËã¶ÔÆä½øÐÐÏ꾡µÄ½éÉÜ¡£ ¼ò¶øÑÔÖ®£¬ Èç¹ûÓжÔijһ±äÁ¿ÉÏÐ´Ëø£¬ ¾Í²»ÄÜÔÚ²»»ñµÃÏàÓ¦µÄËøÊ±¶ÔÆä½øÐжÁÈ¡²Ù×÷¡£ Ò²¾ÍÊÇ˵£¬ ÄÚ´æÕ¤µÄ×÷ÓÃÔÚÓÚ±£Ö¤ÄÚ´æ²Ù×÷µÄÏà¶Ô˳Ðò£¬ µ«²¢²»±£Ö¤ÄÚ´æ²Ù×÷µÄÑϸñʱÐò¡£ »»ÑÔÖ®£¬ ÄÚ´æÕ¤²¢²»±£Ö¤ CPU ½«±¾µØ¿ìÈ¡»º´æ»ò´æ´¢»º³åµÄÄÚÈÝˢд»ØÄڴ棬 ¶øÊÇÔÚËøÊÍ·Åʱȷ±£ÆäËù±£»¤µÄÊý¾Ý£¬ ¶ÔÓÚÄÜ¿´µ½¸ÕÊͷŵÄÄǸöËøµÄ CPU »òÉ豸¿É¼û¡£ ³ÖÓÐÄÚ´æÕ¤µÄ CPU ¿ÉÒÔÔÚÆä¿ìÈ¡»º´æ»ò´æ´¢»º³åÖн«Êý¾Ý±£³ÖÆäËùÏ£ÍûµÄ¡¢ ÈÎÒⳤµÄʱ¼ä£¬ µ«Èç¹ûÆäËü CPU ÔÚͬһÊý¾ÝÔªÉÏÖ´ÐÐÔ×Ó²Ù×÷£¬ ÔòµÚÒ»¸ö CPU ±ØÐë±£Ö¤£¬ ÆäËù¸üеÄÊý¾ÝÖµ£¬ ÒÔ¼°ÄÚ´æÕ¤ËùÒªÇóµÄÈÎºÎÆäËü²Ù×÷£¬ ¶ÔµÚ¶þ¸ö CPU ¿É¼û¡£
¡¡¡¡ÀýÈ磬 ¼ÙÉèÔÚÒ»¼òµ¥Ä£ÐÍÖУ¬ ÈÏΪÔÚÖ÷´æ (»òijһȫ¾Ö¿ìÈ¡»º´æ) ÖеÄÊý¾ÝÊǿɼûµÄ£¬ µ±Ä³Ò» CPU ÉÏ´¥·¢Ô×Ó²Ù×÷ʱ£¬ ÆäËü CPU µÄ´æ´¢»º³åºÍ¿ìÈ¡»º´æ¾Í±ØÐë¶Ôͬһ¿ìÈ¡»º´æÏßÉϵÄÈ«²¿Ð´²Ù×÷£¬ ÒÔ¼°ÄÚ´æÕ¤Ö®ºóµÄÈ«²¿Î´Íê³É²Ù×÷½øÐÐˢд¡£
¡¡¡¡ÕâÑùÒ»À´£¬ ÔÚʹÓÃÓÉÔ×Ó²Ù×÷±£»¤µÄÄڴ浥Ԫʱ¾ÍÐèÒªÌØ±ðСÐÄ¡£ ÀýÈ磬 ÔÚʵÏÖ sleep
mutex ʱ£¬ ÎÒÃǾͱØÐëʹÓà atomic_cmpset
¶ø²»ÊÇ
atomic_set
À´´ò¿ª MTX_CONTESTED
λ¡£ ÕâÑù×öµÄÔÒòÊÇ£¬ ÎÒÃÇÐèÒª°Ñ mtx_lock
µÄÖµ¶Áµ½Ä³¸ö±äÁ¿£¬ ²¢¾Ý´Ë½øÐоö²ß¡£ È»¶ø£¬
ÎÒÃǶÁµ½µÄÖµ¿ÉÄÜÊǹýʱµÄ£¬ Ò²¿ÉÄÜÔÚÎÒÃǽøÐоö²ßµÄ¹ý³ÌÖз¢Éú±ä»¯¡£ Òò´Ë£¬ µ±Ö´ÐÐ
atomic_set
ʱ£¬ ×îÖÕ¿ÉÄÜ»á¶ÔÁíÒ»Öµ½øÐÐÖÃ룬
¶ø²»ÊÇÎÒÃǽøÐоö²ßµÄÄÇÒ»¸ö¡£ Õâ¾Í±ØÐëͨ¹ý atomic_cmpset
À´±£Ö¤Ö»ÓÐÔÚÎÒÃǵľö²ßÒÀ¾ÝÊÇ×îеÄʱ£¬ ²Å¶ÔÏàÓ¦µÄ±äÁ¿½øÐÐÖÃλ¡£
¡¡¡¡×îºó£¬ Ô×Ó²Ù×÷Ö»ÔÊÐíÒ»´Î¸üлò¶ÁÒ»¸öÄÚ´æµ¥Ôª¡£ ÐèÒªÔ×ӵظüжà¸öµ¥ÔªÊ±£¬ ¾Í±ØÐëʹÓÃËøÀ´´úÌæËüÁË¡£ ÀýÈ磬 Èç¹ûÐèÒª¸üÐÂÁ½¸öÏ໥¹ØÁªµÄ¼ÆÊýÆ÷ʱ£¬ ¾Í±ØÐëʹÓÃËø£¬ ¶ø²»ÊÇÁ½´Îµ¥¶ÀµÄÔ×Ó²Ù×÷ÁË¡£
¡¡¡¡¶ÁËø²¢²»ÐèÒªÏñÐ´ËøÄÇÑùÇ¿¡£ ÕâÁ½ÖÖÀàÐ͵ÄËø£¬ ¶¼ÐèҪȷ±£Í¨¹ýËüÃÇ·ÃÎʵIJ»ÊǹýʱµÄÊý¾Ý¡£ È»¶ø£¬ Ö»ÓÐд²Ù×÷±ØÐëÊÇÅÅËûµÄ£¬ ¶ø¶à¸öÏß³ÌÔò¿ÉÒÔ°²È«µØ¶Áͬһ±äÁ¿µÄÖµ¡£ ʹÓò»Í¬ÀàÐ͵ÄËøÓÃÓÚ¶ÁºÍд²Ù×÷ÓÐÐí¶à¸÷×Ô²»Í¬µÄʵÏÖ·½Ê½¡£
¡¡¡¡µÚÒ»ÖÖ·½·¨ÊÇÓà sx Ëø£¬ Ëü¿ÉÒÔÓÃÓÚʵÏÖдʱʹÓõÄÅÅËûËø£¬ ¶ø¶ÁʱÔò×÷Ϊ¹²ÏíËø¡£ ÕâÖÖ·½·¨Ê®·Ö¼òµ¥Ã÷ÁË¡£
¡¡¡¡µÚ¶þÖÖ·½·¨ÔòÂÔÏÔ»Þɬ¡£ ¿ÉÒÔÓöà¸öËøÀ´±£»¤Í¬Ò»Êý¾ÝÔª¡£ ¶Áʱ£¬
Ö»ÐèËøÆäÖеÄÒ»¸ö¶ÁËø¼´¿É¡£ È»¶ø£¬ Èç¹ûҪдÊý¾ÝµÄ»°£¬ ÔòÐèÒªÊ×ÏÈÉÏËùÓеÄÐ´Ëø¡£
Õâ»á´ó´óÌá¸ßд²Ù×÷µÄ´ú¼Û£¬ µ«µ±¿ÉÄÜÒÔ¶àÖÖ·½Ê½·ÃÎÊÊý¾Ýʱȴ¿ÉÄܷdz£ÓÐÓᣠÀýÈ磬
¸¸½ø³ÌÖ¸ÕëÊÇͬʱÊÜ proctree_lock
sx ËøºÍ½ø³Ì mutex
±£»¤µÄ¡£ ÔÚֻϣÍû¼ì²éÒÑËø½ø³ÌµÄ¸¸½ø³Ìʱ£¬ Óà proc Ëø¸üΪ·½±ã¡£ µ«ÊÇ£¬ ÆäËüһЩµØ·½£¬
ÀýÈç inferior
ÕâÀàÐèҪͨ¹ý¸¸Ö¸ÕëÔÚ½ø³ÌÊ÷ÉϽøÐÐËÑË÷£¬
²¢¶Ôÿ¸ö½ø³ÌÉÏËøµÄµØ·½¾Í²»ÄÜÕâÑù×öÁË£¬ ·ñÔò£¬
½«ÎÞ·¨±£Ö¤ÔÚ¶ÔÎÒÃÇËù»ñµÃµÄ½á¹ûÖ´ÐвÙ×÷ʱ£¬ ֮ǰ¼ì²éʱµÄ×´¿öÒÀ¾ÉÓÐЧ¡£
¡¡¡¡Èç¹ûÄúÐèҪʹÓÃËøÀ´±£³ÖËù¼ì²é±äÁ¿µÄ״̬£¬ ²¢¾Ý´ËÖ´ÐÐijЩ²Ù×÷ʱ£¬ ÊDz»Äܽö½öÔÚ¶Á±äÁ¿Ö®Ç°¶ÔÆäÉÏËø£¬ ²¢ÔÚÖ´ÐвÙ×÷֮ǰ½âËøµÄ¡£ ¹ýÔç½âËø½«Ê¹±äÁ¿Ôٴοɱ䣬 Õâ¿ÉÄܻᵼÖÂ֮ǰËù×öµÄ¾ö²ßʧЧ¡£ Òò´Ë£¬ ÔÚËù×ö¼ì²âÒý·¢µÄ¶¯×÷½áÊøÖ®Ç°£¬ ±ØÐë¼ÌÐø±£³ÖÉÏËø×´Ì¬¡£
¡¡¡¡ÓëÐí¶àÆäËü¶àÏß³Ì UNIX ÄÚºËËù²ÉÈ¡µÄģʽÀàËÆ£¬ FreeBSD »á¸³ÓèÖжϴ¦Àí³ÌÐò¶ÀÁ¢µÄÏß³ÌÉÏÏÂÎÄ£¬ ÕâÑù×öÄܹ»ÈÃÖжÏÏß³ÌÔÚÓöµ½ËøÊ±×èÈû¡£ µ«ÎªÁ˱ÜÃâ²»±ØÒªµÄÑÓ³Ù£¬ ÖжÏÏß³ÌÔÚÄÚºËÖУ¬ ÊÇÒÔʵʱÏ̵߳ÄÓÅÏȼ¶ÔËÐеġ£ Òò´Ë£¬ Öжϴ¦Àí³ÌÐò²»Ó¦Ö´Ðйý¾Ã£¬ ÒÔÃâ¶öËÀÆäËüÄÚºËÏ̡߳£ ´ËÍ⣬ ÓÉÓÚ¶à¸ö´¦Àí³ÌÐò¿ÉÒÔ·ÖÏíͬһÖжÏỊ̈߳¬ Öжϴ¦Àí³ÌÐò²»Ó¦ÐÝÃߣ¬ »òʹÓÿÉÄܵ¼ÖÂÐÝÃßµÄËø£¬ ÒÔ±ÜÃ⽫ÆäËüÖжϴ¦Àí³ÌÐò¶öËÀ¡£
¡¡¡¡Ä¿Ç°ÔÚ FreeBSD ÖеÄÖжÏÏß³ÌÊÇÖ¸ÖØÁ¿¼¶ÖжÏÏ̡߳£ ÕâÑù³ÆºôËüÃǵÄÔÒòÔÚÓÚ£¬ תµ½ÖжÏÏß³ÌÐèÒªÖ´ÐÐÒ»´ÎÍêÕûµÄÉÏÏÂÎÄÇл»²Ù×÷¡£ ÔÚ×î³õµÄʵÏÖÖУ¬ Äں˲»ÔÊÐíÇÀÕ¼£¬ Òò´ËÖжÏÔÚ´ò¶ÏÄÚºËÏß³Ì֮ǰ£¬ ±ØÐëµÈ´ýÄÚºËÏß³Ì×èÈû»ò·µ»ØÓû§Ì¬Ö®ºó²ÅÄÜÖ´ÐС£
¡¡¡¡ÎªÁ˽â¾öÏìӦʱ¼äÎÊÌ⣬ FreeBSD ÄÚºËÏÖÔÚ²ÉÓÃÁËÇÀռʽµ÷¶È²ßÂÔ¡£ Ŀǰ£¬ Ö»ÓÐÊÍ·ÅÐÝÃß mutex »ò·¢ÉúÖжÏʱ²ÅÄÜÇÀ¶ÏÄÚºËỊ̈߳¬ µ«×îÖÕÄ¿±êÊÇÔÚ FreeBSD ÉÏʵÏÖÏÂÃæËùÃèÊöµÄÈ«ÇÀռʽµ÷¶È²ßÂÔ¡£
¡¡¡¡²¢·ÇËùÓеÄÖжϴ¦Àí³ÌÐò¶¼ÔÚ¶ÀÁ¢µÄÏß³ÌÉÏÏÂÎÄÖÐÖ´ÐС£ Ïà·´£¬
ijЩ´¦Àí³ÌÐò»áÖ±½ÓÔÚÖ÷ÖжÏÉÏÏÂÎÄÖÐÖ´ÐС£ ÕâЩÖжϴ¦Àí³ÌÐò£¬ ÏÖÔÚ±»´íÎóµØÃüÃûΪ ¡°¿ìËÙ¡±
Öжϴ¦Àí³ÌÐò£¬ ÒòΪÔçÆÚ°æ±¾µÄÄÚºËÖÐʹÓÃÁË INTR_FAST
±êÖ¾À´±ê¼ÇÕâЩ´¦Àí³ÌÐò¡£ ĿǰֻÓÐʱÖÓÖжϺʹ®¿Ú I/O É豸ÖжϲÉÓÃÕâÒ»ÀàÐÍ¡£
ÓÉÓÚÕâЩ´¦Àí³ÌÐòûÓжÀÁ¢µÄÉÏÏÂÎÄ£¬ Òò¶øËüÃǶ¼²»ÄÜ»ñµÃ×èÈûÐÔËø£¬ Òò´ËÒ²¾ÍÖ»ÄÜʹÓÃ×ÔÐý
mutex¡£
¡¡¡¡×îºó£¬ »¹ÓÐÒ»ÖÖ³ÆÎªÇáÁ¿¼¶ÉÏÏÂÎÄÇл»µÄÓÅ»¯£¬ ¿ÉÒÔÔÚ MD ´úÂëÖÐʹÓᣠÒòΪÖжÏÏ̶߳¼ÊÇÔÚÄÚºËÉÏÏÂÎÄÖÐÖ´Ðеģ¬ ËùÒÔËü¿ÉÒÔ½èÓÃÈÎÒâ½ø³ÌµÄ vmspace (ÐéÄâÄÚ´æµØÖ·¿Õ¼ä)¡£ Òò´Ë£¬ ÔÚÇáÁ¿¼¶ÉÏÏÂÎÄÇл»ÖУ¬ Çл»µ½ÖжÏÏ̲߳¢²»Çл»¶ÔÓ¦µÄ vmspace£¬ ¶øÊǽèÓñ»ÖжÏÏß³ÌµÄ vmspace¡£ Ϊȷ±£±»ÖжÏÏß³ÌµÄ vmspace ²»ÔÚÖжϴ¦Àí¹ý³ÌÖÐÏûʧ£¬ ±»ÖжÏÏß³ÌÔÚÖжÏÏ̲߳»ÔÙ½èÓÃÆä vmspace ֮ǰÊDz»ÔÊÐíÖ´Ðеġ£ ¸Õ²ÅÌáµ½µÄÇé¿ö¿ÉÄÜÔÚÖжÏÏß³Ì×èÈû»òÍê³Éʱ·¢Éú¡£ Èç¹ûÖжÏÏ̷߳¢Éú×èÈû£¬ ÔòËüÔٴνøÈë¿ÉÔËÐÐ״̬ʱ½«Ê¹ÓÃ×Ô¼ºµÄÉÏÏÂÎÄ£¬ ÕâÑùÒ»À´£¬ ¾Í¿ÉÒÔÊͷű»ÖжϵÄÏß³ÌÁË¡£
¡¡¡¡ÕâÖÖÓÅ»¯µÄ»µ´¦ÔÚÓÚËüÃǺÍÓ²¼þ½ôÃÜÏà¹Ø£¬ ¶øÇÒʵÏֱȽϸ´ÔÓ£¬ Òò´ËÖ»ÓÐÔÚÕâÑù×öÄÜ´øÀ´´ó·ùÐÔÄܸÄÉÆÊ±²ÅÓ¦²ÉÓᣠĿǰÕâÑù˵¿ÉÄÜ»¹ÎªÊ±¹ýÔ磬 ¶øÇÒÊÂʵÉÏ¿ÉÄܻᷴ¶øµ¼ÖÂÐÔÄÜϽµ£¬ ÒòΪ¼¸ºõËùÓеÄÖжϴ¦Àí³ÌÐò¶¼»áÁ¢¼´±»È«¾ÖËø (Giant) ×èÈû£¬ ¶øÕâÖÖ×èÈû½«½ø¶øÐèÒªÏß³ÌÐÞÕý¡£ ÁíÍ⣬ Mike Smith ÌáÒé²ÉÓÃÁíÒ»ÖÖ·½Ê½À´´¦ÀíÖжÏỊ̈߳º
ÿ¸öÖжϴ¦Àí³ÌÐò·ÖΪÁ½²¿·Ö£¬ Ò»¸öÔÚÖ÷ÖжÏÉÏÏÂÎÄÖÐÔËÐеÄÖ÷Ìå (predicate) ºÍÒ»¸öÔÚ×Ô¼ºµÄÏß³ÌÉÏÏÂÎÄÖÐÖ´ÐеĴ¦Àí³ÌÐò (handler)¡£
Èç¹ûÖжϴ¦Àí³ÌÐòÓµÓÐÖ÷Ì壬 Ôòµ±´¥·¢ÖжÏʱ£¬ Ö´ÐиÃÖ÷Ìå¡£ Èç¹ûÖ÷Ìå·µ»ØÕ棬 ÔòÈÏΪ¸ÃÖжϱ»´¦ÀíÍê±Ï£¬ Äں˴ÓÖжϷµ»Ø¡£ Èç¹ûÖ÷Ìå·µ»Ø¼Ù£¬ »òÕßÖжÏûÓÐÖ÷Ì壬 Ôòµ÷¶ÈÔËÐÐÏß³Ìʽ´¦Àí³ÌÐò¡£
¡¡¡¡ÔÚÕâһģʽÖÐÊʵ±µØ²ÉÓÃÇáÁ¿¼¶ÉÏÏÂÎÄÇл»¿ÉÄÜÊǷdz£¸´Ôӵġ£ ÒòΪÎÒÃÇ¿ÉÄÜ»áÏ£ÍûÔÚδÀ´¸Ä±äÕâһģʽ£¬ Òò´ËÏÖÔÚ×îºÃµÄ·½°¸£¬ Ó¦¸ÃÊÇÔÝÊ±ÍÆ³ÙÔÚÇáÁ¿¼¶ÉÏÏÂÎÄÇл»Ö®ÉϵŤ×÷£¬ ÒÔ±ã½øÒ»²½ÍêÉÆÖжϴ¦Àí¼Ü¹¹£¬ ËæºóÔÙ¿¼²ìÇáÁ¿¼¶ÉÏÏÂÎÄÇл»ÊÇ·ñÊÊÓá£
¡¡¡¡ÄÚºËÇÀÕ¼µÄ¸ÅÄîºÜ¼òµ¥£¬ Æä»ù±¾Ë¼ÏëÊÇ CPU ×ÜÓ¦Ö´ÐÐÓÅÏȼ¶×î¸ßµÄ¹¤×÷¡£ µ±È»£¬ ÖÁÉÙÔÚÀíÏëÇé¿öÏÂÊÇÕâÑù¡£ ÓÐЩʱºò£¬ ´ï³ÉÕâÒ»ÀíÏëµÄ´ú¼Û»áÊ®·Ö¸ß°º£¬ ÒÔÖÁÓÚÔÚÕâЩÇé¿öÏÂÇÀÕ¼»áµÃ²»³¥Ê§¡£
¡¡¡¡ÊµÏÖÍêÈ«µÄÄÚºËÇÀռʮ·Ö¼òµ¥£º ÔÚµ÷¶È½«ÒªÖ´ÐеÄÏ̲߳¢·ÅÈëÔËÐжÓÁÐʱ£¬ ¼ì²éËüµÄÓÅÏȼ¶ÊÇ·ñ¸ßÓÚĿǰÕýÔÚÖ´ÐеÄÏ̡߳£ Èç¹ûÊÇÕâÑùµÄ»°£¬ Ö´ÐÐÒ»´ÎÉÏÏÂÎÄÇл»²¢Á¢¼´¿ªÊ¼Ö´ÐиÃÏ̡߳£
¡¡¡¡¾¡¹ÜËøÄܹ»ÔÚÇÀռʱ±£»¤¶àÊýÊý¾Ý£¬ µ«Äں˲¢²»ÊÇ¿ÉÒÔ°²È«µØ´¦´¦ÇÀÕ¼µÄ¡£ ÀýÈ磬
Èç¹û³ÖÓÐ×ÔÐý mutex µÄÏ̱߳»ÇÀÕ¼£¬ ¶øÐÂÏß³ÌÒ²³¢ÊÔ»ñµÃͬһ×ÔÐý mutex£¬
ÐÂÏ߳̾ͿÉÄÜÒ»Ö±×ÔÐýÏÂÈ¥£¬ ÒòΪ±»ÖжϵÄÏ߳̿ÉÄÜÓÀԶûÓлú»áÔËÐÐÁË¡£ ´ËÍ⣬ ijЩ´úÂ룬
ÀýÈçÔÚ Alpha É쵀 exec
¶Ô½ø³ÌµØÖ·¿Õ¼ä±àºÅ½øÐи³ÖµµÄ´úÂëÒ²²»Äܱ»ÇÀ¶Ï£¬ ÒòΪËü±»ÓÃÀ´Ö§³Öʵ¼ÊµÄÉÏÏÂÎÄÇл»²Ù×÷¡£
ÔÚÕâЩ´úÂë¶ÎÖУ¬ »áͨ¹ýʹÓÃÁÙ½çÇøÀ´ÁÙʱ½ûÓÃÇÀÕ¼¡£
¡¡¡¡ÁÙ½çÇø API µÄÔðÈÎÊDZÜÃâÔÚÁÙ½çÇøÄÚ·¢ÉúÉÏÏÂÎÄÇл»¡£ ¶ÔÓÚÍêÈ«ÇÀռʽÄں˶øÑÔ£¬
³ýÁ˵±Ç°Ïß³ÌÖ®ÍâµÄÆäËüÏ̵߳Äÿ¸ö setrunqueue
¶¼ÊÇÇÀ¶Ïµã¡£
critical_enter
µÄÒ»ÖÖʵÏÖ·½Ê½ÊÇÉèÖÃÒ»Ïß³Ì˽Óбê¼Ç£¬
²¢ÓÉÆä¶ÔÓ¦·½Çå³ý¡£ Èç¹ûµ÷Óà setrunqueue
ʱÉèÖÃÁËÕâ¸ö±êÖ¾£¬ ÔòÎÞÂÛÐÂÏ̺߳͵±Ç°Ïß³ÌÏà±ÈÆäÓÅÏȼ¶¸ßµÍ£¬ ¶¼²»»á·¢ÉúÇÀÕ¼¡£ È»¶ø£¬
ÓÉÓÚÁÙ½çÇø»áÔÚ×ÔÐý mutex ÖÐÓÃÓÚ±ÜÃâÉÏÏÂÎÄÇл»£¬ ¶øÇÒÄܹ»Í¬Ê±»ñµÃ¶à¸ö×ÔÐý mutex£¬
Òò´ËÁÙ½çÇø API ±ØÐëÖ§³ÖǶÌס£ ÓÉÓÚÕâ¸öÔÒò£¬ ĿǰµÄʵÏÖÖвÉÓÃÁËǶÌ×¼ÆÊý£¬
¶ø²»½ö½öÊǵ¥¸öµÄÏ̱߳êÖ¾¡£
¡¡¡¡ÎªÁ˾¡¿ÉÄÜËõ¶ÌÏìӦʱ¼ä£¬ ÔÚÁÙ½çÇøÖеÄÇÀÕ¼±»ÍƳ٣¬ ¶ø²»ÊÇÖ±½Ó¶ªÆú¡£ Èç¹ûÏß³ÌÓ¦±»ÇÀ¶Ï£¬ ²¢±»ÖÃΪ¿ÉÔËÐУ¬ ¶øµ±Ç°Ï̴߳¦ÓÚÁÙ½çÇø£¬ Ôò»áÉèÖÃÒ»Ïß³Ì˽ÓбêÖ¾£¬ ±íʾÓÐÒ»¸öÉÐδ½øÐеÄÇÀ¶Ï²Ù×÷¡£ µ±×îÍâ²ãÁÙ½çÇøÍ˳öʱ£¬ »á¼ì²éÕâÒ»±êÖ¾£¬ Èç¹ûËü±»ÖÃ룬 Ôòµ±Ç°Ï̻߳ᱻÇÀ¶Ï£¬ ÒÔÔÊÐí¸ü¸ßÓÅÏȼ¶µÄÏ߳̿ªÊ¼ÔËÐС£
¡¡¡¡ÖжϻáÒý·¢Ò»¸öºÍ×ÔÐý mutex ÓйصÄÎÊÌâ¡£ Èç¹ûµÍ¼¶Öжϴ¦Àí³ÌÐòÐèÒªËø£¬
Ëü¾Í²»ÄÜÖжÏÈκÎÐèÒª¸ÃËøµÄ´úÂ룬 ÒÔ±ÜÃâ¿ÉÄÜ·¢ÉúµÄËð»µÊý¾Ý½á¹¹µÄÇé¿ö¡£
Ŀǰ£¬ÕâÒ»»úÖÆÊÇ͸¹ýÁÙ½çÇø API ÒÔ cpu_critical_enter
ºÍ
cpu_critical_exit
º¯ÊýµÄÐÎʽʵÏֵġ£ ĿǰÕâÒ» API
»áÔÚËùÓÐ FreeBSD ËùÖ§³ÖµÄƽ̨ÉϽûÓúÍÖØÐÂÆôÓÃÖжϡ£ ÕâÖÖ·½·¨²¢²»ÊÇ×îÓŵģ¬
µ«Ëü¸üÒ×Àí½â£¬ Ò²¸üÈÝÒ×ÕýÈ·µØÊµÏÖ¡£ ÀíÂÛÉÏ£¬ ÕâÒ»¸¨Öú API
Ö»ÐèÒªÅäºÏÔÚÖ÷ÖжÏÉÏÏÂÎÄÖеÄ×ÔÐý mutex ʹÓᣠȻ¶ø£¬ ΪÁËÈôúÂë¸üΪ¼òµ¥£¬
Ëü±»ÓÃÔÚÁËÈ«²¿×ÔÐý mutex£¬ ÉõÖÁ°üÀ¨ËùÓÐÁÙ½çÇøÉÏ¡£ ½«Æä´Ó MI API ÖаþÀë³öÀ´·ÅÈë MD API£¬
²¢Ö»ÔÚÐèҪʹÓÃËüµÄ MI API µÄ×ÔÐý mutex ʵÏÖÖÐʹÓÿÉÄÜ»áÓиüºÃµÄЧ¹û¡£
Èç¹ûÎÒÃÇ×îÖÕ²ÉÓÃÁËÕâÖÖʵÏÖ·½Ê½£¬ Ôò MD API ¿ÉÄÜÐèÒª¸ÄÃû£¬ ÒÔÕÃÏÔÆäΪһµ¥¶À API
ÕâÒ»ÊÂʵ¡£
¡¡¡¡ÈçÇ°ÃæÌáµ½µÄ£¬ µ±ÍêÈ«ÇÀÕ¼²¢·Ç×ÜÄÜÌṩ×î¼ÑÐÔÄÜʱ£¬ ²ÉÈ¡ÁËһЩÕÛÖԵĴëÊ©¡£
¡¡¡¡µÚÒ»´¦ÕÛÖÔÊÇ£¬ ÇÀÕ¼´úÂë²¢²»¿¼ÂÇÆäËü CPU µÄ´æÔÚ¡£ ¼ÙÉèÎÒÃÇÓÐÁ½¸ö CPU£¬ A ºÍ B£¬ ÆäÖÐ A ÉÏÏ̵߳ÄÓÅÏȼ¶Îª 4£¬ ¶ø B ÉÏÏ̵߳ÄÓÅÏȼ¶ÊÇ 2¡£ Èç¹û CPU B ÁîÒ»ÓÅÏȼ¶Îª 1 µÄÏ߳̽øÈë¿ÉÔËÐÐ״̬£¬ ÔòÀíÂÛÉÏ£¬ ÎÒÃÇÏ£Íû CPU A Çл»ÖÁÕâÒ»ÐÂỊ̈߳¬ ÕâÑù¾ÍÓÐÁ½¸öÓÅÏȼ¶×î¸ßµÄÏß³ÌÔÚÔËÐÐÁË¡£ È»¶ø£¬ È·¶¨Äĸö CPU ÔÚÇÀռʱ¸üºÏÊÊ£¬ ²¢Í¨¹ý IPI ÏòÄǸö CPU ·¢³öÐźţ¬ ²¢Íê³ÉÏà¹ØµÄͬ²½¹¤×÷µÄ´ú¼ÛÊ®·Ö¸ß°º¡£ Òò´Ë£¬ ĿǰµÄ´úÂë»áÇ¿ÖÆ CPU B Çл»ÖÁ¸ü¸ßÓÅÏȼ¶µÄÏ̡߳£ Çë×¢ÒâÕâÑù×öÈÔ»áÈÃϵͳ½øÈë¸üºÃµÄ״̬£¬ ÒòΪ CPU B »áÈ¥Ö´ÐÐÓÅÏȼ¶Îª 1 ¶ø²»ÊÇ 2 µÄÄǸöÏ̡߳£
¡¡¡¡µÚ¶þ´¦ÕÛÖÔÊÇÏÞÖÆ¶ÔÓÚʵʱÓÅÏȼ¶µÄÄÚºËÏ̵߳ÄÁ¢¼´ÇÀÕ¼¡£ ÔÚÇ°ÃæËù¶¨ÒåµÄÇÀÕ¼²Ù×÷µÄ¼òµ¥ÇéÐÎÖУ¬ µÍÓÅÏȼ¶×ܻᱻÁ¢¼´ÇÀ¶Ï (»òÔÚÆäÍ˳öÁÙ½çÇøºó±»ÇÀ¶Ï)¡£ È»¶ø£¬ Ðí¶àÔÚÄÚºËÖÐÖ´ÐеÄỊ̈߳¬ ÓкܶàÖ»»áÖ´Ðк̵ܶÄʱ¼ä¾Í»á×èÈû»ò·µ»ØÓû§Ì¬¡£ Òò´Ë£¬ Èç¹ûÄÚºËÇÀ¶ÏÕâЩÏ̲߳¢Ö´ÐÐÆäËü·ÇʵʱµÄÄÚºËỊ̈߳¬ ÔòÄں˿ÉÄÜ»áÔÚÕâЩÏß³ÌÂíÉÏÒªÐÝÃß»òÖ´ÐÐÍê±Ï֮ǰÇл»³öÈ¥¡£ ÕâÑùÒ»À´£¬ CPU ¾Í±ØÐëµ÷Õû¿ìÈ¡»º´æÒÔÅäºÏÐÂÏ̵߳ÄÖ´ÐС£ µ±Äں˷µ»Øµ½±»ÇÀ¶ÏµÄÏß³Ìʱ£¬ ËüÓÖÐèÒªÖØÐÂÌî³ä֮ǰ¶ªÊ§µÄ¿ìÈ¡»º´æÐÅÏ¢¡£ ´ËÍ⣬ Èç¹ûÄÚºËÄܹ»½«¶Ô½«×èÈû»ò·µ»ØÓû§Ì¬µÄÄǸöÏ̵߳ÄÇÀ¶ÏÑÓ³Ùµ½ÕâÖ®ºóµÄ»°£¬ »¹Äܹ»ÃâÈ¥Á½´Î¶îÍâµÄÉÏÏÂÎÄÇл»¡£ Òò´Ë£¬ ĬÈÏÇé¿öÏ£¬ Ö»ÓÐÔÚÓÅÏȼ¶½Ï¸ßµÄÏß³ÌÊÇʵʱÏß³Ìʱ£¬ ÇÀÕ¼´úÂë²Å»áÁ¢¼´Ö´ÐÐÇÀ¶Ï²Ù×÷¡£
¡¡¡¡ÆôÓÃÕë¶ÔËùÓÐÄÚºËÏ̵߳ÄÍêÈ«ÇÀÕ¼¶ÔÓÚµ÷ÊԷdz£ÓаïÖú£¬ ÒòΪËü»á±©Â¶³ö¸ü¶àµÄ¾ºÌ¬Ìõ¼þ (race conditions)¡£ ÔÚÄÑÒÔÄ£ÄâÕâЩ¾ºÌ¬Ìõ¼þµÄµ¥´¦ÀíÆ÷ϵͳÖУ¬ ÕâÏÔµÃÓÈÆäÓÐÓᣠÒò´Ë£¬ ÎÒÃÇÌṩÁËÄÚºËÑ¡Ïî FULL_PREEMPTION À´ÆôÓÃÕë¶ÔËùÓÐÄÚºËÏ̵߳ÄÇÀÕ¼£¬ ÕâһѡÏîÖ÷ÒªÓÃÓÚµ÷ÊÔÄ¿µÄ¡£
¡¡¡¡¼òµ¥µØËµ£¬ Ï̴߳ÓÒ»¸ö CPU ÒÆ¶¯µ½ÁíÒ»¸öÉϵĹý³Ì³Æ×÷Ç¨ÒÆ¡£ ÔÚ·ÇÇÀռʽÄÚºËÖУ¬
ÕâÖ»»áÔÚÃ÷È·¶¨ÒåµÄµã£¬ ÀýÈçµ÷Óà msleep
»ò·µ»ØÖÁÓû§Ì¬Ê±²Å»á·¢Éú¡£ µ«ÊÇ£¬ ÔÚÇÀռʽÄÚºËÖУ¬ ÖжϿÉÄÜ»áÔÚÈκÎʱºòÇ¿ÖÆÇÀ¶Ï£¬
²¢µ¼ÖÂÇ¨ÒÆ¡£ ¶ÔÓÚ CPU ˽ÓеÄÊý¾Ý¶øÑÔÕâ¿ÉÄÜ»á´øÀ´Ò»Ð©¸ºÃæÓ°Ï죬 ÒòΪ³ý curthread
ºÍ curpcb
ÒÔÍâµÄÊý¾Ý¶¼¿ÉÄÜÔÚÇ¨ÒÆ¹ý³ÌÖз¢Éú±ä»¯¡£ ÓÉÓÚ´æÔÚDZÔÚµÄÏß³ÌÇ¨ÒÆ£¬ ʹµÃδÊܱ£»¤µÄ CPU
˽ÓÐÊý¾Ý·ÃÎʱäµÃÎÞÓᣠÕâ¾ÍÐèÒªÔÚijЩ´úÂë¶Î½ûÖ¹Ç¨ÒÆ£¬ ÒÔ»ñµÃÎȶ¨µÄ CPU ˽ÓÐÊý¾Ý¡£
¡¡¡¡Ä¿Ç°ÎÒÃDzÉÓÃÁÙ½çÇøÀ´±ÜÃâÇ¨ÒÆ£¬ ÒòΪËüÃÇÄܹ»×èÖ¹ÉÏÏÂÎÄÇл»¡£ µ«ÊÇ£¬ ÕâÓÐʱ¿ÉÄÜÊÇÒ»ÖÖ¹ýÓÚÑÏÀ÷µÄÏÞÖÆ£¬ ÒòΪÁÙ½çÇøÊµ¼ÊÉÏ»á×èÖ¹µ±Ç°´¦ÀíÆ÷ÉϵÄÖжÏÏ̡߳£ Òò¶ø£¬ ÌṩÁËÁíÒ»¸ö API£¬ ÓÃÒÔָʾµ±Ç°½ø³ÌÔÚ±»ÇÀ¶Ïʱ£¬ ²»Ó¦Ç¨ÒƵ½ÁíÒ» CPU¡£
¡¡¡¡Õâ×é API Ò²½ÐÏß³ÌÇ£ÖÆ£¬ ËüÓɵ÷¶ÈÆ÷Ìṩ¡£ Õâ×é API °üÀ¨Á½¸öº¯Êý£º sched_pin
ºÍ sched_unpin
¡£
ÕâÁ½¸öº¯ÊýÓÃÓÚ¹ÜÀíÏß³Ì˽ÓеļÆÊý td_pinned
¡£
Èç¹ûǶÌ×¼ÆÊý´óÓÚÁ㣬 ÔòÏ߳̽«±»Ëø×¡£¬ ¶øÏ߳̿ªÊ¼ÔËÐÐʱÆäǶÌ×¼ÆÊýΪÁ㣬
±íʾ´¦ÓÚÎ´Ç£ÖÆ×´Ì¬¡£ ËùÓеĵ÷¶ÈÆ÷ʵÏÖÖУ¬ ¶¼ÒªÇó±£Ö¤Ç£ÖÆÏß³ÌÖ»ÔÚËüÃÇÊ״ε÷ÓÃ
sched_pin
ʱËùÔÚµÄ CPU ÉÏÔËÐС£
ÓÉÓÚÖ»ÓÐÏß³Ì×Ô¼º»áдǶÌ×¼ÆÊý£¬ ¶øÖ»ÓÐÆäËüÏß³ÌÔÚÊÜÇ£ÖÆÏß³ÌûÓÐÖ´ÐУ¬ ÇÒ³ÖÓÐ sched_lock
ËøÊ±²Å»á¶ÁǶÌ×¼ÆÊý£¬ Òò´Ë·ÃÎÊ td_pinned
²»±ØÉÏËø¡£ sched_pin
º¯Êý»áʹǶÌ×¼ÆÊýµÝÔö£¬ ¶ø sched_unpin
ÔòʹÆäµÝ¼õ¡£ ×¢Ò⣬
ÕâЩº¯ÊýÖ»²Ù×÷µ±Ç°Ị̈߳¬ ²¢½«Æä°ó¶¨µ½ÆäÖ´ÐÐËüʱËù´¦µÄ CPU ÉÏ¡£ Òª½«ÈÎÒâḬ̈߳󶨵½Ö¸¶¨µÄ
CPU ÉÏ£¬ ÔòӦʹÓà sched_bind
ºÍ sched_unbind
¡£
¡¡¡¡Äں˻úÖÆ timeout
ÔÊÐíÄں˷þÎñ×¢²áº¯Êý£¬ ÒÔ×÷Ϊ
softclock
Èí¼þÖжϵÄÒ»²¿·ÖÀ´Ö´ÐС£
ʼþ½«»ùÓÚËùÏ£ÍûµÄʱÖÓàÖવÄÊýÄ¿½øÐУ¬ ²¢ÔÚ´óÔ¼Ö¸¶¨µÄʱ¼ä»Øµ÷Óû§ÌṩµÄº¯Êý¡£
¡¡¡¡Î´¾ö timeout (³¬Ê±) ʼþµÄÈ«¾Ö±íÊÇÓÉһȫ¾Ö mutex£¬ callout_lock
±£»¤µÄ£» ËùÓÐ¶Ô timeout ±íµÄ·ÃÎÊ£¬ ¶¼±ØÐëÊ×ÏÈÄõ½Õâ¸ö
mutex¡£ µ± softclock
»½ÐÑʱ£¬ Ëü»áɨÃèδ¾ö³¬Ê±±í£¬
²¢ÕÒ³öÓ¦Æô¶¯µÄÄÇЩ¡£ Ϊ±ÜÃâËøÄæÐò£¬ softclock
Ï̻߳áÔÚµ÷ÓÃËùÌṩµÄ timeout
»Øµ÷º¯ÊýʱÊ×ÏÈÊÍ·Å
callout_lock
mutex¡£ Èç¹ûÔÚ×¢²áʱûÓÐÉèÖà CALLOUT_MPSAFE
±êÖ¾£¬ ÔòÔÚµ÷Óõ÷³öº¯Êý֮ǰ£¬ »¹»áץȡȫ¾ÖËø£¬
²¢ÔÚÖ®ºóÊÍ·Å¡£ Æäºó£¬ callout_lock
mutex
»áÔÚ¼ÌÐø´¦ÀíǰÔٴλñµÃ¡£ softclock
´úÂëÔÚÊÍ·ÅÕâ¸ö mutex
ʱ»á·Ç³£Ð¡Ðĵر£³Ö±íµÄÒ»ÖÂ״̬¡£ Èç¹ûÆôÓÃÁË DIAGNOSTIC
£¬
Ôòÿ¸öº¯ÊýµÄÖ´ÐÐʱ¼ä»á±»¼Ç¼£¬ Èç¹û³¬¹ýÁËijһãÐÖµ£¬ Ôò»á²úÉú¾¯¸æ¡£
¡¡¡¡struct ucred
ÊÇÄÚºËÄÚ²¿µÄƾ¾Ý½á¹¹Ì壬
Ëüͨ³£×÷ΪÄÚºËÖÐÒÔ½ø³ÌΪµ¼ÏòµÄ·ÃÎÊ¿ØÖƵÄÒÀ¾Ý¡£ BSD-ÅÉÉúµÄϵͳ²ÉÓÃÒ»ÖÖ ¡°Ð´Ê±¸´ÖÆ¡±
µÄÄ£ÐÍÀ´´¦ÀíÆ¾¾ÝÊý¾Ý£º ͬһƾ¾Ý½á¹¹Ìå¿ÉÄÜ´æÔÚ¶à¸öÒýÓ㬠Èç¹ûÐèÒª¶ÔÆä½øÐÐÐ޸ģ¬
ÔòÕâ¸ö½á¹¹Ì彫±»¸´ÖÆ¡¢ Ð޸ģ¬ È»ºóÌæ»»¸ÃÒýÓá£
ÓÉÓÚÔÚ´ò¿ªÊ±ÓÃÓÚʵÏÖ·ÃÎÊ¿ØÖÆµÄÆ¾¾Ý¿ìÈ¡»º´æ¹ã·º´æÔÚ£¬ ÕâÖÖ×ö·¨»á¼«´óµØ½ÚÊ¡ÄÚ´æ¡£
ÔÚÇ¨ÒÆµ½Ï¸Á£¶ÈµÄ SMP ʱ£¬ ÕâһģÐÍҲʡȥÁË´óÁ¿µÄËø²Ù×÷£¬
ÒòΪֻÓÐδ¹²ÏíµÄƾ¾Ý²ÅÄÜʵʩÐ޸ģ¬ Òò¶ø±ÜÃâÁËÔÚʹÓù²ÏíÆ¾¾Ýʱ¶îÍâµÄͬ²½²Ù×÷¡£
¡¡¡¡Æ¾¾Ý½á¹¹ÌåÖ»ÓÐÒ»¸öÒýÓÃʱ£¬ ±»ÈÏΪÊǿɱäµÄ£» ²»ÔÊÐí¸Ä±ä¹²ÏíµÄƾ¾Ý½á¹¹Ì壬
·ñÔò½«¿ÉÄܵ¼Ö·¢Éú¾ºÌ¬Ìõ¼þ¡£ cr_mtxp
mutex ÓÃÓÚ±£»¤
struct ucred
µÄÒýÓüÆÊý£¬ ÒÔά»¤ÆäÒ»ÖÂÐÔ¡£
ʹÓÃÆ¾¾Ý½á¹¹Ìåʱ£¬ ±ØÐëÔÚʹÓùý³ÌÖб£³ÖÓÐЧµÄÒýÓã¬
·ñÔòËü¾Í¿ÉÄÜÔÚÕâ¸ö²»ºÏÀíµÄÏû·ÑÕßʹÓùý³ÌÖб»ÊÍ·Å¡£
¡¡¡¡struct ucred
mutex ÊÇÒ»ÖÖÒ¶ mutex£¬
³öÓÚÐÔÄÜ¿¼ÂÇ£¬ Ëüͨ¹ý mutex ³ØÊµÏÖ¡£
¡¡¡¡ÓÉÓÚ¶àÓÃÓÚ·ÃÎÊ¿ØÖƾö²ß£¬ ƾ¾Ýͨ³£Çé¿öÏÂÊÇÒÔÖ»¶Á·½Ê½·ÃÎʵģ¬ ´Ëʱһ°ãӦʹÓÃ
td_ucred
£¬ ÒòΪËü²»ÐèÒªÉÏËø¡£ µ±¸üнø³Ìƾ¾Ýʱ£¬
¼ì²éºÍ¸üйý³ÌÖбØÐë³ÖÓÐ proc Ëø¡£ ¼ì²éºÍ¸üвÙ×÷±ØÐëʹÓÃ
p_ucred
£¬ ÒÔ±ÜÃâ¼ì²éʱºÍʹÓÃʱµÄ¾ºÌ¬Ìõ¼þ¡£
¡¡¡¡Èç¹ûËùµ÷ϵͳµ÷Óý«ÔÚ¸üнø³Ìƾ¾ÝÖ®ºó½øÐзÃÎÊ¿ØÖƼì²é£¬ Ôò td_ucred
Ò²±ØÐëË¢ÐÂΪµ±Ç°½ø³ÌµÄÖµ¡£
ÕâÑù×öÄܹ»±ÜÃâÐ޸ĺóʹÓùýʱµÄƾ¾Ý¡£ Äں˻á×Ô¶¯ÔÚ½ø³Ì½øÈëÄÚºËʱ£¬ ½«Ï߳̽ṹÌåµÄ
td_ucred
Ö¸ÕëË¢ÐÂΪ½ø³ÌµÄ p_ucred
£¬ ÒÔ±£Ö¤Äں˷ÃÎÊ¿ØÖÆÄÜÓõ½ÐÂµÄÆ¾¾Ý¡£
¡¡¡¡struct prison
±£´æÁËÓÃÓÚά»¤ÄÇЩͨ¹ý jail(2) API ´´½¨µÄ jail
ËùÓõ½µÄ¹ÜÀíÐÅÏ¢¡£ Õâ°üÀ¨ jail µÄÖ÷»úÃû¡¢ IP µØÖ·£¬ ÒÔ¼°Ò»Ð©Ïà¹ØµÄÉèÖá£
Õâ¸ö½á¹¹Ìå°üº¬ÒýÓüÆÊý£¬ ÒòΪָÏòÕâÒ»½á¹¹ÌåʵÀýµÄÖ¸Õë»áÔÚ¶àÖÖÆ¾¾Ý½á¹¹Ö®¼ä¹²Ïí¡£
ÓÃÁËÒ»¸ö mutex£¬ pr_mtx
À´±£»¤¶ÔÒýÓüÆÊýÒÔ¼°ËùÓÐ jail
½á¹¹ÌåÖпɱä±äÁ¿µÄ¶Áд·ÃÎÊ¡£ ÓÐһЩ±äÁ¿Ö»»áÔÚ´´½¨ jail µÄʱ¿Ì·¢Éú±ä»¯£¬ Ö»Ðè³ÖÓÐÓÐЧµÄ
struct prison
¾Í¿ÉÒÔ¿ªÊ¼¶ÁÕâЩֵÁË¡£
¹ØÓÚÿ¸öÏîÄ¿¾ßÌåµÄÉÏËø²Ù×÷µÄÎĵµ£¬ ¿ÉÒÔÔÚ sys/jail.h
µÄ×¢ÊÍÖÐÕÒµ½¡£
¡¡¡¡TrustedBSD MAC ¿ò¼Ü»áÒÔ struct label
µÄÐÎʽά»¤Ò»ÏµÁÐÄں˶ÔÏóµÄÊý¾Ý¡£ Ò»°ãÀ´Ëµ£¬ ÄÚºËÖÐµÄ label (±êÇ©)
ÊÇÓÉÓëÆä¶ÔÓ¦µÄÄں˶ÔÏóͬÑùµÄËø±£»¤µÄ¡£ ÀýÈ磬 struct
vnode
É쵀 v_label
±êÇ©ÊÇÓÉÆäËùÔÚ vnode ÉϵÄ
vnode Ëø±£»¤µÄ¡£
¡¡¡¡³ýÁËǶÈëµ½±ê×¼Äں˶ÔÏóÖеıêǩ֮Í⣬ MAC
¿ò¼ÜÒ²ÐèҪά»¤Ò»×é°üº¬ÒÑ×¢²áµÄºÍ¼¤»î²ßÂÔµÄÁÐ±í¡£ ²ßÂÔ±íºÍæ¼ÆÊýÓÉÒ»¸öÈ«¾Ö mutex
(mac_policy_list_lock
) ±£»¤¡£
ÓÉÓÚÄܹ»Í¬Ê±²¢ÐеؽøÐÐÐí¶à·ÃÎÊ¿ØÖƼì²é£¬ ¶Ô²ßÂÔ±íµÄÖ»¶Á·ÃÎÊ£¬ ÔÚÔö¼õæ¼ÆÊýʱ£¬
¿ò¼ÜµÄÈë¿Ú´¦ÐèÒªÊ×ÏȳÖÓÐÕâ¸ö mutex¡£ MAC Èë¿Ú²Ù×÷µÄ¹ý³ÌÖв¢²»ÐèÒª³¤Ê±¼ä³ÖÓÐ´Ë mutex --
ÓÐЩ²Ù×÷£¬ ÀýÈçÎļþϵͳ¶ÔÏóÉϵıêÇ©²Ù×÷ -- Êdz־õġ£ ÒªÐ޸IJßÂÔ±í£¬
ÀýÈçÔÚ×¢²áºÍ½â³ý×¢²á²ßÂÔʱ£¬ ÐèÒª³ÖÓÐ´Ë mutex£¬ ¶øÇÒÒªÇóÒýÓüÆÊýΪÁ㣬
ÒÔ±ÜÃâÔÚÓñíʱ¶ÔÆä½øÐÐÐ޸ġ£
¡¡¡¡¶ÔÓÚÐèÒªµÈ´ý±í½øÈëÏÐÖÃ״̬µÄỊ̈߳¬ ÌṩÁËÒ»¸öÌõ¼þ±äÁ¿ mac_policy_list_not_busy
£¬
µ«ÕâÒ»Ìõ¼þ±äÁ¿Ö»ÄÜÔÚµ÷ÓÃÕßûÓгÖÓÐÆäËüËøÊ±²ÅÄÜʹÓ㬠·ñÔò¿ÉÄÜ»áÒý·¢ËøÄæÐòÎÊÌâ¡£
æ¼ÆÊýÔÚÕû¸ö¿ò¼ÜÖÐÊÂʵÉÏ»¹°çÑÝÁËijÖÖÐÎʽµÄ ¹²Ïí/ÅÅËû ËøµÄ×÷Ó㺠Óë sx Ëø²»Í¬µÄµØ·½ÔÚÓÚ£¬
µÈ´ýÁÐ±í½øÈëÏÐÖÃ״̬µÄÏ߳̿ÉÒÔ¶öËÀ£¬ ¶ø²»ÊÇÔÊÐíæ¼ÆÊýºÍÆäËüÔÚ MAC ¿ò¼ÜÈë¿Ú (»òÄÚ²¿)
µÄËøÖ®¼äµÄÄæÐòÇé¿ö¡£
¡¡¡¡¶ÔÓÚÄ£¿é×Óϵͳ£¬ ÓÃÓÚ±£»¤¹²ÏíÊý¾ÝʹÓÃÁËÒ»¸öµ¥¶ÀµÄËø£¬ ËüÊÇÒ»¸ö ¹²Ïí/ÅÅËû (SX)
Ëø£¬ Ðí¶àÇé¿öÐèÒª»ñµÃËü (ÒÔ¹²Ïí»òÅÅËûµÄ·½Ê½)£¬
Òò´ËÎÒÃÇÌṩÁ˼¸¸ö·½±ãʹÓõĺêÀ´¼ò»¯¶ÔÕâ¸öËøµÄ·ÃÎÊ£¬ ÕâЩºê¿ÉÒÔÔÚ sys/module.h ÖÐÕÒµ½£¬ ÆäÓ÷¨¶¼·Ç³£¼òµ¥Ã÷ÁË¡£ Õâ¸öËø±£»¤µÄÖ÷ÒªÊÇ
module_t
(µ±ÒÔ¹²Ïí·½Ê½ÉÏËø) ºÍÈ«¾ÖµÄ modulelist_t
ÕâÁ½¸ö½á¹¹Ì壬 ÒÔ¼°Ä£¿é¡£ Òª¸ü½øÒ»²½Àí½âÕâÐ©Ëø²ßÂÔ£¬
ÐèÒª×ÐϸÔĶÁ kern/kern_module.c µÄÔ´´úÂë¡£
¡¡¡¡newbus ϵͳʹÓÃÁËÒ»¸ö sx Ëø¡£ ¶ÁµÄÒ»·½Ó¦³ÖÓй²Ïí (¶Á) Ëø (sx_slock(9)) ¶øÐ´µÄÒ»·½ÔòÓ¦³ÖÓÐÅÅËû (д) Ëø (sx_xlock(9))¡£ ÄÚ²¿º¯ÊýÒ»°ã²»ÐèÒª½øÐÐÉÏËø£¬ ¶øÍⲿ¿É¼ûµÄÔòÓ¦¸ù¾ÝÐèÒªÉÏËø¡£ ÓÐЩÏîÄ¿²»ÐèÉÏËø£¬ ÒòΪÕâЩÏîÄ¿ÔÚÈ«³ÌÊÇÖ»¶ÁµÄ£¬ (ÀýÈç device_get_softc(9))£¬ Òò¶ø²¢²»»á²úÉú¾ºÌ¬Ìõ¼þ¡£ Õë¶Ô newbus Êý¾Ý½á¹¹µÄÐÞ¸ÄÏà¶Ô¶øÑԷdz£ÉÙ£¬ Òò´Ëµ¥¸öµÄËøÒѾ×㹻ʹÓ㬠¶ø²»ÖÂÔì³ÉÐÔÄÜÕÛËð¡£
¡¡¡¡- ½ø³Ì²ã´Î½á¹¹
¡¡¡¡- proc Ëø¼°Æä²Î¿¼
¡¡¡¡- ÔÚϵͳµ÷Óùý³ÌÖÐÏß³Ì˽ÓÐµÄ proc Ï±¾£¬ °üÀ¨ td_ucred
¡¡¡¡- ½ø³Ì¼ä²Ù×÷
¡¡¡¡- ½ø³Ì×éºÍ»á»°
¡¡¡¡select
ºÍ poll
ÕâÁ½¸öº¯ÊýÔÊÐíÏß³Ì×èÈû²¢µÈ´ýÎļþÃèÊö·ûÉϵÄʼþ --
×î³£¼ûµÄÇé¿öÊÇÎļþÃèÊö·ûÊÇ·ñ¿É¶Á»ò¿Éд¡£
¡¡¡¡...
¡¡¡¡SIGIO ·þÎñÔÊÐí½ø³ÌÇëÇóÔÚÌØ¶¨ÎļþÃèÊö·ûµÄ¶Á/д״̬·¢Éú±ä»¯Ê±£¬ ½« SIGIO
ÐźÅȺ·¢¸øÆä½ø³Ì×é¡£ ÈÎÒâ¸ø¶¨Äں˶ÔÏóÉÏ£¬ Ö»ÔÊÐíÒ»½ø³Ì»ò½ø³Ì×é×¢²á SIGIO£¬
Õâ¸ö½ø³Ì»ò½ø³Ì×é³ÆÎªÊôÖ÷ (owner)¡£ ÿһ֧³Ö SIGIO ×¢²áµÄ¶ÔÏó£¬ ¶¼°üº¬Ò»Ö¸Õë×ֶΣ¬
Èç¹û¶ÔÏóδע²áÔòΪ NULL
£¬ ·ñÔòÊÇÒ»Ö¸ÏòÃèÊöÕâÒ»×¢²áµÄ
struct sigio
µÄÖ¸Õë¡£ ÕâÒ»×Ö¶ÎÓÉһȫ¾Ö mutex£¬
sigio_lock
±£»¤¡£ µ÷Óà SIGIO ά»¤º¯Êýʱ£¬ ±ØÐëÒÔ
¡°´«ÒýÓá± ·½Ê½´«µÝÕâÒ»×ֶΣ¬ ÒÔÈ·±£±¾µØ×¢²á¸±±¾µÄÖÐÕâ¸ö×ֶβ»ÍÑÀëËøµÄ±£»¤¡£
¡¡¡¡Ã¿¸ö¹ØÁªµ½½ø³Ì»ò½ø³Ì×éµÄ×¢²á¶ÔÏó£¬ ¶¼»á·ÖÅäÒ» struct
sigio
½á¹¹£¬ ²¢°üÀ¨Ö¸»Ø¸Ã¶ÔÏóµÄÖ¸Õë¡¢ ÊôÖ÷¡¢ ÐźÅÐÅÏ¢¡¢ ƾ¾Ý£¬
ÒÔ¼°¹ØÓÚÕâÒ»×¢²áµÄÒ»°ãÐÅÏ¢¡£ ÿ¸ö½ø³Ì»ò½ø³Ì×é¶¼°üº¬Ò»¸öÒÑ×¢²á struct sigio
½á¹¹ÌåµÄÁÐ±í£¬ ¶Ô½ø³ÌÀ´ËµÊÇ p_sigiolst
£¬ ¶ø¶Ô½ø³Ì×éÔòÊÇ pg_sigiolst
¡£ ÕâЩ±íÓÉÏàÓ¦µÄ½ø³Ì»ò½ø³Ì×éËø±£»¤¡£ ³ýÁËÓÃÒÔ½«
struct sigio
Á¬½Óµ½½ø³Ì×éÉ쵀 sio_pgsigio
×Ö¶ÎÖ®Í⣬ ÔÚ struct
sigio
ÖеĶàÊý×Ö¶ÎÔÚ×¢²á¹ý³ÌÖж¼ÊDz»±äÁ¿¡£ Ò»°ã¶øÑÔ£¬ ¿ª·¢ÈËÔ±ÔÚʵÏÖеÄÖ§³Ö
SIGIO µÄÄں˶ÔÏóʱ£¬ »áÏ£Íû±ÜÃâÔÚµ÷Óà SIGIO Ö§³Öº¯Êý£¬ ÀýÈç fsetown
»ò funsetown
³ÖÓнṹÌåËø£¬
ÒÔÃâÈ¥ÐèÒªÔڽṹÌåËøºÍÈ«¾Ö SIGIO ËøÖ®¼ä¶¨ÒåËøÐò¡£
ͨ³£¿ÉÒÔͨ¹ýÌá¸ß½á¹¹ÌåÉϵÄÒýÓüÆÊýÀ´´ïµ½ÕâÑùµÄÄ¿µÄ£¬ ÀýÈ磬 ÔÚ½øÐйܵÀ²Ù×÷ʱ£¬
ʹÓÃÒýÓÃij¸ö¹ÜµÀµÄÎļþÃèÊö·ûÕâÑùµÄ²Ù×÷£¬ ¾Í¿ÉÒÔÕմ˰ìÀí¡£
¡¡¡¡sysctl
MIB ·þÎñ»á´ÓÄÚºËÄÚ²¿£¬
ÒÔ¼°Óû§Ì¬µÄÓ¦ÓóÌÐòÒÔϵͳµ÷Óõķ½Ê½´¥·¢¡£ Õâ»áÒý·¢ÖÁÉÙÁ½¸öºÍËøÓйصÄÎÊÌ⣺
ÆäÒ»ÊǶÔά³ÖÃüÃû¿Õ¼äµÄÊý¾Ý½á¹¹µÄ±£»¤£¬ Æä¶þÊÇÓëÄÇЩͨ¹ý sysctl
½Ó¿Ú·ÃÎʵÄÄں˱äÁ¿ºÍº¯ÊýÖ®¼äµÄ½»»¥¡£ ÓÉÓÚ sysctl ÔÊÐíÖ±½Óµ¼³ö (ÉõÖÁÐÞ¸Ä)
ÄÚºËͳ¼ÆÊý¾ÝÒÔ¼°ÅäÖòÎÊý£¬ sysctl »úÖÆ±ØÐëÖªµÀÕâЩ±äÁ¿ÏàÓ¦µÄÉÏËøÓïÒå¡£ Ŀǰ£¬ sysctl
ʹÓÃÒ»¸öÈ«¾Ö sx ËøÀ´ÊµÏÖ¶Ô sysctl
²Ù×÷µÄ´®Ðл¯£» È»¶ø£¬
ÕâЩÊǼٶ¨ÓÃÈ«¾ÖËø±£»¤µÄ£¬ ²¢ÇÒûÓÐÌṩÆäËü±£»¤»úÖÆ¡£ ÕâÒ»½ÚµÄÆäÓಿ·Ö½«Ïêϸ½éÉÜÉÏËøºÍ
sysctl Ïà¹Ø±ä¶¯µÄÓïÒå¡£
¡¡¡¡- ÐèÒª½« sysctl ¸üÐÂÖµËù½øÐеIJÙ×÷µÄ˳Ðò£¬ ´ÓÔÏȵĶÁ¾ÉÖµ¡¢ copyin ºÍ copyout¡¢ дÐÂÖµ£¬ ¸ÄΪ copyin¡¢ ÉÏËø¡¢ ¶Á¾ÉÖµ¡¢ дÐÂÖµ¡¢ ½âËø¡¢ copyout¡£ Ò»°ãµÄ sysctl Ö»ÊÇ copyout ¾ÉÖµ²¢ÉèÖÃËüÃÇ copyin ËùµÃµ½µÄÐÂÖµ£¬ ÈÔÈ»¿ÉÒÔ²ÉÓþÉʽµÄÄ£ÐÍ¡£ È»¶ø£¬ ¶ÔËùÓÐ sysctl ´¦Àí³ÌÐò²ÉÓõڶþÖÖÄ£ÐͲ¢±ÜÃâËø²Ù×÷·½Ã棬 µÚ¶þÖÖ·½Ê½¿ÉÄܸü¹æ¾ØÒ»Ð©¡£
¡¡¡¡- ¶ÔÓÚͨ³£µÄÇé¿ö£¬ sysctl ¿ÉÒÔÄÚǶһ¸ö mutex Ö¸Õëµ½ SYSCTL_FOO ºêºÍ½á¹¹ÌåÖС£ Õâ¶Ô¶àÊý sysctl ¶¼ÊÇÓÐЧµÄ¡£ ¶ÔÓÚʹÓà sx Ëø¡¢ ×ÔÐý mutex£¬ »òÆäËü³ýµ¥Ò»ÐÝÃß mutex Ö®ÍâµÄËø²ßÂÔ£¬ ¿ÉÒÔÓà SYSCTL_PROC ½ÚµãÀ´Íê³ÉÕýÈ·µÄÉÏËø¡£
¡¡¡¡ÈÎÎñ¶ÓÁÐ (taskqueue) µÄ½Ó¿Ú°üÀ¨Á½¸öÓëÖ®¹ØÁªµÄÓÃÓÚ±£»¤Ïà¹ØÊý¾ÝµÄËø¡£ taskqueue_queues_mutex
ÊÇÓÃÓÚ±£»¤ taskqueue_queues
TAILQ µÄËø¡£ ÓëÕâ¸öϵͳ¹ØÁªµÄÁíÒ»¸ö mutex ËøÊÇλÓÚ
struct taskqueue
½á¹¹ÌåÉÏ¡£
ÔÚ´Ë´¦Ê¹ÓÃͬ²½ÔÓïµÄÄ¿µÄÔÚÓÚ±£»¤ struct taskqueue
ÖÐÊý¾ÝµÄÍêÕûÐÔ¡£ ӦעÒâµÄÊÇ£¬ ²¢Ã»Óе¥¶ÀµÄ¡¢ °ïÖúÓû§¶ÔÆä×ÔÉíµÄ¹¤×÷½øÐÐËøµÄϸ»¯Óõĺ꣬
ÒòΪÕâÐ©Ëø»ù±¾Éϲ»»áÔÚ kern/subr_taskqueue.c
ÒÔÍâµÄµØ·½Óõ½¡£
¡¡¡¡ÐÝÃß¶ÓÁÐÊÇÒ»ÖÖÓÃÓÚ±£´æÍ¬´¦Ò»¸öµÈ´ýͨµÀ (wait channel) ÉÏÐÝÃßÏß³ÌÁбíµÄÊý¾Ý½á¹¹¡£ ÔڵȴýͨµÀÉÏ£¬ ÿ¸ö´¦ÓÚ·Ç˯Ãß״̬µÄÏ̶߳¼»áЯ´øÒ»¸öÐÝÃß¶ÓÁнṹ¡£ µ±Ïß³ÌÔڵȴýͨµÀÉÏ·¢Éú×èÈûʱ£¬ Ëü»á½«ÐÝÃß¶ÓÁнṹÌåË͸øÄǸöµÈ´ýͨµÀ¡£ ÓëµÈ´ýͨµÀ¹ØÁªµÄÐÝÃß¶ÓÁÐÔò±£´æÔÚÒ»¸öÉ¢ÁбíÖС£
¡¡¡¡ÐÝÃß¶ÓÁÐÉ¢ÁбíÖб£´æÁ˰üº¬ÖÁÉÙÒ»¸ö×èÈûÏ̵߳ĵȴýͨµÀÉϵÄÐÝÃß¶ÓÁС£ Õâ¸öÉ¢ÁбíÉϵÄÏî³Æ×÷ sleepqueue (ÐÝÃß¶ÓÁÐ) Á´¡£ Ëü°üº¬ÁËÒ»¸öÐÝÃß¶ÓÁеÄÁ´±í£¬ ÒÔ¼°Ò»¸ö×ÔÐý mutex¡£ ´Ë´¦µÄ×ÔÐý mutex ÓÃÓÚ±£»¤ÐÝÃß¶ÓÁÐ±í£¬ ÒÔ¼°ÆäÉÏÐÝÃß¶ÓÁнṹµÄÄÚÈÝ¡£ Ò»¸öµÈ´ýͨµÀÉÏÖ»»á¹ØÁªÒ»¸öÐÝÃß¶ÓÁС£ Èç¹ûÓжà¸öÏß³ÌÔÚͬһµÈ´ýͨµÀÉÏ×èÈû£¬ ÔòÐÝÃß¶ÓÁÐÖн«¹ØÁª³ýµÚÒ»¸öÏß³ÌÖ®ÍâµÄÈ«²¿Ï̡߳£ µ±´ÓÐÝÃß¶ÓÁÐÖÐɾ³ýÏß³Ìʱ£¬ Èç¹ûËü²»ÊÇΨһµÄ×èÈûµÄÐÝÃßỊ̈߳¬ Ôò»á»ñµÃÖ÷ÐÝÃß¶ÓÁеĿÕÏбíÉϵÄÐÝÃß¶ÓÁнṹ¡£ ×îºóÒ»¸öÏ̻߳áÔÚ»Ö¸´ÔËÐÐʱ»ñµÃÖ÷ÐÝÃß¶ÓÁС£ ÓÉÓÚÏß³ÌÓпÉÄÜÒԺͼÓÈëÐÝÃß¶ÓÁв»Í¬µÄ´ÎÐò´ÓÆäÖÐɾ³ý£¬ Òò´Ë£¬ Ïß³ÌÀ뿪¶ÓÁÐʱ¿ÉÄÜ»áЯ´øÓëÆä½øÈëʱ²»Í¬µÄÐÝÃß¶ÓÁС£
¡¡¡¡sleepq_lock
º¯Êý»áËø×¡Ö¸¶¨µÈ´ýͨµÀÉÏÐÝÃß¶ÓÁÐÁ´µÄ×ÔÐý
mutex¡£ sleepq_lookup
º¯Êý»áÔÚÖ÷ÐÝÃß¶ÓÁÐÉ¢ÁбíÖвéÕÒ¸ø¶¨µÄµÈ´ýͨµÀ¡£ Èç¹ûûÓÐÕÒµ½Ö÷ÐÝÃß¶ÓÁУ¬ Ëü»á·µ»Ø
NULL
¡£ sleepq_release
º¯Êý»á¶Ô¸ø¶¨µÈ´ýͨµÀËù¹ØÁªµÄ×ÔÐý mutex ½øÐнâËø¡£
¡¡¡¡½«Ï̼߳ÓÈëÐÝÃß¶ÓÁÐÊÇͨ¹ý sleepq_add
À´Íê³ÉµÄ¡£
Õâ¸öº¯ÊýµÄ²ÎÊý°üÀ¨µÈ´ýͨµÀ¡¢ Ö¸Ïò±£»¤µÈ´ýͨµÀµÄ mutex µÄÖ¸Õë¡¢ µÈ´ýÏûÏ¢ÃèÊö´®£¬
ÒÔ¼°Ò»¸ö±êÖ¾ÑÚÂë¡£ µ÷Óô˺¯Êý֮ǰ£¬ Ӧͨ¹ý sleepq_lock
ΪÐÝÃß¶ÓÁÐÁ´ÉÏËø¡£ Èç¹ûµÈ´ýͨµÀ²»ÊÇͨ¹ý mutex ±£»¤µÄ (»òÕßËüÓÉÈ«¾ÖËø±£»¤)£¬ ÔòÓ¦½«
mutex Ö¸ÕëÉèÖÃΪ NULL
¡£ ¶ø flags (±êÖ¾)
²ÎÊýÔò°üÀ¨ÁËÒ»¸öÀàÐÍ×ֶΣ¬ ÓÃÒÔ±íʾÏ̼߳´½«¼ÓÈëµ½µÄÐÝÃß¶ÓÁеÄÀàÐÍ£¬
ÒÔ¼°ÐÝÃßÊÇ·ñÊÇ¿ÉÖÐ¶ÏµÄ (SLEEPQ_INTERRUPTIBLE
)¡£
ĿǰֻÓÐÁ½ÖÖÀàÐ͵ÄÐÝÃß¶ÓÁУº ͨ¹ý msleep
ºÍ wakeup
º¯Êý¹ÜÀíµÄ´«Í³ÐÝÃß¶ÓÁÐ (SLEEPQ_MSLEEP
)£¬ ÒÔ¼°»ùÓÚÌõ¼þ±äÁ¿µÄÐÝÃß¶ÓÁÐ (SLEEPQ_CONDVAR
)¡£
ÐÝÃß¶ÓÁÐÀàÐͺÍËøÖ¸ÕëÕâÁ½¸ö²ÎÊýÍêÈ«ÊÇÓÃÓÚÄÚ²¿µÄ¶ÏÑÔ¼ì²é¡£ µ÷Óà sleepq_add
µÄ´úÂ룬 Ó¦Ã÷ʾµØÔÚ¹ØÁªµÄ sleepqueue Á´Í¸¹ý sleepq_lock
½øÐÐÉÏËøÖ®ºó£¬
²¢Ê¹Óõȴýº¯ÊýÔÚÐÝÃß¶ÓÁÐÉÏ×èÈû֮ǰ½âËøËùÓÐÓÃÓÚ±£»¤µÈ´ýͨµÀµÄ interlock¡£
¡¡¡¡Í¨¹ýʹÓà sleepq_set_timeout
¿ÉÒÔΪÐÝÃßÉèÖó¬Ê±¡£
Õâ¸öº¯ÊýµÄ²ÎÊý°üÀ¨µÈ´ýͨµÀ£¬ ÒÔ¼°ÒÔÏà¶ÔʱÖÓàÖàªÊýΪµ¥Î»µÄ³¬Ê±Ê±¼ä¡£
Èç¹ûÐÝÃßÓ¦±»Ä³¸öµ½À´µÄÐźŴò¶Ï£¬ Ôò»¹Ó¦µ÷Óà sleepq_catch_signals
º¯Êý£¬ Õâ¸öº¯ÊýΨһµÄ²ÎÊý¾ÍÊǵȴýͨµÀ¡£
Èç¹û´ËÏß³ÌÒѾÓÐδ¾öÐźţ¬ Ôò sleepq_catch_signals
½«·µ»ØÐźűàºÅ£» ÆäËüÇé¿öÏ£¬ Æä·µ»ØÖµÔòÊÇ 0¡£
¡¡¡¡Ò»µ©½«Ï̼߳ÓÈëµ½ÐÝÃß¶ÓÁÐÖУ¬ ¾Í¿ÉÒÔʹÓà sleepq_wait
º¯Êý×åÖ®Ò»½«Æä×èÈûÁË¡£ Ŀǰ×ܹ²ÌṩÁËËĸöµÈ´ýº¯Êý£¬
ʹÓÃÄĸöÈ¡¾öÓÚµ÷ÓÃÕâÊÇ·ñÏ£ÍûÔÊÐíʹÓó¬Ê±¡¢ ÊÕµ½Ðźţ¬ »òÓû§Ì¬Ï̵߳÷¶ÈÆ÷´ò¶ÏÐÝÃß״̬¡£
ÆäÖУ¬ sleepq_wait
º¯Êý¼òµ¥µØµÈ´ý£¬
Ö±µ½µ±Ç°Ïß³Ìͨ¹ýij¸ö»½ÐÑ (wakeup) º¯ÊýÏÔʽµØ»Ö¸´ÔËÐУ» sleepq_timedwait
º¯ÊýÔòµÈ´ý£¬ Ö±µ½µ±Ç°Ï̱߳»ÏÔʽµØ»½ÐÑ£¬
»òÕß´ïµ½ÔçǰʹÓà sleepq_set_timeout
ÉèÖõij¬Ê±£»
sleepq_wait_sig
º¯Êý»áµÈ´ýÏÔʽµØ»½ÐÑ£¬ »òÕ߯äÐÝÃß±»Öжϣ»
¶ø sleepq_timedwait_sig
º¯ÊýÔòµÈ´ýÏÔʽµØ»½ÐÑ¡¢ ´ïµ½ÓÃ
sleepq_set_timeout
ÉèÖõij¬Ê±£¬
»òÏ̵߳ÄÐÝÃß±»ÖжÏÕâÈýÖÖÌõ¼þÖ®Ò»¡£ ËùÓÐÕâЩµÈ´ýº¯ÊýµÄµÚÒ»¸ö²ÎÊý¶¼ÊǵȴýͨµÀ¡£
³ý´ËÖ®Í⣬ sleepq_timedwait_sig
µÄµÚ¶þ¸ö²ÎÊýÊÇÒ»¸ö²¼¶ûÖµ£¬ ±íʾ֮ǰµ÷Óà sleepq_catch_signals
ʱÊÇ·ñÓз¢ÏÖδ¾öÐźš£
¡¡¡¡Èç¹ûÏ̱߳»ÏÔʽµØ»Ö¸´ÔËÐУ¬ »òÆäÐÝÃß±»ÐźÅÖÕÖ¹£¬ ÔòµÈ´ýº¯Êý»á·µ»ØÁ㣬
±íʾÐÝÃ߳ɹ¦¡£ Èç¹ûÏ̵߳ÄÐÝÃß±»³¬Ê±»òÓû§Ì¬Ï̵߳÷¶ÈÆ÷´ò¶Ï£¬ Ôò»á·µ»ØÏàÓ¦µÄ errno ÊýÖµ¡£
ÐèҪעÒâµÄÊÇ£¬ ÒòΪ sleepq_wait
Ö»ÄÜ·µ»Ø 0£¬
Òò´Ëµ÷ÓÃÕß²»ÄÜÖ¸ÍûËü·µ»ØÊ²Ã´ÓÐÓÃÐÅÏ¢£¬ ¶øÓ¦¼Ù¶¨ËüÍê³ÉÁËÒ»´Î³É¹¦µÄÐÝÃß¡£ ͬʱ£¬
Èç¹ûÏ̵߳ÄÐÝÃßʱ¼ä³¬Ê±£¬ ²¢Í¬Ê±±»ÖÕÖ¹£¬ Ôò sleepq_timedwait_sig
½«·µ»ØÒ»¸ö±íʾ·¢Éú³¬Ê±µÄ´íÎó´úÂë¡£
Èç¹û·µ»Ø´íÎó´úÂëÊÇ 0 ¶øÇÒʹÓà sleepq_wait_sig
»ò
sleepq_timedwait_sig
À´Ö´ÐÐ×èÈû£¬ ÔòÓ¦µ÷Óà sleepq_calc_signal_retval
À´¼ì²éÊÇ·ñÓÐδ¾öÐźţ¬
²¢¾Ý´ËÑ¡ÔñºÏÊʵķµ»ØÖµ¡£ ½ÏÔçǰµ÷Óà sleepq_catch_signals
µÃµ½µÄÐźűàºÅ£¬ Ó¦×÷Ϊ²ÎÊý´«¸ø sleepq_calc_signal_retval
¡£
¡¡¡¡ÔÚͬһÐÝÃßͨµÀÉÏÐÝÃßµÄỊ̈߳¬ ¿ÉÒÔÓÉ sleepq_broadcast
»ò sleepq_signal
º¯ÊýÀ´ÏÔʽµØ»½ÐÑ¡£ ÕâÁ½¸öº¯ÊýµÄ²ÎÊý¾ù°üÀ¨Ï£Íû»½ÐѵĵȴýͨµÀ¡¢ ½«»½ÐÑÏ̵߳ÄÓÅÏȼ¶
(priority) Ìá¸ßµ½¶àÉÙ£¬ ÒÔ¼°Ò»¸ö±êÖ¾ (flags) ²ÎÊý±íʾ½«Òª»Ö¸´ÔËÐеÄÐÝÃß¶ÓÁÐÀàÐÍ¡£
ÓÅÏȼ¶²ÎÊý½«×÷Ϊ×îµÍÓÅÏȼ¶£¬ Èç¹û½«»Ö¸´µÄÏ̵߳ÄÓÅÏȼ¶±È´Ë²ÎÊý¸ü¸ß (ÊýÖµ¸üµÍ)
ÔòÆäÓÅÏȼ¶²»»áµ÷Õû¡£ ±êÖ¾²ÎÊýÖ÷ÒªÓÃÓÚº¯ÊýÄÚ²¿µÄ¶ÏÑÔ£¬
ÓÃÒÔÈ·ÈÏÐÝÃß¶ÓÁÐûÓб»µ±×ö´íÎóµÄÀàÐͶԴý¡£ ÀýÈ磬
Ìõ¼þ±äÁ¿º¯Êý²»Ó¦»Ö¸´´«Í³ÐÝÃß¶ÓÁеÄÖ´ÐС£ sleepq_broadcast
º¯Êý½«»Ö¸´ËùÓÐÖ¸¶¨ÐÝÃßͨµÀÉϵÄ×èÈûỊ̈߳¬ ¶ø sleepq_signal
ÔòÖ»»Ö¸´ÔڵȴýͨµÀÉÏÓÅÏȼ¶×î¸ßµÄ×èÈûÏ̡߳£ ÔÚµ÷ÓÃÕâЩº¯Êý֮ǰ£¬ Ó¦Ê×ÏÈʹÓà sleepq_lock
¶ÔÐÝÃß¶ÓÁÐÉÏËø¡£
¡¡¡¡ÐÝÃßÏß³ÌÒ²¿ÉÒÔͨ¹ýµ÷Óà sleepq_abort
º¯ÊýÀ´ÖÐ¶ÏÆäÐÝÃß״̬¡£ Õâ¸öº¯ÊýÖ»ÓÐÔÚ³ÖÓÐ sched_lock
ʱ²ÅÄܵ÷Ó㬠¶øÇÒÏ̱߳ØÐë´¦ÓÚÐÝÃß¶ÓÁÐÖ®ÉÏ¡£ Ïß³ÌÒ²¿ÉÒÔͨ¹ýʹÓà sleepq_remove
º¯Êý´ÓÖ¸¶¨µÄÐÝÃß¶ÓÁÐÖÐɾ³ý¡£ Õâ¸öº¯Êý°üÀ¨Á½¸ö²ÎÊý£¬
¼´ÐÝÃßͨµÀºÍỊ̈߳¬ ËüÖ»ÔÚÏ̴߳¦ÓÚÖ¸¶¨ÐÝÃßͨµÀµÄÐÝÃß¶ÓÁÐÖ®ÉÏʱ²Å½«Æä»½ÐÑ¡£
Èç¹ûÏ̲߳»ÔÚÄǸöÐÝÃß¶ÓÁÐÖ®ÉÏ£¬ »òͬʱ´¦ÓÚÁíÒ»µÈ´ýͨµÀµÄÐÝÃß¶ÓÁÐÉÏ£¬
ÔòÕâ¸öº¯Êý½«Ê²Ã´¶¼²»×ö¶øÖ±½Ó·µ»Ø¡£
¡¡¡¡- ÓëÐÝÃß¶ÓÁеıȽϺͲ»Í¬¡£
¡¡¡¡- ²éѯ/µÈ´ý/ÊÍ·Å (lookup/wait/release) - ½éÉÜ TDF_TSNOBLOCK ¾ºÌ¬Ìõ¼þ¡£
¡¡¡¡- ÓÅÏȼ¶´«²¥¡£
¡¡¡¡- ÎÒÃÇÊÇ·ñÓ¦ÒªÇó mtx_destroy() ³ÖÓÐ mutex£¬ ÒòΪÎÞ·¨°²È«µØ¶ÏÑÔËüÃÇûÓб»ÆäËü¶ÔÏó³ÖÓУ¿
¡¡¡¡- ÃèÊö mutex ³åͻʱµÄ¾ºÌ¬Ìõ¼þ
¡¡¡¡- ΪºÎÔÚ³ÖÓÐÊ®×ÖתÃÅÁ´ËøÊ±£¬ ¿ÉÒÔ°²È«µØ¶Á³åÍ» mutex µÄ mtx_lock¡£
¡¡¡¡- ÊÇ·ñÓ¦½« interlock ´«¸ø sema_wait
£¿
¡¡¡¡- ÊÇ·ñÓ¦Ìṩ·ÇÐÝÃßʽ sx Ëø£¿
¡¡¡¡- Ôö¼ÓһЩ¹ØÓÚÕýȷʹÓÃÒýÓüÆÊýµÄ½éÉÜ¡£
µ±×ñÑÊʵ±µÄ·ÃÎÊÐÒéʱ£¬ Èç¹ûÒ»²Ù×÷µÄЧ¹û¶ÔÆäËüËùÓÐ CPU ¾ù¿É¼û£¬ Ôò³ÆÆäΪÔ×Ó²Ù×÷¡£ ÏÁÒåµÄÔ×Ó²Ù×÷ÊÇ»úÆ÷Ö±½ÓÌṩµÄ¡£ ¾Í¸ü¸ßµÄ³éÏó²ã´Î¶øÑÔ£¬ Èç¹û½á¹¹ÌåµÄ¶à¸ö³ÉÔ±ÓÉÒ»¸öËø±£»¤£¬ ÔòÈç¹û¶ÔËüÃǵIJÙ×÷¶¼ÊÇÔÚÉÏËøºó¡¢ ½âËøÇ°½øÐеģ¬ Ò²¿ÉÒÔ³ÆÆäΪÔ×Ó²Ù×÷¡£
²Î¼û: ²Ù×÷.
Ï̵߳ȴýËø¡¢ ×ÊÔ´»òÌõ¼þʱ±»×èÈû¡£ ÕâÒ»ÊõÓïÒ²Òò´Ë±»¸³ÓèÁËÌ«¶àµÄÒ⺡£
²Î¼û: ÐÝÃß.
²»ÔÊÐí·¢ÉúÇÀÕ¼µÄ´úÂë¶Î¡£ ʹÓà critical_enter(9) API À´±íʾ½øÈëºÍÍ˳öÁÙ½çÇø¡£
±íʾÓë»úÆ÷/ƽ̨Óйء£
²Î¼û: MI.
ÄÚ´æ²Ù×÷°üÀ¨¶Á»òдÄÚ´æÖеÄÖ¸¶¨Î»Öá£
±íʾÓë»úÆ÷/ƽ̨Î޹ء£
²Î¼û: MD.
Ö÷ÖжÏÉÏÏÂÎıíʾµ±·¢ÉúÖжÏʱËùÖ´ÐеÄÄǶδúÂë¡£ ÕâЩ´úÂë¿ÉÒÔÖ±½ÓÔËÐÐij¸öÖжϴ¦Àí³ÌÐò£¬ »òµ÷¶ÈÒ»Òì²½ÖÕ¶ËỊ̈߳¬ ÒÔ±ãΪ¸ø¶¨µÄÖжÏÔ´Ö´ÐÐÖжϴ¦Àí³ÌÐò¡£
Ò»ÖÖ¸ßÓÅÏȼ¶µÄÄÚºËÏ̡߳£ Ŀǰ£¬ Ö»ÓÐÖжÏÏß³ÌÊôÓÚʵʱÓÅÏȼ¶µÄÄÚºËÏ̡߳£
²Î¼û: Ïß³Ì.
µ±½ø³ÌÓÉÌõ¼þ±äÁ¿»òͨ¹ý msleep
»ò tsleep
×èÈû²¢½øÈëÐÝÃß¶ÓÁÐʱ£¬ ³ÆÆä½øÈëÐÝÃß״̬¡£
²Î¼û: ×èÈû.
¿ÉÐÝÃßËøÊÇÒ»ÖÖÔÚ½ø³ÌÐÝÃßʱÈԿɳÖÓеÄËø¡£ Ëø¹ÜÀíÆ÷ (lockmgr) ËøºÍ sx ËøÊÇĿǰ FreeBSD ÖнöÓеĿÉÐÝÃßËø¡£ ×îÖÕ£¬ ijЩ sx Ëø£¬ ÀýÈç allproc (È«²¿½ø³Ì) ºÍ proctree (½ø³ÌÊ÷) Ëø½«³ÉΪ²»¿ÉÐÝÃßËø¡£
²Î¼û: ÐÝÃß.
ÓÉ struct thread Ëù±í´ïµÄÄÚºËÏ̡߳£ Ï߳̿ÉÒÔ³ÖÓÐËø£¬ ²¢ÓµÓжÀÁ¢µÄÖ´ÐÐÉÏÏÂÎÄ¡£
Ï߳̿ÉÒÔÔÚÆäÉÏÐÝÃßµÄÄÚºËÐéÄâµØÖ·¡£
¡¡¡¡±¾Õ¼òÒª½éÉÜÁËÈçºÎΪFreeBSD±àдÉ豸Çý¶¯³ÌÐò¡£ÊõÓïÉ豸ÔÚ Õâ¶ùµÄÉÏÏÂÎÄÖжàÓÃÓÚÖ¸´úϵͳÖÐÓ²¼þÏà¹ØµÄ¶«Î÷£¬Èç´ÅÅÌ£¬´òÓ¡»ú£¬ ͼÐÎÏÔʽÆ÷¼°Æä¼üÅÌ¡£É豸Çý¶¯³ÌÐòÊDzÙ×÷ϵͳÖÐÓÃÓÚ¿ØÖÆÌض¨É豸µÄ Èí¼þ×é¼þ¡£Ò²ÓÐËùνµÄαÉ豸£¬¼´É豸Çý¶¯³ÌÐòÓÃÈí¼þÄ£ÄâÉ豸µÄÐÐΪ£¬ ¶øÃ»ÓÐÌØ¶¨µÄµ×²ãÓ²¼þ¡£É豸Çý¶¯³ÌÐò¿ÉÒÔ±»¾²Ì¬µØ±àÒë½øÏµÍ³£¬»òÕß Í¨¹ý¶¯Ì¬ÄÚºËÁ´½Ó¹¤¾ß¡®kld¡¯ÔÚÐèҪʱ¼ÓÔØ¡£
¡¡¡¡ÀàUNIX²Ù×÷ϵͳÖеĴó¶àÊýÉ豸¶¼ÊÇͨ¹ýÉ豸½ÚµãÀ´·ÃÎʵģ¬ÓÐʱҲ ±»³ÆÎªÌØÊâÎļþ¡£ÕâЩÎļþÔÚÎļþϵͳµÄ²ã´Î½á¹¹ÖÐͨ³£Î»ÓÚ /devĿ¼Ï¡£ÔÚFreeBSD 5.0-RELEASEÒÔǰµÄ ·¢ÐаæÖÐ, ¶Ôdevfs(5)µÄÖ§³Ö»¹Ã»Óб»¼¯³Éµ½FreeBSDÖУ¬Ã¿¸öÉ豸 ½Úµã±ØÐëÒª¾²Ì¬´´½¨£¬²¢ÇÒ¶ÀÁ¢ÓÚÏà¹ØÉ豸Çý¶¯³ÌÐòµÄ´æÔÚ¡£ÏµÍ³Öдó ¶àÊýÉ豸½ÚµãÊÇͨ¹ýÔËÐÐMAKEDEV´´½¨µÄ¡£
¡¡¡¡É豸Çý¶¯³ÌÐò¿ÉÒÔ´ÖÂԵطÖΪÁ½À࣬×Ö·ûºÍÍøÂçÉ豸Çý¶¯³ÌÐò¡£
¡¡¡¡kld½Ó¿ÚÔÊÐíϵͳ¹ÜÀíÔ±´ÓÔËÐеÄϵͳÖж¯Ì¬µØÌí¼ÓºÍɾ³ý¹¦ÄÜ¡£ ÕâÔÊÐíÉ豸Çý¶¯³ÌÐòµÄ±àдÕß½«ËûÃǵÄÐ¸Ķ¯¼ÓÔØµ½ÔËÐеÄÄÚºËÖУ¬ ¶ø²»ÓÃΪÁ˲âÊÔÐ¸Ķ¯¶øÆµ·±µØÖØÆô¡£
¡¡¡¡kld½Ó¿Úͨ¹ýÏÂÃæµÄÌØÈ¨ÃüÁîʹÓãº
kldload - ¼ÓÔØÐÂÄÚºËÄ£¿é
kldunload - Ð¶ÔØÄÚºËÄ£¿é
kldstat - Áоٵ±Ç°¼ÓÔØµÄÄ£¿é
¡¡¡¡ÄÚºËÄ£¿éµÄ³ÌÐò¿ò¼Ü
/* * KLD³ÌÐò¿ò¼Ü * ÊÜAndrew ReiterÔÚDaemonnewsÉϵÄÎÄÕÂËùÆô·¢ */ #include <sys/types.h> #include <sys/module.h> #include <sys/systm.h> /* uprintf */ #include <sys/errno.h> #include <sys/param.h> /* kernel.hÖÐÓõ½µÄ¶¨Òå */ #include <sys/kernel.h> /* Ä£¿é³õʼ»¯ÖÐʹÓõÄÀàÐÍ */ /* * ¼ÓÔØ´¦Àíº¯Êý£¬¸ºÔð´¦ÀíKLDµÄ¼ÓÔØºÍÐ¶ÔØ¡£ */ static int skel_loader(struct module *m, int what, void *arg) { int err = 0; switch (what) { case MOD_LOAD: /* kldload */ uprintf("Skeleton KLD loaded.\n"); break; case MOD_UNLOAD: uprintf("Skeleton KLD unloaded.\n"); break; default: err = EOPNOTSUPP; break; } return(err); } /* ÏòÄÚºËÆäÓಿ·ÖÉùÃ÷´ËÄ£¿é */ static moduledata_t skel_mod = { "skel", skel_loader, NULL }; DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY);
¡¡¡¡FreeBSDÌṩÁËÒ»¸ömakefile°üº¬Îļþ£¬ÀûÓÃËüÄã¿ÉÒÔ¿ìËٵرàÒë Ä㸽¼Óµ½Äں˵Ķ«Î÷¡£
SRCS=skeleton.c KMOD=skeleton .include <bsd.kmod.mk>
¡¡¡¡¼òµ¥µØÓÃÕâ¸ömakefileÔËÐÐmake¾ÍÄܹ»´´½¨Îļþ skeleton.ko£¬¼üÈëÈçÏÂÃüÁî¿ÉÒÔ°ÑËü¼ÓÔØµ½Äںˣº
# kldload -v ./skeleton.ko
¡¡¡¡UNIX ÌṩÁËÒ»Ì×¹«¹²µÄϵͳµ÷Óù©Óû§µÄÓ¦ÓóÌÐòʹÓᣵ±Óû§·ÃÎÊ É豸½Úµãʱ£¬Äں˵ÄÉϲ㽫ÕâЩµ÷Ó÷ַ¢µ½ÏàÓ¦µÄÉ豸Çý¶¯³ÌÐò¡£½Å±¾ /dev/MAKEDEVΪÄãµÄϵͳÉú³ÉÁË´ó¶àÊýµÄÉ豸½Úµã£¬ µ«Èç¹ûÄãÕýÔÚ¿ª·¢Äã×Ô¼ºµÄÇý¶¯³ÌÐò£¬¿ÉÄÜÐèÒªÓà mknod´´½¨Äã×Ô¼ºµÄÉ豸½Úµã¡£
¡¡¡¡mknodÃüÁîÐèÒªËĸö²ÎÊýÀ´´´½¨É豸½Úµã¡£ Äã±ØÐëÖ¸¶¨É豸½ÚµãµÄÃû×Ö£¬É豸µÄÀàÐÍ£¬É豸µÄÖ÷ºÅÂëºÍÉ豸µÄ´ÓºÅÂë¡£
¡¡¡¡É豸Îļþϵͳ£¬»òÕß˵devfs£¬ÔÚÈ«¾ÖÎļþϵͳÃû×Ö¿Õ¼äÖÐÌṩ¶Ô ÄÚºËÉ豸Ãû×Ö¿Õ¼äµÄ·ÃÎÊ¡£ÕâÏû³ýÁËÓÉÓÚÓÐÉ豸Çý¶¯³ÌÐò¶øÃ»Óо²Ì¬ É豸½Úµã£¬»òÕßÓÐÉ豸½Úµã¶øÃ»Óа²×°É豸Çý¶¯³ÌÐò¶ø´øÀ´µÄDZÔÚÎÊÌâ¡£ DevfsÈÔÔÚ½øÕ¹ÖУ¬µ«ÒѾÄܹ»¹¤×÷µÃÏ൱ºÃÁË¡£
¡¡¡¡×Ö·ûÉ豸Çý¶¯³ÌÐòÖ±½Ó´ÓÓû§½ø³Ì´«ÊäÊý¾Ý£¬»ò´«ÊäÊý¾Ýµ½Óû§½ø³Ì¡£ ÕâÊÇ×îÆÕͨµÄÒ»ÀàÉ豸Çý¶¯³ÌÐò£¬Ô´ÂëÊ÷ÖÐÓдóÁ¿µÄ¼òµ¥Àý×Ó¡£
¡¡¡¡Õâ¸ö¼òµ¥µÄαÉ豸Àý×Ó»á¼ÇסÄãд¸øËüµÄÈκÎÖµ£¬²¢ÇÒµ±Äã¶ÁÈ¡ËüµÄʱºò »á½«ÕâЩֵ·µ»Ø¸øÄã¡£ÏÂÃæÏÔʾÁËÁ½¸ö°æ±¾£¬Ò»¸öÊÊÓÃÓÚFreeBSD 4.X£¬ Ò»¸öÊÊÓÃÓÚFreeBSD 5.X¡£
Àý 9-1. ÊÊÓÃÓÚFreeBSD 4.XµÄ»ØÏÔαÉ豸Çý¶¯³ÌÐòʵÀý
/* * ¼òµ¥¡®echo¡¯Î±É豸KLD * * Murray Stokely */ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #include <sys/types.h> #include <sys/module.h> #include <sys/systm.h> /* uprintf */ #include <sys/errno.h> #include <sys/param.h> /* kernel.hÖÐÓõ½µÄ¶¨Òå */ #include <sys/kernel.h> /* Ä£¿é³õʼ»¯ÖÐʹÓõÄÀàÐÍ */ #include <sys/conf.h> /* cdevsw½á¹¹ */ #include <sys/uio.h> /* uio½á¹¹ */ #include <sys/malloc.h> #define BUFFERSIZE 256 /* º¯ÊýÔÐÍ */ d_open_t echo_open; d_close_t echo_close; d_read_t echo_read; d_write_t echo_write; /* ×Ö·ûÉ豸Èë¿Úµã */ static struct cdevsw echo_cdevsw = { echo_open, echo_close, echo_read, echo_write, noioctl, nopoll, nommap, nostrategy, "echo", 33, /* Ϊlkms±£Áô - /usr/src/sys/conf/majors */ nodump, nopsize, D_TTY, -1 }; typedef struct s_echo { char msg[BUFFERSIZE]; int len; } t_echo; /* ±äÁ¿ */ static dev_t sdev; static int count; static t_echo *echomsg; MALLOC_DECLARE(M_ECHOBUF); MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module"); /* * Õâ¸öº¯Êý±»kld[un]load(2)ϵͳµ÷ÓÃÀ´µ÷Ó㬠* ÒÔ¾ö¶¨¼ÓÔØºÍÐ¶ÔØÄ£¿éʱÐèÒª²ÉÈ¡µÄ¶¯×÷¡£ */ static int echo_loader(struct module *m, int what, void *arg) { int err = 0; switch (what) { case MOD_LOAD: /* kldload */ sdev = make_dev(&echo_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "echo"); /* kmalloc·ÖÅ乩Çý¶¯³ÌÐòʹÓõÄÄÚ´æ */ MALLOC(echomsg, t_echo *, sizeof(t_echo), M_ECHOBUF, M_WAITOK); printf("Echo device loaded.\n"); break; case MOD_UNLOAD: destroy_dev(sdev); FREE(echomsg,M_ECHOBUF); printf("Echo device unloaded.\n"); break; default: err = EOPNOTSUPP; break; } return(err); } int echo_open(dev_t dev, int oflags, int devtype, struct proc *p) { int err = 0; uprintf("Opened device \"echo\" successfully.\n"); return(err); } int echo_close(dev_t dev, int fflag, int devtype, struct proc *p) { uprintf("Closing device \"echo.\"\n"); return(0); } /* * readº¯Êý½ÓÊÜÓÉecho_write()´æ´¢µÄbuf£¬²¢½«Æä·µ»Øµ½Óû§¿Õ¼ä£¬ * ÒÔ¹©ÆäËûº¯Êý·ÃÎÊ¡£ * uio(9) */ int echo_read(dev_t dev, struct uio *uio, int ioflag) { int err = 0; int amt; /* * Õâ¸ö¶Á²Ù×÷Óжà´ó£¿ * ÓëÓû§ÇëÇóµÄ´óСһÑù£¬»òÕßµÈÓÚÊ£ÓàÊý¾ÝµÄ´óС¡£ */ amt = MIN(uio->uio_resid, (echomsg->len - uio->uio_offset > 0) ? echomsg->len - uio->uio_offset : 0); if ((err = uiomove(echomsg->msg + uio->uio_offset,amt,uio)) != 0) { uprintf("uiomove failed!\n"); } return(err); } /* * echo_write½ÓÊÜÒ»¸ö×Ö·û´®²¢½«Ëü±£´æµ½»º³åÇø£¬ÓÃÓÚÒÔºóµÄ·ÃÎÊ¡£ */ int echo_write(dev_t dev, struct uio *uio, int ioflag) { int err = 0; /* ½«×Ö·û´®´ÓÓû§¿Õ¼äµÄÄÚ´æ¸´ÖÆµ½Äں˿ռä */ err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_len, BUFFERSIZE - 1)); /* ÏÖÔÚÐèÒªÒÔnull½áÊø×Ö·û´®£¬²¢¼Ç¼³¤¶È */ *(echomsg->msg + MIN(uio->uio_iov->iov_len, BUFFERSIZE - 1)) = 0; echomsg->len = MIN(uio->uio_iov->iov_len, BUFFERSIZE); if (err != 0) { uprintf("Write failed: bad address!\n"); } count++; return(err); } DEV_MODULE(echo,echo_loader,NULL);
Àý 9-2. ÊÊÓÃÓÚFreeBSD 5.X»ØÏÔαÉ豸Çý¶¯³ÌÐòʵÀý
/* * ¼òµ¥¡®echo¡¯Î±É豸 KLD * * Murray Stokely * * ´Ë´úÂëÓÉSøren (Xride) Straarupת»»µ½5.X */ #include <sys/types.h> #include <sys/module.h> #include <sys/systm.h> /* uprintf */ #include <sys/errno.h> #include <sys/param.h> /* kernel.hÖÐÓõ½µÄ¶¨Òå */ #include <sys/kernel.h> /* Ä£¿é³õʼ»¯ÖÐʹÓõÄÀàÐÍ */ #include <sys/conf.h> /* cdevsw½á¹¹ */ #include <sys/uio.h> /* uio½á¹¹ */ #include <sys/malloc.h> #define BUFFERSIZE 256 /* º¯ÊýÔÐÍ */ static d_open_t echo_open; static d_close_t echo_close; static d_read_t echo_read; static d_write_t echo_write; /* ×Ö·ûÉ豸Èë¿Úµã */ static struct cdevsw echo_cdevsw = { .d_version = D_VERSION, .d_open = echo_open, .d_close = echo_close, .d_read = echo_read, .d_write = echo_write, .d_name = "echo", }; typedef struct s_echo { char msg[BUFFERSIZE]; int len; } t_echo; /* ±äÁ¿ */ static struct cdev *echo_dev; static int count; static t_echo *echomsg; MALLOC_DECLARE(M_ECHOBUF); MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module"); /* * Õâ¸öº¯Êý±»kld[un]load(2)ϵͳµ÷ÓÃÀ´µ÷ÓÃ, * ÒÔ¾ö¶¨¼ÓÔØºÍÐ¶ÔØÄ£¿éʱÐèÒª²ÉÈ¡µÄ¶¯×÷. */ static int echo_loader(struct module *m, int what, void *arg) { int err = 0; switch (what) { case MOD_LOAD: /* kldload */ echo_dev = make_dev(&echo_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "echo"); /* kmalloc·ÖÅ乩Çý¶¯³ÌÐòʹÓõÄÄÚ´æ */ echomsg = malloc(sizeof(t_echo), M_ECHOBUF, M_WAITOK); printf("Echo device loaded.\n"); break; case MOD_UNLOAD: destroy_dev(echo_dev); free(echomsg, M_ECHOBUF); printf("Echo device unloaded.\n"); break; default: err = EOPNOTSUPP; break; } return(err); } static int echo_open(struct cdev *dev, int oflags, int devtype, struct thread *p) { int err = 0; uprintf("Opened device \"echo\" successfully.\n"); return(err); } static int echo_close(struct cdev *dev, int fflag, int devtype, struct thread *p) { uprintf("Closing device \"echo.\"\n"); return(0); } /* * readº¯Êý½ÓÊÜÓÉecho_write()´æ´¢µÄbuf£¬²¢½«Æä·µ»Øµ½Óû§¿Õ¼ä£¬ * ÒÔ¹©ÆäËûº¯Êý·ÃÎÊ¡£ * uio(9) */ static int echo_read(struct cdev *dev, struct uio *uio, int ioflag) { int err = 0; int amt; /* * Õâ¸ö¶Á²Ù×÷Óжà´ó£¿ * µÈÓÚÓû§ÇëÇóµÄ´óС£¬»òÕßµÈÓÚÊ£ÓàÊý¾ÝµÄ´óС¡£ */ amt = MIN(uio->uio_resid, (echomsg->len - uio->uio_offset > 0) ? echomsg->len - uio->uio_offset : 0); if ((err = uiomove(echomsg->msg + uio->uio_offset, amt, uio)) != 0) { uprintf("uiomove failed!\n"); } return(err); } /* * echo_write½ÓÊÜÒ»¸ö×Ö·û´®²¢½«Ëü±£´æµ½»º³åÇø, ÓÃÓÚÒÔºóµÄ·ÃÎÊ. */ static int echo_write(struct cdev *dev, struct uio *uio, int ioflag) { int err = 0; /* ½«×Ö·û´®´ÓÓû§¿Õ¼äµÄÄÚ´æ¸´ÖÆµ½Äں˿ռä */ err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_len, BUFFERSIZE - 1)); /* ÏÖÔÚÐèÒªÒÔnull½áÊø×Ö·û´®£¬²¢¼Ç¼³¤¶È */ *(echomsg->msg + MIN(uio->uio_iov->iov_len, BUFFERSIZE - 1)) = 0; echomsg->len = MIN(uio->uio_iov->iov_len, BUFFERSIZE); if (err != 0) { uprintf("Write failed: bad address!\n"); } count++; return(err); } DEV_MODULE(echo,echo_loader,NULL);
¡¡¡¡ÔÚFreeBSD 4.XÉϰ²×°´ËÇý¶¯³ÌÐò£¬Ä㽫Ê×ÏÈÐèÒªÓÃÈçÏÂÃüÁîÔÚ ÄãµÄÎļþϵͳÉÏ´´½¨Ò»¸ö½Úµã£º
# mknod /dev/echo c 33 0
¡¡¡¡Çý¶¯³ÌÐò±»¼ÓÔØºó£¬ÄãÓ¦¸ÃÄܹ»¼üÈëһЩ¶«Î÷£¬È磺
# echo -n "Test Data" > /dev/echo # cat /dev/echo Test Data
¡¡¡¡ÕæÕýµÄÓ²¼þÉ豸ÔÚÏÂÒ»ÕÂÃèÊö¡£
¡¡¡¡²¹³ä×ÊÔ´
Dynamic Kernel Linker (KLD) Facility Programming Tutorial - Daemonnews October 2000
How to Write Kernel Drivers with NEWBUS - Daemonnews July 2000
¡¡¡¡ÆäËûUNIXϵͳ֧³ÖÁíÒ»ÀàÐ͵ĴÅÅÌÉ豸£¬³ÆÎª¿éÉ豸¡£¿éÉ豸ÊÇÄÚºË ÎªËüÃÇÌṩ»º³åµÄ´ÅÅÌÉ豸¡£ÕâÖÖ»º³åʹµÃ¿éÉ豸¼¸ºõûÓÐÓ㬻òÕß˵·Ç³£ ²»¿É¿¿¡£»º³å»áÖØÐ°²ÅÅд²Ù×÷µÄ´ÎÐò£¬Ê¹µÃÓ¦ÓóÌÐòɥʧÁËÔÚÈκÎʱ¿Ì¼°Ê± ÖªµÀ׼ȷµÄ´ÅÅÌÄÚÈݵÄÄÜÁ¦¡£Õâµ¼Ö¶ԴÅÅÌÊý¾Ý½á¹¹£¨Îļþϵͳ£¬Êý¾Ý¿âµÈ£©µÄ ¿ÉÔ¤²âµÄºÍ¿É¿¿µÄ±ÀÀ£»Ö¸´³ÉΪ²»¿ÉÄÜ¡£ÓÉÓÚд²Ù×÷±»ÑÓ³Ù£¬ÄÚºËÎÞ·¨ÏòÓ¦Óà ³ÌÐò±¨¸æÄĸöÌØ¶¨µÄд²Ù×÷Óöµ½ÁËд´íÎó£¬ÕâÓÖ½øÒ»²½Ôö¼ÓÁËÒ»ÖÂÐÔÎÊÌâ¡£ ÓÉÓÚÕâ¸öÔÒò£¬ÕæÕýµÄÓ¦ÓóÌÐò´Ó²»ÒÀÀµÓÚ¿éÉ豸£¬ÊÂʵÉÏ£¬¼¸ºõËùÓзÃÎÊ ´ÅÅ̵ÄÓ¦ÓóÌÐò¶¼¾¡Á¦Ö¸¶¨×ÜÊÇʹÓÃ×Ö·û£¨»ò¡°raw¡±£©É豸¡£ ÓÉÓÚʵÏÖ½«Ã¿¸ö´ÅÅÌ£¨·ÖÇø£©Í¬¾ßÓв»Í¬ÓïÒåµÄÁ½¸öÉ豸»ìΪһ̸£¬´Ó¶øÖÂʹ Ïà¹ØÄں˴úÂ뼫´óµØ¸´ÔÓ»¯£¬×÷ÎªÍÆ½ø´ÅÅÌI/O»ù´¡½á¹¹ÏÖ´ú»¯µÄÒ»²¿·Ö£¬FreeBSD ÅׯúÁ˶Դø»º³åµÄ´ÅÅÌÉ豸µÄÖ§³Ö¡£
¡¡¡¡·ÃÎÊÍøÂçÉ豸µÄÇý¶¯³ÌÐò²»ÐèҪʹÓÃÉ豸½Úµã¡£Ñ¡ÔñÄĸöÇý¶¯³ÌÐòÊÇ »ùÓÚÄÚºËÄÚ²¿µÄÆäËû¾ö¶¨¶ø²»Êǵ÷ÓÃopen()£¬¶ÔÍøÂçÉ豸µÄʹÓÃͨ³£ÓÉ ÏµÍ³µ÷ÓÃsocket(2)ÒýÈë¡£
¡¡¡¡¸ü¶àϸ½Ú£¬ Çë²Î¼û ifnet(9) Áª»úÊֲᡢ »Ø»·É豸µÄÔ´´úÂ룬 ÒÔ¼° Bill Paul ׫дµÄÍøÂçÇý¶¯³ÌÐò¡£
¡¡¡¡±¾Õ½éÉÜÁ˱àдISAÉ豸Çý¶¯³ÌÐòÏà¹ØµÄһЩÎÊÌâ¡£Õâ¶ùչʾµÄα´úÂë Ï൱Ïêϸ£¬ºÜÈÝÒ×ÈÃÈËÁªÏëµ½ÕæÕýµÄ´úÂ룬²»¹ýÕâÒÀÈ»½ö½öÊÇα´úÂë¡£ Ëü±ÜÃâÁËÓëËùÌÖÂÛµÄÖ÷ÌâÎ޹صÄϸ½Ú¡£ÕæÊµµÄÀý×Ó¿ÉÒÔÔÚʵ¼ÊÇý¶¯³ÌÐòµÄ Ô´´úÂëÖÐÕÒµ½¡£epºÍaha ¸üÊÇÐÅÏ¢µÄºÃÀ´Ô´¡£
¡¡¡¡µäÐ͵ÄISAÇý¶¯³ÌÐòÐèÒªÒÔϰüº¬Îļþ£º
#include <sys/module.h> #include <sys/bus.h> #include <machine/bus.h> #include <machine/resource.h> #include <sys/rman.h> #include <isa/isavar.h> #include <isa/pnpvar.h>
¡¡¡¡ËüÃÇÃèÊöÁËÕë¶ÔISAºÍͨÓÃ×ÜÏß×ÓϵͳµÄ¶«Î÷¡£
¡¡¡¡×ÜÏß×ÓϵͳÊÇÒÔÃæÏò¶ÔÏóµÄ·½Ê½ÊµÏֵ쬯äÖ÷Òª½á¹¹Í¨¹ýÏà¹ØÁªµÄ ·½·¨º¯ÊýÀ´·ÃÎÊ¡£
¡¡¡¡ISAÇý¶¯³ÌÐòʵÏÖµÄ×ÜÏß·½·¨µÄÁбíÓëÈÎºÎÆäËû×ÜÏߵĺÜÏàËÆ¡£ ¶ÔÓÚÃû×ÖΪ¡°xxx¡±µÄ¼ÙÏëÇý¶¯³ÌÐò£¬ËüÃǽ«ÊÇ£º
static void xxx_isa_identify (driver_t *, device_t);
ͨ³£ÓÃÓÚ×ÜÏßÇý¶¯³ÌÐò¶ø²»ÊÇÉ豸Çý¶¯³ÌÐò¡£
µ«¶ÔÓÚISAÉ豸£¬Õâ¸ö·½·¨ÓÐÌØÊâÓÃ;£ºÈç¹ûÉ豸ÌṩijЩÉè±¸ÌØ¶¨µÄ
£¨·ÇPnP£©·½·¨×Ô¶¯Õì²âÉ豸£¬Õâ¸öÀý³Ì¿ÉÒÔʵÏÖËü¡£
static int xxx_isa_probe (device_t dev);
ÔÚÒÑÖª£¨»òPnP£©Î»ÖÃ̽²âÉ豸¡£¶ÔÓÚÒѾ²¿·ÖÅäÖõÄ
É豸£¬Õâ¸öÀý³ÌÒ²Äܹ»ÌṩÉè±¸ÌØ¶¨µÄ¶ÔijЩ²ÎÊýµÄ×Ô¶¯Õì²â¡£
static int xxx_isa_attach (device_t dev);
¹Ò½ÓºÍ³õʼ»¯É豸¡£
static int xxx_isa_detach (device_t dev);
Ð¶ÔØÉ豸Çý¶¯Ä£¿éǰ½â¹ÒÉ豸¡£
static int xxx_isa_shutdown (device_t dev);
ϵͳ¹Ø±ÕǰִÐÐÉ豸µÄ¹Ø±Õ¡£
static int xxx_isa_suspend (device_t dev);
ϵͳ½øÈë½ÚÄÜ״̬ǰ¹ÒÆðÉ豸¡£Ò²¿ÉÒÔÖÐÖ¹ Çл»µ½½ÚÄÜ״̬¡£
static int xxx_isa_resume (device_t dev);
´Ó½ÚÄÜ״̬·µ»Øºó»Ö¸´É豸µÄ»î¶¯×´Ì¬¡£
¡¡¡¡xxx_isa_probe()
ºÍ xxx_isa_attach()
ÊDZØÐëÌṩµÄ£¬ÆäÓàÀý³Ì¸ù¾ÝÉ豸µÄ
ÐèÒª¿ÉÒÔÓÐÑ¡ÔñµØÊµÏÖ¡£
¡¡¡¡Ê¹ÓÃÏÂÃæÒ»×éÃèÊö·û½«É豸Çý¶¯Á´½Óµ½ÏµÍ³¡£
/* Ö§³ÖµÄ×ÜÏß·½·¨±í */ static device_method_t xxx_isa_methods[] = { /* ÁгöÇý¶¯³ÌÐòÖ§³ÖµÄËùÓÐ×ÜÏß·½·¨º¯Êý */ /* ÂÔÈ¥²»Ö§³ÖµÄº¯Êý */ DEVMETHOD(device_identify, xxx_isa_identify), DEVMETHOD(device_probe, xxx_isa_probe), DEVMETHOD(device_attach, xxx_isa_attach), DEVMETHOD(device_detach, xxx_isa_detach), DEVMETHOD(device_shutdown, xxx_isa_shutdown), DEVMETHOD(device_suspend, xxx_isa_suspend), DEVMETHOD(device_resume, xxx_isa_resume), { 0, 0 } }; static driver_t xxx_isa_driver = { "xxx", xxx_isa_methods, sizeof(struct xxx_softc), }; static devclass_t xxx_devclass; DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass, load_function, load_argument);
¡¡¡¡´Ë´¦µÄ½á¹¹xxx_softc
ÊÇÒ»¸öÉ豸
ÌØ¶¨µÄ½á¹¹£¬Ëü°üº¬Ë½ÓеÄÇý¶¯³ÌÐòÊý¾ÝºÍÇý¶¯³ÌÐò×ÊÔ´µÄÃèÊö·û¡£
×ÜÏß´úÂë»á×Ô¶¯°´ÐèҪΪÿ¸öÉ豸·ÖÅäÒ»¸ösoftcÃèÊö·û¡£
¡¡¡¡Èç¹ûÇý¶¯³ÌÐò×÷Ϊ¿É¼ÓÔØÄ£¿éʵÏÖ£¬µ±Çý¶¯³ÌÐò±»¼ÓÔØ»òÐ¶ÔØÊ±£¬ »áµ÷ÓÃload_function()
º¯Êý½øÐÐÇý¶¯³ÌÐòÌØ¶¨µÄ
³õʼ»¯»òÇåÀí¹¤×÷£¬²¢½«load_argument×÷Ϊº¯ÊýµÄÒ»¸ö²ÎÁ¿´«µÝ½øÈ¥¡£
Èç¹ûÇý¶¯³ÌÐò²»Ö§³Ö¶¯Ì¬¼ÓÔØ£¨»»¾ä»°Ëµ£¬Ëü±ØÐë±»Á´½Óµ½ÄÚºËÖУ©£¬Ôò
ÕâЩֵӦµ±±»ÉèÖÃΪ0£¬×îºóµÄ¶¨Ò彫¿´ÆðÀ´ÈçÏÂËùʾ£º
DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass, 0, 0);
¡¡¡¡Èç¹ûÇý¶¯³ÌÐòÊÇΪ֧³ÖPnPµÄÉ豸¶øÐ´µÄ£¬ÄÇô¾Í±ØÐ붨ÒåÒ»¸ö°üº¬ ËùÓÐÖ§³ÖµÄPnP IDµÄ±í¡£Õâ¸ö±íÓÉ´ËÇý¶¯³ÌÐòËùÖ§³ÖµÄPnP IDµÄÁÐ±í ºÍÒÔÈ˿ɶÁµÄÐÎʽ¸ø³öµÄ¡¢ÓëÕâЩID¶ÔÓ¦µÄÓ²¼þÀàÐͺÍÐͺŵÄÃèÊö ×é³É¡£¿´ÆðÀ´ÈçÏ£º
static struct isa_pnp_id xxx_pnp_ids[] = { /* ÿ¸öËùÖ§³ÖµÄPnP IDÕ¼Ò»ÐÐ */ { 0x12345678, "Our device model 1234A" }, { 0x12345679, "Our device model 1234B" }, { 0, NULL }, /* ±í½áÊø */ };
¡¡¡¡Èç¹ûÇý¶¯³ÌÐò²»Ö§³ÖPnPÉ豸£¬ËüÈÔÈ»ÐèÒªÒ»¸ö¿ÕµÄPnP ID±í£¬ ÈçÏÂËùʾ£º
static struct isa_pnp_id xxx_pnp_ids[] = { { 0, NULL }, /* ±í½áÊø */ };
¡¡¡¡Device_t
ÊÇΪÉ豸½á¹¹¶ø¶¨ÒåµÄÖ¸ÕëÀàÐÍ£¬
ÕâÀïÎÒÃÇÖ»¹ØÐÄ´ÓÉ豸Çý¶¯³ÌÐò±àдÕߵĽǶȿ´¸ÐÐËȤµÄ·½·¨¡£ÏÂÃæµÄ·½·¨
ÓÃÀ´²Ù×ÝÉ豸½á¹¹ÖеÄÖµ£º
¡¡¡¡
device_t device_get_parent(dev)
»ñÈ¡É豸µÄ¸¸×ÜÏß¡£
driver_t device_get_driver(dev)
»ñȡָÏòÆäÇý¶¯³ÌÐò½á¹¹µÄÖ¸Õë¡£
char *device_get_name(dev)
»ñÈ¡Çý¶¯³ÌÐòµÄÃû×Ö£¬ÔÚÎÒÃÇµÄ Àý×ÓÖÐΪ"xxx"¡£
int device_get_unit(dev)
»ñÈ¡µ¥ÔªºÅ£¨Óëÿ¸öÇý¶¯³ÌÐò¹ØÁªµÄÉ豸´Ó0¿ªÊ¼±àºÅ£©¡£
char *device_get_nameunit(dev)
»ñÈ¡É豸Ãû£¬°üÀ¨µ¥ÔªºÅ¡£ ÀýÈç¡°xxx0¡±£¬¡°xxx1¡± µÈ¡£
char *device_get_desc(dev)
»ñÈ¡É豸ÃèÊö¡£Í¨³£ËüÒÔÈ˿ɶÁµÄ ÐÎʽÃèÊöÉ豸µÄÈ·ÇÐÐͺš£
device_set_desc(dev,
desc)
ÉèÖÃÃèÊöÐÅÏ¢¡£ÕâʹµÃÉ豸ÃèÊöÖ¸Ïòdesc×Ö·û´®£¬
´ËºóÕâ¸ö×Ö·û´®¾Í²»Äܱ»½â³ý·ÖÅä¡£
device_set_desc_copy(dev, desc)
ÉèÖÃÃèÊöÐÅÏ¢¡£ÃèÊö±»¿½±´µ½ÄÚ²¿¶¯Ì¬·ÖÅäµÄ
»º³åÇø£¬ÕâÑùdesc×Ö·û´®ÔÚÒÔºó¿ÉÒÔ±»¸Ä±ä¶ø²»»á²úÉúÓк¦µÄ½á¹û¡£
void *device_get_softc(dev)
»ñȡָÏòÓëÉ豸¹ØÁªµÄÉ豸ÃèÊö·û £¨xxx_softc
½á¹¹£©µÄÖ¸Õë¡£
u_int32_t device_get_flags(dev)
»ñÈ¡ÅäÖÃÎļþÖÐÌØ¶¨ÓÚÉ豸µÄ ±êÖ¾¡£
¡¡¡¡¿ÉÒÔʹÓÃÒ»¸öºÜ·½±ãµÄº¯Êýdevice_printf(dev, fmt,
...)
´ÓÉ豸Çý¶¯³ÌÐòÖдòӡѶϢ¡£Ëü×Ô¶¯ÔÚѶϢǰÌí¼Ó µ¥ÔªÃûºÍðºÅ¡£
¡¡¡¡device_tµÄÕâЩ·½·¨ÔÚÎļþkern/bus_subr.c ÖÐʵÏÖ¡£
¡¡¡¡ISAÉ豸ÔÚÄÚºËÅäÖÃÎļþÖеÄÃèÊöÈçÏ£º
device xxx0 at isa? port 0x300 irq 10 drq 5 iomem 0xd0000 flags 0x1 sensitive
¡¡¡¡¶Ë¿ÚÖµ¡¢IRQÖµºÍÆäËûÖµ±»×ª»»³ÉÓëÉ豸¹ØÁªµÄ×ÊÔ´Öµ¡£¸ù¾ÝÉ豸 ¶Ô×Ô¶¯ÅäÖÃÐèÒªºÍÖ§³Ö³Ì¶ÈµÄ²»Í¬£¬ÕâЩֵÊÇ¿ÉÑ¡µÄ¡£ÀýÈ磬 ijЩÉ豸¸ù±¾²»ÐèÒª¶ÁDRQ£¬¶øÓÐЩÔòÔÊÐíÉ豸´ÓÉ豸ÅäÖö˿ڶÁÈ¡ IRQÉèÖá£Èç¹û»úÆ÷Óжà¸öISA×ÜÏߣ¬¿ÉÒÔÔÚÅäÖÃÎļþÖÐÃ÷È·Ö¸¶¨ÄÄÌõ ×ÜÏߣ¬Èçisa0»òisa1£¬ ·ñÔò½«ÔÚËùÓÐISA×ÜÏßÉÏËÑË÷É豸¡£
¡¡¡¡Ãô¸Ð(sensitive)ÊÇÒ»ÖÖ×ÊÔ´ÇëÇó£¬Ëüָʾ ±ØÐëÔÚËùÓзÇÃô¸ÐÉ豸֮ǰ̽²âÉ豸¡£´ËÌØÐÔËä±»Ö§³Ö£¬µ«Ëƺõ´Óδ ÔÚĿǰµÄÈκÎÇý¶¯³ÌÐòÖÐʹÓùý¡£
¡¡¡¡¶ÔÓÚÀϵÄISAÉ豸£¬ºÜ¶àÇé¿öÏÂÇý¶¯³ÌÐòÈÔÈ»Äܹ»Õì²âÅäÖòÎÊý¡£ µ«ÊÇϵͳÖÐÅäÖõÄÿ¸öÉ豸±ØÐë¾ßÓÐÒ»¸öÅäÖÃÐС£Èç¹ûϵͳÖÐ×°ÓÐͬһ ÀàÐ͵ÄÁ½¸öÉ豸£¬µ«¶ÔÓ¦µÄÇý¶¯³ÌÐòÈ´Ö»ÓÐÒ»¸öÅäÖÃÐУ¬ÀýÈç:
device xxx0 at isa?ÄÇôֻÓÐÒ»¸öÉ豸»á±»ÅäÖá£
¡¡¡¡µ«¶ÔÓÚÖ§³Öͨ¹ýPnP»òרÓÐÐÒé½øÐÐ×Ô¶¯Ê¶±ðµÄÉ豸£¬Ò»¸öÅäÖÃÐÐ ¾Í×ã¹»ÅäÖÃϵͳÖеÄËùÓÐÉ豸£¬ÈçÉÏÃæµÄÅäÖÃÐУ¬»òÕß¼òµ¥µØ£º
device xxx at isa?
¡¡¡¡Èç¹ûÉ豸Çý¶¯³ÌÐò¼ÈÖ§³ÖÄÜ×Ô¶¯Ê¶±ðµÄÉ豸ÓÖÖ§³ÖÀÏÉ豸£¬²¢ÇÒ Á½ÀàÉ豸ͬʱ°²×°ÔÚһ̨»úÆ÷ÉÏ£¬ÄÇôֻҪÔÚÅäÖÃÎļþÖÐÃèÊöÀÏÉ豸 ¾Í×ã¹»ÁË¡£×Ô¶¯Ê¶±ðµÄÉ豸½«±»×Ô¶¯Ìí¼Ó¡£
¡¡¡¡Èç¹ûISAÉ豸ÊÇ×Ô¶¯ÅäÖõ쬷¢ÉúµÄʼþÈçÏ£º
¡¡¡¡ËùÓÐÉ豸Çý¶¯³ÌÐòµÄʶ±ðÀý³Ì£¨°üÀ¨Ê¶±ðËùÓÐPnPÉ豸µÄPnPʶ±ð Àý³Ì£©ÒÔËæ»ú˳Ðò±»µ÷Óá£ËûÃÇʶ±ð³öÉ豸ºó¾Í°ÑÉ豸Ìí¼Óµ½ISA×ÜÏß ÉϵÄÁбíÖС£Í¨³£Çý¶¯³ÌÐòµÄʶ±ðÀý³Ì½«ÐÂÉ豸ÓëËüÃǵÄÇý¶¯ ³ÌÐò¹ØÁªÆðÀ´¡£¶øPnPʶ±ðÀý³Ì²¢²»ÖªµÀÆäËûÇý¶¯³ÌÐò£¬Òò´Ë²»Äܽ« Çý¶¯³ÌÐòÓëËüËùÌí¼ÓµÄÐÂÉ豸¹ØÁªÆðÀ´¡£
¡¡¡¡Ê¹ÓÃPnPÐÒéÈÃPnPÉ豸½øÈë˯Ãߣ¬ÒÔ·ÀÖ¹ËüÃDZ»Ì½²âΪÀÏÉ豸¡£
¡¡¡¡±»±ê¼ÇΪÃô¸Ð(sensitive)µÄ·ÇPnPÉ豸µÄ ̽²âÀý³Ì±»µ÷Óá£Èç¹û̽²âÉ豸³É¹¦£¬ÄÇô¾ÍΪÆäµ÷ÓùҽÓ(attach) Àý³Ì¡£
¡¡¡¡ËùÓзÇPnPÉ豸µÄ̽²âºÍÁ¬½ÓÀý³ÌÒÔͬÑùµÄ·½Ê½±»µ÷Óá£
¡¡¡¡PnPÉ豸´Ó˯ÃßÖлָ´¹ýÀ´£¬²¢¸øËüÃÇ·ÖÅäËùÇëÇóµÄ×ÊÔ´£ºI/O¡¢ ÄÚ´æµØÖ··¶Î§¡¢IRQºÍDRQ£¬ËùÓÐÕâЩÓëÒÑÁ¬½ÓµÄÀÏÉ豸²»»á³åÍ»¡£
¡¡¡¡¶ÔÓÚÿ¸öPnPÉ豸£¬ËùÓÐISAÉ豸Çý¶¯³ÌÐòµÄ̽²âÀý³Ì¶¼»á±»µ÷Óá£
µÚÒ»¸öÒªÇó´ËÉ豸µÄÇý¶¯³ÌÐò½«±»Á¬½Ó¡£¶à¸öÇý¶¯³ÌÐòÒÔ²»Í¬µÄÓÅÏÈȨ
ÒªÇóÒ»¸öÉ豸µÄÇé¿öÊÇ¿ÉÄܵģ¬ÕâÖÖÇé¿öÏ£¬¾ßÓÐ×î¸ßÓÅÏÈȨµÄÇý¶¯³ÌÐò
½«»ñʤ¡£Ì½²âÀý³Ì±ØÐëµ÷ÓÃISA_PNP_PROBE()
½« ÕæÊµµÄPnP
IDºÍÇý¶¯³ÌÐòÖ§³ÖµÄIDÁбí×÷±È½Ï£¬Èç¹ûID²»ÔÚ±íÖÐÔò·µ»Ø
ʧ°Ü¡£ÕâÒâζ×Åÿ¸öÇý¶¯³ÌÐò£¬°üÀ¨²»Ö§³ÖÈκÎPnPÉ豸µÄÇý¶¯³ÌÐò£¬
¶¼±ØÐë¶Ôδ֪µÄPnPÉ豸ÎÞÌõ¼þµ÷Óà ISA_PNP_PROBE()
£¬¶ÔÓÚδ֪É豸£¬ ÖÁÉÙÒªÓÃÒ»¸ö ¿ÕµÄPnP
ID±íµ÷Óò¢·µ»ØÊ§°Ü¡£
¡¡¡¡Ì½²âÀý³ÌÓöµ½´íÎóʱ»á·µ»ØÒ»¸öÕýÖµ£¨´íÎóÂ룩£¬³É¹¦Ê±·µ»Ø Áã»ò¸ºÖµ¡£
¡¡¡¡¸ºµÄ·µ»ØÖµÓÃÓÚPnPÉ豸֧³Ö¶à¸ö½Ó¿ÚµÄÇé¿ö¡£ÀýÈ磬ÀϵļæÈÝ½Ó¿Ú ºÍеĸ߼¶½Ó¿Úͨ¹ý²»Í¬µÄÇý¶¯³ÌÐòÀ´Ìṩ֧³Ö¡£Á½¸öÇý¶¯³ÌÐò ¶¼Õì²âÉ豸¡£ÔÚ̽²âÀý³ÌÖзµ»Ø½Ï¸ßÖµµÄÇý¶¯³ÌÐòÓÅÏÈ£¨»»¾ä»°Ëµ£¬ ·µ»Ø0µÄÇý¶¯³ÌÐò¾ßÓÐ×î¸ßµÄÓÅÏȼ¶£¬·µ»Ø-1µÄÆä´Î£¬·µ»Ø-2µÄ¸üÔÚ Æäºó£¬Èç´ËÏÂÈ¥£©¡£Èç¹û¶à¸öÇý¶¯³ÌÐò·µ»ØÏàͬµÄÖµ£¬ÄÇô×îÏȵ÷ÓÃµÄ »ñʤ¡£Òò´Ë£¬Èç¹ûÇý¶¯³ÌÐò·µ»Ø0£¬¾Í»ù±¾Äܹ»È·ÐÅËü»ñµÃÓÅÏÈȨÖٲá£
¡¡¡¡Éè±¸ÌØ¶¨µÄʶ±ðÀý³ÌÒ²Äܹ»½«Ò»Àà¶ø²»Êǵ¥¸öÇý¶¯³ÌÐòÖ¸ÅɸøÉ豸¡£ ¾ÍÏóʹÓÃPnPµÄÇé¿öÒ»Ñù£¬¶ÔÓÚijһÉ豸£¬»á̽²âÕâÒ»ÀàÖÐËùÓеÄÇý¶¯³ÌÐò¡£ ÓÉÓÚÕâ¸öÌØÐÔÔÚÈκÎÏÖ´æµÄÇý¶¯³ÌÐòÖÐ×ܾùδʵÏÖ£¬¹Ê±¾ÎĵµÖв»ÔÙÓèÒÔ ¿¼ÂÇ¡£
¡¡¡¡ÓÉÓÚ̽²âÀÏÉ豸µÄʱºòPnPÉ豸±»½ûÓã¬ËüÃDz»»á±»Á¬½ÓÁ½´Î £¨Ò»´Î×÷ΪÀÏÉ豸£¬Ò»´Î×÷ΪPnP£©¡£µ«Èç¹ûʶ±ðÀý³ÌÉ豸Ïà¹ØµÄ£¬ ÕâÖÖÇé¿öÏÂÉ豸Çý¶¯³ÌÐòÓÐÔðÈÎÈ·±£Í¬Ò»É豸²»»á±»É豸Çý¶¯³ÌÐò Á¬½ÓÁ½´Î£ºÒ»´Î×÷ΪÀϵÄÓÉÓû§ÅäÖõģ¬Ò»´Î×÷Ϊ×Ô¶¯Ê¶±ðµÄ¡£
¡¡¡¡¶ÔÓÚ×Ô¶¯Ê¶±ðµÄÉ豸£¨°üÀ¨PnPºÍÉè±¸ÌØ¶¨µÄ£©µÄÁíÒ»¸öʵ¼ù½áÂÛÊÇ£¬ ²»ÄÜ´ÓÄÚºËÅäÖÃÎļþÖÐÏòËüÃÇ´«µÝÆì±ê¡£Òò´ËËüÃDZØÐëҪô¸ù±¾²»Ê¹Óà Æì±ê£¬ÒªÃ´ÎªËùÓÐ×Ô¶¯Ê¶±ðµÄÉ豸ʹÓõ¥ÔªºÅΪ0µÄÉ豸µÄÆì±ê£¬»òÕß Ê¹ÓÃsysctl½Ó¿Ú¶ø²»ÊÇÆì±ê¡£
¡¡¡¡Í¨¹ýʹÓú¯Êý×åresource_query_*()
ºÍ resource_*_value()
Ö±½Ó·ÃÎÊÅäÖÃ×ÊÔ´£¬
´Ó¶ø¿ÉÒÔÌṩÆäËû²»³£ÓõÄÅäÖá£ËüÃǵÄʵÏÖλÓÚ kern/subr_bus.c¡£ÀϵÄIDE´ÅÅÌÇý¶¯Æ÷ i386/isa/wd.c°üº¬ÕâÑùʹÓõÄÀý×Ó¡£
µ«±ØÐëÓÅÏÈʹÓÃÅäÖõıê×¼·½·¨¡£½«½âÎöÅäÖÃ×ÊÔ´ÕâÀàÊÂÇéÁô¸ø ×ÜÏßÅäÖôúÂë¡£
¡¡¡¡Óû§Ð´Èëµ½ÄÚºËÅäÖÃÎļþÖеÄÐÅÏ¢±»×÷ΪÅäÖÃ×ÊÔ´´¦Àí£¬²¢´«µÝµ½Äںˡ£
×ÜÏßÅäÖôúÂë½âÎöÕⲿ·ÖÐÅÏ¢²¢½«Æäת»»Îª½á¹¹device_tµÄÖµºÍÓëÖ®
¹ØÁªµÄ×ÜÏß×ÊÔ´¡£¶ÔÓÚ¸´ÔÓÇé¿öϵÄÅäÖã¬Çý¶¯³ÌÐò¿ÉÒÔÖ±½ÓʹÓà resource_*
º¯Êý·ÃÎÊÅäÖÃ×ÊÔ´¡£ È»¶ø£¬ ͨ³£¼È²»ÐèÒªÒ²²»ÍƼöÕâÑù×ö£¬
Òò´ËÕâ¶ù²»ÔÙ½øÒ»²½ÌÖÂÛÕâ¸öÎÊÌâ¡£
¡¡¡¡×ÜÏß×ÊÔ´Óëÿ¸öÉ豸Ïà¹ØÁª¡£Í¨¹ýÀàÐͺÍÀàÐÍÖеÄÊý×Ö±êʶËüÃÇ¡£ ¶ÔÓÚISA×ÜÏߣ¬¶¨ÒåÁËÏÂÃæµÄÀàÐÍ£º
SYS_RES_IRQ - ÖжϺÅ
SYS_RES_DRQ - ISA DMAͨµÀºÅ
SYS_RES_MEMORY - Ó³É䵽ϵͳÄÚ´æ¿Õ¼ä µÄÉ豸ÄÚ´æµÄ·¶Î§
SYS_RES_IOPORT - É豸I/O¼Ä´æÆ÷µÄ·¶Î§
¡¡¡¡ÀàÐÍÄÚµÄö¾Ù´Ó0¿ªÊ¼£¬Òò´ËÈç¹ûÉ豸ÓÐÁ½¸öÄÚ´æÇøÓò£¬ËüµÄ SYS_RES_MEMORY ÀàÐ͵Ä×ÊÔ´±àºÅΪ0ºÍ1¡£ ×ÊÔ´ÀàÐÍÓëCÓïÑÔµÄÀàÐÍÎ޹أ¬ ËùÓÐ×ÊÔ´Öµ¾ßÓÐCÓïÑÔ unsigned long ÀàÐÍ£¬²¢ÇÒ±ØÒªÊ±±ØÐë½øÐÐÀàÐÍÇ¿ÖÆ×ª»» (cast)¡£×ÊÔ´ºÅ²»±ØÁ¬Ðø£¬ ¾¡¹Ü¶ÔÓÚISAËüÃÇÒ»°ãÊÇÁ¬ÐøµÄ¡£ISAÉ豸ÔÊÐíµÄ×ÊÔ´±àºÅΪ£º
IRQ: 0-1 DRQ: 0-1 MEMORY: 0-3 IOPORT: 0-7
¡¡¡¡ËùÓÐ×ÊÔ´±»±íʾΪ´øÓÐÆðʼֵºÍ¼ÆÊýµÄ·¶Î§¡£¶ÔÓÚIRQºÍDRQ×ÊÔ´£¬ ¼ÆÊýÒ»°ãµÈÓÚ1¡£ÄÚ´æµÄÖµÒýÓÃÎïÀíµØÖ·¡£
¡¡¡¡¶Ô×ÊÔ´Äܹ»Ö´ÐÐÈýÖÖÀàÐ͵͝×÷£º
set/get
allocate/release
activate/deactivate
¡¡¡¡SetÉèÖÃ×ÊԴʹÓõķ¶Î§¡£Allocation±£Áô³öÇëÇóµÄ·¶Î§£¬Ê¹µÃ ÆäËüÉ豸²»ÄÜÔÙÕ¼Ó㨲¢¼ì²é´Ë·¶Î§Ã»Óб»ÆäËüÉ豸ռÓã©¡£ ActivationÖ´ÐбØÒªµÄ¶¯×÷ʹµÃÇý¶¯³ÌÐò¿ÉÒÔ·ÃÎÊ×ÊÔ´£¨ÀýÈ磬¶ÔÓÚ Äڴ棬Ëü½«±»Ó³Éäµ½Äں˵ÄÐéÄâµØÖ·¿Õ¼ä£©¡£
¡¡¡¡²Ù×÷×ÊÔ´µÄº¯ÊýÓУº
int bus_set_resource(device_t dev, int type, int rid, u_long
start, u_long count)
Ϊ×ÊÔ´ÉèÖ÷¶Î§¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£ Ò»°ã´Ëº¯ÊýÖ»ÓÐÔÚtype£¬ rid£¬start»ò countÖ®Ò»µÄÖµ³¬³öÁËÔÊÐíµÄ·¶Î§²Å»á ·µ»Ø´íÎó¡£
dev - Çý¶¯³ÌÐòµÄÉ豸
type - ×ÊÔ´ÀàÐÍ£¬SYS_RES_*
rid - ÀàÐÍÄÚ²¿µÄ×ÊÔ´ºÅ£¨ID£©
start, count - ×ÊÔ´·¶Î§
int bus_get_resource(device_t dev, int type, int rid, u_long
*startp, u_long *countp)
È¡µÃ×ÊÔ´·¶Î§¡£³É¹¦Ôò·µ»Ø0£¬Èç¹û×ÊÔ´ÉÐ䶨ÒåÔò·µ»Ø´íÎóÂë¡£
u_long bus_get_resource_start(device_t dev, int type, int rid)
u_long bus_get_resource_count (device_t dev, int type, int rid)
±ã½Ýº¯Êý£¬Ö»ÓÃÀ´»ñÈ¡start»òcount¡£³ö´íµÄÇé¿öÏ·µ»Ø0£¬ Òò´ËÈç¹û0ÊÇ×ÊÔ´µÄstartºÏ·¨ÖµÖ®Ò»£¬½«ÎÞ·¨Çø·Ö·µ»Ø µÄ0ÊÇ·ñָʾ´íÎó¡£ÐÒÔ˵ÄÊÇ£¬¶ÔÓÚ¸½¼ÓÇý¶¯³ÌÐò£¬Ã»ÓÐISA×ÊÔ´µÄ startÖµ´Ó0¿ªÊ¼¡£
void bus_delete_resource(device_t dev, int type, int
rid)
ɾ³ý×ÊÔ´£¬ÁîÆä䶨Òå¡£
struct resource * bus_alloc_resource(device_t dev, int type,
int *rid, u_long start, u_long end, u_long count, u_int flags)
ÔÚstartºÍendÖ®¼äûÓб»ÆäËüÉ豸ռÓõĵط½°´countÖµ
µÄ·¶Î§·ÖÅäÒ»¸ö×ÊÔ´¡£²»¹ý£¬²»Ö§³Ö¶ÔÆë¡£Èç¹û×ÊÔ´ÉÐδ±»ÉèÖã¬
Ôò×Ô¶¯´´½¨Ëü¡£startΪ0£¬endΪ~0£¨È«1£©µÄÕâ¶ÔÌØÊâÖµ Òâζ×űØÐëʹÓÃÒÔǰͨ¹ý bus_set_resource()
ÉèÖõĹ̶¨Öµ£º
startºÍcount¾ÍÊÇËüÃÇ×Ô¼º£¬end=(start+count)£¬ÕâÖÖÇé¿öÏ£¬
Èç¹ûÒÔǰ×ÊԴûÓж¨Ò壬Ôò·µ»Ø´íÎó¡£¾¡¹Üridͨ¹ýÒýÓô«µÝ£¬
µ«Ëü²¢²»±»ISA×ÜÏßµÄ×ÊÔ´·ÖÅä´úÂëÉèÖã¨ÆäËü×ÜÏß¿ÉÄÜʹÓò»Í¬µÄ ·½·¨²¢¿ÉÄÜÐÞ¸ÄËü£©¡£
¡¡¡¡Æì±êÊÇÒ»¸öλӳÉ䣬µ÷ÓÃÕ߸ÐÐËȤµÄÓУº
RF_ACTIVE - ʹµÃ×ÊÔ´·ÖÅäºó ±»×Ô¶¯¼¤»î¡£
RF_SHAREABLE - ×ÊÔ´¿ÉÒÔͬʱ ±»¶à¸öÇý¶¯³ÌÐò¹²Ïí¡£
RF_TIMESHARE - ×ÊÔ´¿ÉÒÔ±»¶à¸öÇý¶¯ ³ÌÐò·Öʱ¹²Ïí£¬Ò²¾ÍÊÇ˵£¬±»¶à¸öÇý¶¯³ÌÐòͬʱ·ÖÅ䣬µ«ÈκΠ¸ø¶¨Ê±¼äÖ»Äܱ»ÆäÖÐÒ»¸ö¼¤»î¡£
³ö´í·µ»Ø0¡£±»·ÖÅäµÄÖµ¿ÉÒÔʹÓà rhand_*()
´Ó·µ»ØµÄ¾ä±ú»ñµÃ¡£
int bus_release_resource(device_t dev, int type, int rid,
struct resource *r)
ÊÍ·Å×ÊÔ´£¬rΪbus_alloc_resource()
·µ»ØµÄ¾ä±ú¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£
int bus_activate_resource(device_t dev, int type, int rid,
struct resource *r)
int bus_deactivate_resource(device_t
dev, int type, int rid, struct resource *r)
¼¤»î»ò½ûÓÃ×ÊÔ´¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£Èç¹û ×ÊÔ´±»·Öʱ¹²ÏíÇÒµ±Ç°±»ÁíÒ»Çý¶¯³ÌÐò¼¤»î£¬Ôò·µ»Ø EBUSY¡£
int bus_setup_intr(device_t dev, struct resource *r, int flags,
driver_intr_t *handler, void *arg, void **cookiep)
int
bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
¹ØÁª/·ÖÀëÖжϴ¦Àí³ÌÐòÓëÉ豸¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò ·µ»Ø´íÎóÂë¡£
r - ±»¼¤»îµÄÃèÊöIRQµÄ×ÊÔ´¾ä±ú¡£
flags - ÖжÏÓÅÏȼ¶£¬ÈçÏÂÖ®Ò»£º
INTR_TYPE_TTY
- ÖÕ¶ËºÍÆäËü ÀàËÆµÄ×Ö·ûÀàÐÍÉ豸¡£Ê¹ÓÃ
spltty()
ÆÁ±ÎËüÃÇ¡£
(INTR_TYPE_TTY | INTR_TYPE_FAST)
-
ÊäÈ뻺³å½ÏСµÄÖÕ¶ËÀàÐÍ É豸£¬¶øÇÒÊäÈëÉϵÄÊý¾Ý¶ªÊ§ºÜ¹Ø¼ü£¨ÀýÈçÀÏʽ´®¿Ú£©¡£
ʹÓÃspltty()
ÆÁ±ÎËüÃÇ¡£
INTR_TYPE_BIO
- ¿éÀàÐÍÉ豸£¬ ²»°üÀ¨CAM¿ØÖÆÆ÷Éϵġ£Ê¹ÓÃ
splbio()
ÆÁ±ÎËüÃÇ¡£
INTR_TYPE_CAM
- CAM £¨Í¨Ó÷ÃÎÊ ·½·¨Common Access
Method£©×ÜÏß¿ØÖÆÆ÷¡£Ê¹Óà splcam()
ÆÁ±ÎËüÃÇ¡£
INTR_TYPE_NET
- ÍøÂç½Ó¿Ú ¿ØÖÆÆ÷¡£Ê¹Óà splimp()
ÆÁ±ÎËüÃÇ¡£
INTR_TYPE_MISC
- ¸÷ÖÖÆäËüÉ豸¡£³ýÁËͨ¹ý splhigh()
ûÓÐÆäËü·½·¨ÆÁ±ÎËüÃÇ¡£ splhigh()
ÆÁ±ÎËùÓÐÖжϡ£
¡¡¡¡µ±Öжϴ¦Àí³ÌÐòÖ´ÐÐʱ£¬Æ¥ÅäÆäÓÅÏȼ¶µÄËùÓÐÆäËüÖж϶¼±»ÆÁ±Î£¬ ΨһµÄÀýÍâÊÇMISC¼¶±ð£¬Ëü²»»áÆÁ±ÎÆäËüÖжϣ¬Ò²²»»á±»ÆäËüÖÐ¶Ï ÆÁ±Î¡£
handler - Ö¸Ïò´¦Àí³ÌÐòµÄÖ¸Õ룬
ÀàÐÍdriver_intr_t±»¶¨ÒåΪvoid driver_intr_t(void *)
arg - ´«µÝ¸ø´¦Àí³ÌÐòµÄ²ÎÁ¿£¬±êʶ ÌØ¶¨É豸¡£ÓÉ´¦Àí³ÌÐò½«Ëü´Óvoid*ת»»ÎªÈκÎʵ¼ÊÀàÐÍ¡£ISA Öжϴ¦Àí³ÌÐòµÄ¾ÉÔ¼¶¨ÊÇʹÓõ¥ÔªºÅ×÷Ϊ²ÎÁ¿£¬ÐÂÔ¼¶¨£¨ÍƼö£© ʹÓÃÖ¸ÏòÉ豸softc½á¹¹µÄÖ¸Õë¡£
cookie[p] - ´Ó setup()
½ÓÊÕµÄÖµ£¬µ±´«µÝ¸ø teardown()
ʱÓÃÓÚ±êʶ´¦Àí³ÌÐò¡£
¡¡¡¡¶¨ÒåÁËÈô¸É·½·¨À´²Ù×÷×ÊÔ´¾ä±ú(struct resource *)¡£É豸Çý¶¯ ³ÌÐò±àдÕ߸ÐÐËȤµÄÓУº
u_long rman_get_start(r) u_long rman_get_end(r)
È¡µÃ±»·ÖÅäµÄ×ÊÔ´·¶Î§µÄÆðʼºÍ½áÊø¡£
void *rman_get_virtual(r)
È¡µÃ
±»¼¤»îµÄÄÚ´æ×ÊÔ´µÄÐ鵨ַ¡£
¡¡¡¡ºÜ¶àÇé¿öÏÂÉ豸Çý¶¯³ÌÐòºÍÉ豸֮¼äµÄÊý¾Ý½»»»ÊÇͨ¹ýÄÚ´æ ½øÐеġ£ÓÐÁ½ÖÖ¿ÉÄܵıäÌ壺
¡¡¡¡(a) ÄÚ´æÎ»ÓÚÉ豸¿¨ÉÏ
¡¡¡¡(b) ÄÚ´æÎª¼ÆËã»úµÄÖ÷ÄÚ´æ
¡¡¡¡Çé¿ö(a)ÖУ¬Çý¶¯³ÌÐò¿ÉÄÜÐèÒªÔÚ¿¨ÉϵÄÄÚ´æÓëÖ÷´æÖ®¼äÀ´»Ø
¿½±´Êý¾Ý¡£ÎªÁ˽«¿¨ÉϵÄÄÚ´æÓ³Éäµ½Äں˵ÄÐ鵨ַ¿Õ¼ä£¬¿¨ÉÏÄÚ´æµÄ
ÎïÀíµØÖ·ºÍ³¤¶È±ØÐë±»¶¨ÒåΪSYS_RES_MEMORY×ÊÔ´¡£
È»ºó×ÊÔ´¾Í¿ÉÒÔ±»·ÖÅä²¢¼¤»î£¬ËüµÄÐéµØÖ·Í¨¹ýʹÓà rman_get_virtual()
»ñÈ¡¡£½ÏÀϵÄÇý¶¯³ÌÐò ½«º¯Êýpmap_mapdev()
ÓÃÓÚ´ËÄ¿µÄ£¬ÏÖÔÚ
²»Ó¦µ±ÔÙÖ±½ÓʹÓô˺¯Êý¡£ËüÒѳÉΪ×ÊÔ´¼¤»îµÄÒ»¸öÄÚ²¿²½Öè¡£
¡¡¡¡´ó¶àÊýISA¿¨µÄÄÚ´æÅäÖÃΪÎïÀíµØÎ»ÓÚ640KB-1MB·¶Î§Ö®¼äµÄ ij¸öλÖá£Ä³Ð©ISA¿¨ÐèÒª¸ü´óµÄÄڴ淶Χ£¬Î»ÓÚ16MÒÔϵÄij¸ö λÖã¨ÓÉÓÚISA×ÜÏßÉÏ24λµØÖ·ÏÞÖÆ£©¡£ÕâÖÖÇé¿öÏ£¬Èç¹û»úÆ÷ÓÐ ±ÈÉ豸ÄÚ´æµÄÆðʼµØÖ·¸ü¶àµÄÄڴ棨»»¾ä»°Ëµ£¬ËüÃÇÖØµþ£©£¬Ôò ±ØÐëÔÚ±»É豸ʹÓõÄÄÚ´æÆðʼµØÖ·´¦ÅäÖÃÒ»¸öÄÚ´æ¿Õ¶´¡£Ðí¶à BIOSÔÊÐíÔÚÆðʼÓÚ14MB»ò15MB´¦ÅäÖÃ1MµÄÄÚ´æ¿Õ¶´¡£Èç¹ûBIOS ÕýÈ·µØ±¨¸æÄÚ´æ¿Õ¶´£¬FreeBSD¾ÍÄܹ»ÕýÈ·´¦ÀíËüÃÇ£¨´ËÌØÐÔ ÔÚÀÏBIOSÉÏ¿ÉÄÜ»á³öÎÊÌ⣩¡£
¡¡¡¡Çé¿ö(b)ÖУ¬Ö»ÊÇÊý¾ÝµÄµØÖ·±»·¢Ë͵½É豸£¬É豸ʹÓÃDMAʵ¼Ê ·ÃÎÊÖ÷´æÖеÄÊý¾Ý¡£´æÔÚÁ½¸öÏÞÖÆ£ºÊ×ÏÈ£¬ISA¿¨Ö»ÄÜ·ÃÎÊ16MBÒÔÏ µÄÄÚ´æ¡£Æä´Î£¬Ð鵨ַ¿Õ¼äÖÐÁ¬ÐøµÄÒ³ÃæÔÚÎïÀíµØÖ·¿Õ¼äÖпÉÄܲ» Á¬Ðø£¬É豸¿ÉÄܲ»µÃ²»½øÐзÖÉ¢/ÊÕ¼¯²Ù×÷¡£×ÜÏß×ÓϵͳΪÕâЩÎÊÌâ ÌṩÏÖ³ÉÏֳɵĽâ¾ö°ì·¨£¬Ê£ÏµıØÐëÓÉÇý¶¯³ÌÐò×Ô¼ºÍê³É¡£
¡¡¡¡DMAÄÚ´æ·ÖÅäʹÓÃÁËÁ½¸ö½á¹¹£¬ bus_dma_tag_t
ºÍ
bus_dmamap_t
¡£
±êÇ©£¨tag£©ÃèÊöÁËDMAÄÚ´æÒªÇóµÄÌØÐÔ¡£Ó³É䣨map£©±íʾ°´ÕÕÕâЩ
ÌØÐÔ·ÖÅäµÄÄÚ´æ¿é¡£¶à¸öÓ³Éä¿ÉÒÔÓëͬһ±êÇ©¹ØÁª¡£
¡¡¡¡±êÇ©°´ÕÕ¶ÔÌØÐԵļ̳жø±»×éÖ¯³ÉÊ÷ÐͲã´Î½á¹¹¡£×Ó±êÇ©¼Ì³Ð¸¸ ±êÇ©µÄËùÓÐÒªÇ󣬿ÉÒÔÁîÆä¸üÑϸñ£¬µ«²»ÔÊÐí·Å¿íÒªÇó¡£
¡¡¡¡Ò»°ãµØ£¬Ã¿¸öÉ豸µ¥Ôª´´½¨Ò»¸ö¶¥²ã±êÇ©£¨Ã»Óи¸±êÇ©£©¡£Èç¹û ÿ¸öÉ豸ÐèÒª²»Í¬ÒªÇóµÄÄÚ´æÇø£¬ÔòΪÿ¸öÄÚ´æÇø¶¼»á´´½¨Ò»¸ö±êÇ©£¬ÕâЩ ±êÇ©×÷Ϊ¸¸±êÇ©µÄº¢×Ó¡£
¡¡¡¡Ê¹ÓñêÇ©´´½¨Ó³ÉäµÄ·½·¨ÓÐÁ½ÖÖ¡£
¡¡¡¡ÆäÒ»£¬·ÖÅäÒ»´ó¿é·ûºÏ±êǩҪÇóµÄÁ¬ÐøÄڴ棨ÒÔºó¿ÉÒÔ±»ÊÍ·Å£©¡£ ÕâÒ»°ãÓÃÓÚ·ÖÅäΪÁËÓëÉ豸ͨÐŶø´æÔÚÏà¶Ô½Ï³¤Ê±¼äµÄÄÇЩÄÚ´æÇø¡£ ½«ÕâÑùµÄÄÚ´æ¼ÓÔØµ½Ó³ÉäÖзdz£ÈÝÒ×£ºËü×ÜÊDZ»¿´×÷λÓÚÊʵ±ÎïÀí Äڴ淶ΧµÄÒ»Õû¿é¡£
¡¡¡¡Æä¶þ£¬½«ÐéÄâÄÚ´æÖеÄÈÎÒâÇøÓò¼ÓÔØµ½Ó³ÉäÖС£ÕâÆ¬ÄÚ´æµÄ ÿһҳ¶¼±»¼ì²é£¬¿´ÊÇ·ñ·ûºÏÓ³ÉäµÄÒªÇó¡£ÈçºÎ·ûºÏÔòÁôÔÚÔʼλÖᣠÈç¹û²»·ûºÏÔò·ÖÅäÒ»¸öеķûºÏÒªÇóµÄ ¡°·´µ¯Ò³Ãæ(bounce page)¡±£¬ÓÃ×÷ÖÐ¼ä´æ´¢¡£ µ±´Ó²»·ûºÏµÄÔÊ¼Ò³ÃæÐ´ÈëÊý¾Ýʱ£¬Êý¾ÝÊ×Ïȱ»¿½±´µ½·´µ¯Ò³Ã棬 È»ºó´Ó·´µ¯Ò³Ãæ´«µÝµ½É豸¡£µ±¶Áȡʱ£¬Êý¾Ý½«»á´ÓÉ豸µ½·´µ¯Ò³Ã棬 È»ºó±»¿½±´µ½ËüÃDz»·ûºÏµÄÔÊ¼Ò³Ãæ¡£ÔʼºÍ·´µ¯Ò³ÃæÖ®¼äµÄ¿½±´ ´¦Àí±»³Æ×÷ͬ²½¡£ÕâÒ»°ãÓÃÓÚµ¥´Î´«ÊäµÄ»ù´¡Ö®ÉÏ£ºÃ¿´Î´«Êäʱ ¼ÓÔØ»º³åÇø£¬Íê³É´«Êä£¬Ð¶ÔØ»º³åÇø¡£
¡¡¡¡¹¤×÷ÔÚDMAÄÚ´æÉϵĺ¯ÊýÓУº
int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t
alignment, bus_size_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, bus_dma_filter_t
*filter, void *filterarg, bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int
flags, bus_dma_tag_t *dmat)
´´½¨Ð±êÇ©¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£
parent - ¸¸±êÇ©»òÕßNULL£¬ NULLÓÃÓÚ´´½¨¶¥²ã±êÇ©¡£
alignment -
¶Ô½«Òª·ÖÅ䏸±êÇ©µÄÄÚ´æÇøµÄ¶ÔÆëÒªÇ󡣡°no specific alignment¡±Ê±ÖµÎª1¡£½öÓ¦ÓÃÓÚÒÔºóµÄ
bus_dmamem_alloc()
¶ø²»ÊÇ bus_dmamap_create()
µ÷Óá£
boundary - ÎïÀíµØÖ·±ß½ç£¬
·ÖÅäÄÚ´æÊ±²»ÄÜ´©¹ý¡£¶ÔÓÚ¡°no boundary¡± ʹÓÃ0¡£½öÓ¦ÓÃÓÚÒÔºóµÄ bus_dmamem_alloc()
¶ø²»ÊÇ bus_dmamap_create()
µ÷Óá£
±ØÐëΪ2µÄ³Ë·½¡£Èç¹û¼Æ»®ÒԷDzãµþDMA·½Ê½Ê¹ÓÃÄڴ棨Ҳ¾ÍÊÇ˵£¬ DMAµØÖ·ÓÉISA
DMA¿ØÖÆÆ÷Ìṩ¶ø²»ÊÇÉ豸×ÔÉí£©£¬ÔòÓÉÓÚDMAÓ²¼þ ÏÞÖÆ£¬±ß½ç±ØÐë²»ÄÜ´óÓÚ64KB (64*1024)¡£
lowaddr, highaddr - Ãû×ÖÉÔ΢ ÓÐЩÎ󵼡£ÕâЩֵÓÃÓÚÏÞÖÆ¿ÉÓÃÓÚÄÚ´æ·ÖÅäµÄÎïÀíµØÖ·µÄÔÊÐí ·¶Î§¡£ÆäÈ·Çк¬Òå¸ù¾ÝÒÔºó²»Í¬µÄʹÓöøÓÐËù²»Í¬¡£
¶ÔÓÚbus_dmamem_alloc()
£¬
´Ó0µ½lowaddr-1µÄËùÓеØÖ·±»ÊÓΪÔÊÐí£¬¸ü¸ßµÄµØÖ·²»ÔÊÐí ʹÓá£
¶ÔÓÚbus_dmamap_create()
£¬ ±ÕÇø¼ä[lowaddr;
highaddr]Ö®ÍâµÄËùÓеØÖ·±»ÊÓΪ¿É·ÃÎÊ¡£
·¶Î§Ö®ÄڵĵØÖ·Ò³Ãæ±»´«µÝ¸ø¹ýÂ˺¯Êý£¬ÓÉËü¾ö¶¨ÊÇ·ñ¿É·ÃÎÊ¡£
Èç¹ûûÓÐÌṩ¹ýÂ˺¯Êý£¬ÔòÕû¸öÇø¼ä±»ÊÓΪ²»¿É·ÃÎÊ¡£
¶ÔÓÚISAÉ豸£¬Õý³£Öµ£¨Ã»ÓйýÂ˺¯Êý£©Îª£º
lowaddr = BUS_SPACE_MAXADDR_24BIT
highaddr = BUS_SPACE_MAXADDR
filter, filterarg - ¹ýÂ˺¯Êý¼°Æä
²ÎÊý¡£Èç¹ûfilterΪNULL£¬Ôòµ±µ÷Óà bus_dmamap_create()
ʱ£¬Õû¸öÇø¼ä [lowaddr, highaddr]±»ÊÓΪ²»¿É·ÃÎÊ¡£
·ñÔò£¬Çø¼ä[lowaddr; highaddr]ÄÚµÄÿ¸ö±»ÊÔͼ·ÃÎʵÄÒ³ÃæµÄ
ÎïÀíµØÖ·±»´«µÝ¸ø¹ýÂ˺¯Êý£¬ÓÉËü¾ö¶¨ÊÇ·ñ¿É·ÃÎÊ¡£¹ýÂ˺¯ÊýµÄ ÔÐÍΪ£ºint filterfunc(void *arg, bus_addr_t paddr)
¡£µ±Ò³Ãæ¿ÉÒÔ±»·ÃÎÊʱËü±ØÐë
·µ»Ø0£¬·ñÔò·µ»Ø·ÇÁãÖµ¡£
maxsize - ͨ¹ý´Ë±êÇ©¿ÉÒÔ·ÖÅäµÄ ×î´óÄÚ´æÖµ£¨ÒÔ×ֽڼƣ©¡£ÓÐʱÕâ¸öÖµºÜÄѹÀË㣬»òÕß¿ÉÒÔÈÎÒâ´ó£¬ ÕâÖÖÇé¿öÏ£¬¶ÔÓÚISAÉ豸Õâ¸öÖµ¿ÉÒÔÉèΪ BUS_SPACE_MAXSIZE_24BIT¡£
nsegments - É豸֧³ÖµÄ·ÖÉ¢/ÊÕ¼¯¶Î µÄ×î´óÊýÄ¿¡£Èç¹û²»¼ÓÏÞÖÆ£¬ÔòʹÓÃÓ¦µ±Ê¹ÓÃÖµ BUS_SPACE_UNRESTRICTED¡£ ½¨Òé¶Ô¸¸±êǩʹÓÃÕâ¸öÖµ£¬¶øÎª×ÓËï±êǩָ¶¨Êµ¼ÊÏÞÖÆ¡£ nsegmentsÖµµÈÓÚ BUS_SPACE_UNRESTRICTED µÄ±êÇ©²»ÄÜÓÃÓÚʵ¼Ê¼ÓÔØÓ³É䣬½ö¿ÉÒÔ½«ËüÃÇ×÷Ϊ¸¸±êÇ©¡£ nsetments µÄʵ¼ÊÏÞÖÆ´óԼΪ250-300£¬ÔٸߵÄÖµ½«µ¼ÖÂÄں˶ÑÕ»Òç³ö£¨Ó²¼þ ÎÞ·¨Õý³£Ö§³ÖÄÇô¶àµÄ·ÖÉ¢/ÊÕ¼¯»º³åÇø£©¡£
maxsegsz - É豸֧³ÖµÄ·ÖÉ¢/ÊÕ¼¯¶Î µÄ×î´ó³ß´ç¡£¶ÔÓÚISAÉ豸µÄ×î´óֵΪ BUS_SPACE_MAXSIZE_24BIT¡£
flags - Æì±êµÄλͼ¡£¸ÐÐËȤµÄÆì±ê Ö»ÓУº
BUS_DMA_ALLOCNOW - ´´½¨±êǩʱ ÇëÇó·ÖÅäËùÓпÉÄÜÓõ½µÄ·´ÉäÒ³Ãæ¡£
BUS_DMA_ISA - ±È½ÏÉñÃØµÄÒ»¸ö±êÖ¾£¬ ½öÓÃÓÚAlpha»úÆ÷¡£i386»úÆ÷ûÓж¨ÒåËü¡£Alpha»úÆ÷µÄËùÓÐISAÉ豸 ¶¼Ó¦µ±Ê¹ÓÃÕâ¸ö±êÖ¾£¬µ«Ëƺõ»¹Ã»ÓÐÕâÑùµÄÇý¶¯³ÌÐò¡£
dmat - Ö¸Ïò·µ»ØµÄбêÇ©µÄ´æ´¢µÄ Ö¸Õë¡£
int bus_dma_tag_destroy(bus_dma_tag_t dmat)
Ïú»Ù±êÇ©¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£
dmat - ±»Ïú»ÙµÄ±êÇ©¡£
int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int
flags, bus_dmamap_t *mapp)
·ÖÅä±êÇ©ËùÃèÊöµÄÒ»¿éÁ¬ÐøÄÚ´æÇø¡£±»·ÖÅäµÄÄÚ´æµÄ´óСΪ±êÇ©µÄ
maxsize¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£µ÷Óýá¹û±»ÓÃÓÚ»ñÈ¡ÄÚ´æµÄ
ÎïÀíµØÖ·£¬µ«ÔÚ´Ë֮ǰ±ØÐëÓÃbus_dmamap_load()
½«Æä¼ÓÔØ¡£
dmat - ±êÇ©
vaddr - Ö¸Ïò´æ´¢µÄÖ¸Õ룬¸Ã´æ´¢¿Õ¼ä ÓÃÓÚ·µ»ØµÄ·ÖÅäÇøÓòµÄÄÚºËÐ鵨ַ¡£
flags - Æì±êµÄλͼ¡£Î¨Ò»¸ÐÐËȤµÄÆì±êΪ£º
BUS_DMA_NOWAIT - Èç¹ûÄÚ´æ²»ÄÜ Á¢¼´¿ÉÓÃÔò·µ»Ø´íÎó¡£Èç¹û´Ë±ê־ûÓÐÉèÖã¬ÔòÔÊÐíÀý³Ì ˯Ãߣ¬Ö±µ½ÄÚ´æ¿ÉÓÃΪֹ¡£
mapp - Ö¸Ïò·µ»ØµÄÐÂÓ³ÉäµÄ´æ´¢µÄÖ¸Õë¡£
void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr,
bus_dmamap_t map)
ÊÍ·ÅÓÉbus_dmamem_alloc()
·ÖÅäµÄÄÚ´æ¡£
Ŀǰ£¬¶Ô·ÖÅäµÄ´øÓÐISAÏÞÖÆµÄÄÚ´æµÄÊÍ·ÅûÓÐʵÏÖ¡£Òò´Ë£¬½¨ÒéµÄ
ʹÓÃÄ£ÐÍΪ¾¡¿ÉÄܳ¤Ê±¼äµØ±£³ÖºÍÖØÓ÷ÖÅäµÄÇøÓò¡£²»ÒªÇáÒ×µØ
ÊÍ·ÅÄ³Ð©ÇøÓò£¬È»ºóÔÙ¶Ìʱ¼äµØ·ÖÅäËü¡£Õâ²¢²»Òâζ×Ų»Ó¦µ±Ê¹Óà bus_dmamem_free()
£ºÏ£ÍûºÜ¿ìËü¾Í»á±» ÍêÕûµØÊµÏÖ¡£
dmat - ±êÇ©
vaddr - ÄÚ´æµÄÄÚºËÐ鵨ַ
map - ÄÚ´æµÄÓ³É䣨¸ú
bus_dmamem_alloc()
·µ»ØµÄÒ»Ñù£©
int bus_dmamap_create(bus_dma_tag_t dmat, int flags,
bus_dmamap_t *mapp)
Ϊ±êÇ©´´½¨Ó³É䣬ÒÔºóÓÃÓÚ bus_dmamap_load()
¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò ·µ»Ø´íÎóÂë¡£
dmat - ±êÇ©
flags - ÀíÂÛÉÏÊÇÆì±êµÄλͼ¡£µ«»¹ ´Ó䶨Òå¹ýÈÎºÎÆì±ê£¬Òò´ËĿǰ×ÜÊÇ0¡£
mapp - Ö¸Ïò·µ»ØµÄÐÂÓ³ÉäµÄ´æ´¢µÄÖ¸Õë¡£
int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t
map)
Ïú»ÙÓ³Éä¡£³É¹¦Ôò·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£
dmat - ÓëÓ³É乨ÁªµÄ±êÇ©
map - ½«Òª±»Ïú»ÙµÄÓ³Éä
int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void
*buf, bus_size_t buflen, bus_dmamap_callback_t *callback, void *callback_arg, int
flags)
¼ÓÔØ»º³åÇøµ½Ó³ÉäÖÐ(Ó³É䱨ÐëÊÂÏÈÓÉ bus_dmamap_create()
»òÕß bus_dmamem_alloc()
)´´½¨¡£»º³åÇøµÄËùÓÐ
Ò³Ãæ¶¼»á±»¼ì²é£¬¿´ÊÇ·ñ·ûºÏ±êÇ©µÄÒªÇ󣬲¢ÎªÄÇЩ²»·ûºÏµÄ·ÖÅä
·´µ¯Ò³Ãæ¡£»á´´½¨ÎïÀí¶ÎÃèÊö·ûµÄÊý×飬²¢½«Æä´«µÝ¸ø»Øµ÷º¯Êý¡£
»Øµ÷º¯ÊýÒÔijÖÖ·½Ê½´¦ÀíÕâ¸öÊý×顣ϵͳÖеķ´µ¯»º³åÇøÊÇÊÜÏ޵ģ¬
Òò´ËÈç¹ûÐèÒªµÄ·´µ¯»º³åÇø²»ÄÜÁ¢¼´»ñµÃ£¬Ôò½«ÇëÇóÈë¶Ó£¬µ±·´µ¯
»º³åÇø¿ÉÓÃʱÔÙµ÷Óûص÷º¯Êý¡£Èç¹û»Øµ÷º¯ÊýÁ¢¼´Ö´ÐÐÔò·µ»Ø0£¬
Èç¹ûÇëÇó±»ÅŶӣ¬µÈ´ý½«À´Ö´ÐУ¬Ôò·µ»Ø ¡°EINPROGRESS¡±¡£ºóÒ»ÖÖÇé¿öÏ£¬
ÓëÅŶӵĻص÷º¯ÊýÖ®¼äµÄͬ²½ÓÉÇý¶¯³ÌÐò¸ºÔð¡£
dmat - ±êÇ©
map - Ó³Éä
buf - »º³åÇøµÄÄÚºËÐ鵨ַ
buflen - »º³åÇøµÄ³¤¶È
callback, callback_arg
- »Øµ÷º¯Êý¼°Æä²ÎÊý
»Øµ÷º¯ÊýµÄÔÐÍΪ£º
void callback(void *arg, bus_dma_segment_t *seg, int nseg, int
error)
arg - Óë´«µÝ¸ø bus_dmamap_load()
µÄcallback_arg Ïàͬ¡£
seg - ¶ÎÃèÊö·ûµÄÊý×é
nseg - Êý×éÖеÄÃèÊö·û¸öÊý
error - ±íʾ¶ÎÊýÄ¿Òç³ö£ºÈç±»ÉèΪ ¡°EFBIG¡±£¬ Ôò±êÇ©ÔÊÐíµÄ×î´óÊýÄ¿µÄ¶ÎÎÞ·¨ÈÝÄÉ»º³åÇø¡£ ÕâÖÖÇé¿öÏÂÊý×éÖеÄÃèÊö·ûµÄÊýĿֻÓбêÇ©Ðí¿ÉµÄÄÇô¶à¡£ ¶ÔÕâÖÖÇé¿öµÄ´¦ÀíÓÉÇý¶¯³ÌÐò¾ö¶¨£º¸ù¾ÝÏ£ÍûµÄÓïÒ壬Çý¶¯ ³ÌÐò¿ÉÒÔÊÓÆäΪ´íÎ󣬻ò½«»º³åÇø·ÖΪÁ½¸ö²¢µ¥¶À´¦ÀíµÚ¶þ¸ö¡£
¶ÎÊý×éÖеÄÿһÏî°üº¬ÈçÏÂ×ֶΣº
ds_addr - ¶ÎÎïÀíµØÖ·
ds_len - ¶Î³¤¶È
void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t
map)
unload the map.
dmat - ±êÇ©
map - ÒѼÓÔØµÄÓ³Éä
void bus_dmamap_sync (bus_dma_tag_t dmat, bus_dmamap_t map,
bus_dmasync_op_t op)
ÓëÉ豸½øÐÐÎïÀí´«Êäǰºó£¬½«¼ÓÔØµÄ»º³åÇøÓëÆä·´µ¯Ò³Ãæ½øÐÐͬ²½¡£ ´Ëº¯ÊýÍê³ÉÔʼ»º³åÇøÓëÆäÓ³Éä°æ±¾Ö®¼äËùÓбØÐèµÄÊý¾Ý¿½±´¹¤×÷¡£ ½øÐд«Êä֮ǰºÍÖ®ºó±ØÐë¶Ô»º³åÇø½øÐÐͬ²½¡£
dmat - ±êÇ©
map - ÒѼÓÔØµÄÓ³Éä
op - ÒªÖ´ÐеÄͬ²½²Ù×÷µÄÀàÐÍ£º
BUS_DMASYNC_PREREAD
- ´ÓÉ豸µ½ »º³åÇøµÄ¶Á²Ù×÷֮ǰ
BUS_DMASYNC_POSTREAD
- ´ÓÉ豸µ½ »º³åÇøµÄ¶Á²Ù×÷Ö®ºó
BUS_DMASYNC_PREWRITE
- ´Ó»º³åÇøµ½ É豸µÄд²Ù×÷֮ǰ
BUS_DMASYNC_POSTWRITE
- ´Ó»º³åÇøµ½ É豸µÄд²Ù×÷Ö®ºó
¡¡¡¡ µ±Ç°PREREADºÍPOSTWRITEΪ¿Õ²Ù×÷£¬µ«½«À´¿ÉÄÜ»á¸Ä±ä£¬Òò´ËÇý¶¯³ÌÐò
Öв»ÄܺöÂÔËüÃÇ¡£ÓÉbus_dmamem_alloc()
»ñµÃµÄÄÚ´æ²»ÐèҪͬ²½¡£
¡¡¡¡ ´Óbus_dmamap_load()
Öе÷Óûص÷º¯Êý֮ǰ£¬
¶ÎÊý×éÊÇ´æ´¢ÔÚÕ»Öеġ£²¢ÇÒÊǰ´±êÇ©ÔÊÐíµÄ×î´óÊýÄ¿µÄ¶ÎÔ¤ÏÈ·ÖÅä
ºÃµÄ¡£ÕâÑùÓÉÓÚi386Ìåϵ½á¹¹É϶ԶÎÊýÄ¿µÄʵ¼ÊÏÞÖÆÔ¼Îª250-300
£¨ÄÚºËջΪ4KB¼õÈ¥Óû§½á¹¹µÄ´óС£¬¶ÎÊý×éÌõÄ¿µÄ´óСΪ8×Ö½Ú£¬ºÍ
ÆäËü±ØÐëÁô³öÀ´µÄ¿Õ¼ä£©¡£ÓÉÓÚÊý×é»ùÓÚ×î´óÊýÄ¿¶ø·ÖÅ䣬Òò´ËÕâ¸öÖµ
±ØÐë²»ÄÜÉèÖóɳ¬³öʵ¼ÊÐèÒª¡£ÐÒÔ˵ÄÊÇ£¬¶ÔÓÚ´ó¶àÊýÓ²¼þ¶øÑÔ£¬
ËùÖ§³ÖµÄ¶ÎµÄ×î´óÊýÄ¿µÍºÜ¶à¡£µ«Èç¹ûÇý¶¯³ÌÐòÏë´¦Àí¾ßÓзdz£¶à
·ÖÉ¢/ÊÕ¼¯¶ÎµÄ»º³åÇø£¬ÔòÓ¦µ±Ò»²¿·ÖÒ»²¿·ÖµØ´¦Àí£º¼ÓÔØ»º³åÇøµÄ
Ò»²¿·Ö£¬´«Êäµ½É豸£¬È»ºó¼ÓÔØ»º³åÇøµÄÏÂÒ»²¿·Ö£¬Èç´Ë·´¸´¡£
¡¡¡¡ ÁíÒ»¸öʵ¼ù½áÂÛÊǶÎÊýÄ¿¿ÉÄÜÏÞÖÆ»º³åÇøµÄ´óС¡£Èç¹û»º³åÇøÖÐµÄ ËùÓÐÒ³ÃæÅöÇÉÎïÀíÉϲ»Á¬Ðø£¬Ôò·ÖƬÇé¿öÏÂÖ§³ÖµÄ×î´ó»º³åÇø³ß´ç Ϊ(nsegments * page_size)¡£ÀýÈ磬Èç¹ûÖ§³ÖµÄ¶ÎµÄ×î´óÊýĿΪ10£¬ ÔòÔÚi386ÉÏ¿ÉÒÔÈ·±£Ö§³ÖµÄ×î´ó»º³åÇø´óСΪ40K¡£Èç¹ûÏ£Íû¸ü´óµÄ ÔòÐèÒªÔÚÇý¶¯³ÌÐòÖÐʹÓÃÒ»Ð©ÌØÊâ¼¼ÇÉ¡£
¡¡¡¡ Èç¹ûÓ²¼þ¸ù±¾²»Ö§³Ö·ÖÉ¢/ÊÕ¼¯£¬»òÕßÇý¶¯³ÌÐòÏ£Íû¼´Ê¹ÔÚÑÏÖØ·ÖƬµÄ Çé¿öÏÂÈÔȻ֧³ÖijÖÖ»º³åÇø´óС£¬Ôò½â¾ö°ì·¨ÊÇ£ºÈç¹ûÎÞ·¨ÈÝÄÉÏÂÔʼ »º³åÇø£¬¾ÍÔÚÇý¶¯³ÌÐòÖзÖÅäÒ»¸öÁ¬ÐøµÄ»º³åÇø×÷ΪÖÐ¼ä´æ´¢¡£
¡¡¡¡ ÏÂÃæÊǵ±Ê¹ÓÃÓ³ÉäʱµÄµäÐ͵÷ÓÃ˳Ðò£¬¸ù¾Ý¶ÔÓ³ÉäµÄ¾ßÌåʹÓöø²»Í¬¡£ ×Ö·û->ÓÃÓÚÏÔʾʱ¼äÁ÷¡£
¡¡¡¡ ¶ÔÓÚ´ÓÁ¬½Óµ½·ÖÀëÉ豸£¬ÕâÆÚ¼äλÖÃÒ»Ö±²»±äµÄ»º³åÇø£º
¡¡¡¡ bus_dmamem_alloc -> bus_dmamap_load -> ...use buffer... -> -> bus_dmamap_unload -> bus_dmamem_free
¡¡¡¡¶ÔÓÚ´ÓÇý¶¯³ÌÐòÍⲿ´«µÝ½øÈ¥£¬²¢ÇÒ¾³£±ä»¯µÄ»º³åÇø£º
bus_dmamap_create -> -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer -> -> bus_dmamap_sync(POST...) -> bus_dmamap_unload -> ... -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer -> -> bus_dmamap_sync(POST...) -> bus_dmamap_unload -> -> bus_dmamap_destroy
¡¡¡¡ µ±¼ÓÔØÓÉbus_dmamem_alloc()
´´½¨µÄÓ³Éäʱ£¬´«µÝ
½øÈ¥µÄ»º³åÇøµÄµØÖ·ºÍ´óС±ØÐëºÍ bus_dmamem_alloc()
ÖÐʹÓõÄÒ»Ñù¡£ÕâÖÖÇé¿öϾÍ
¿ÉÒÔ±£Ö¤Õû¸ö»º³åÇø±»×÷Ϊһ¸ö¶Î¶øÓ³É䣨Òò¶ø»Øµ÷¿ÉÒÔ»ùÓڴ˼ÙÉ裩£¬
²¢ÇÒÇëÇó±»Á¢¼´Ö´ÐУ¨ÓÀÔ¶²»»á·µ»ØEINPROGRESS£©¡£ÕâÖÖÇé¿öÏ»ص÷º¯Êý
ÐèÒª×÷µÄÖ»ÊDZ£´æÎïÀíµØÖ·¡£
¡¡¡¡ µäÐÍʾÀýÈçÏ£º
static void alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error) { *(bus_addr_t *)arg = seg[0].ds_addr; } ... int error; struct somedata { .... }; struct somedata *vsomedata; /* Ð鵨ַ */ bus_addr_t psomedata; /* ÎïÀí×ÜÏßÏà¹ØµÄµØÖ· */ bus_dma_tag_t tag_somedata; bus_dmamap_t map_somedata; ... error=bus_dma_tag_create(parent_tag, alignment, boundary, lowaddr, highaddr, /*filter*/ NULL, /*filterarg*/ NULL, /*maxsize*/ sizeof(struct somedata), /*nsegments*/ 1, /*maxsegsz*/ sizeof(struct somedata), /*flags*/ 0, &tag_somedata); if(error) return error; error = bus_dmamem_alloc(tag_somedata, &vsomedata, /* flags*/ 0, &map_somedata); if(error) return error; bus_dmamap_load(tag_somedata, map_somedata, (void *)vsomedata, sizeof (struct somedata), alloc_callback, (void *) &psomedata, /*flags*/0);
¡¡¡¡ ´úÂë¿´ÆðÀ´Óе㳤£¬Ò²±È½Ï¸´ÔÓ£¬µ«ÄÇÊÇÕýÈ·µÄʹÓ÷½·¨¡£Êµ¼Ê½á¹ûÊÇ£º Èç¹û·ÖÅä¶à¸öÄÚ´æÇøÓò£¬Ôò×ܽ«ËüÃÇ×éºÏ³ÉÒ»¸ö½á¹¹²¢×÷ΪÕûÌå·ÖÅä £¨Èç¹û¶ÔÆëºÍ±ß½çÏÞÖÆÔÊÐíµÄ»°£©ÊÇÒ»¸öºÜºÃµÄÖ÷Òâ¡£
¡¡¡¡ µ±¼ÓÔØÈÎÒ⻺³åÇøµ½ÓÉbus_dmamap_create()
´´½¨µÄÓ³Éäʱ£¬ÓÉÓڻص÷¿ÉÄܱ»ÑÓ³Ù£¬Òò´Ë±ØÐë²ÉÈ¡ÌØÊâ´ëÊ©Óë»Øµ÷
º¯Êý½øÐÐͬ²½¡£´úÂë¿´ÆðÀ´ÏñÏÂÃæµÄÑù×Ó£º
{ int s; int error; s = splsoftvm(); error = bus_dmamap_load( dmat, dmamap, buffer_ptr, buffer_len, callback, /*callback_arg*/ buffer_descriptor, /*flags*/0); if (error == EINPROGRESS) { /* * Ö´ÐбØÒªµÄ²Ù×÷ÒÔÈ·±£Óë»Øµ÷µÄͬ²½¡£ * »Øµ÷±»È·±£Ö±µ½ÎÒÃÇÖ´ÐÐÁËsplx()»òtsleep()²Å»á±»µ÷Óᣠ*/ } splx(s); }
¡¡¡¡ ´¦ÀíÇëÇóµÄÁ½ÖÖ·½·¨·Ö±ðÊÇ£º
¡¡¡¡ 1. Èç¹ûͨ¹ýÏÔʽµØ±ê¼ÇÇëÇóÒѾ½áÊøÀ´Íê³ÉÇëÇó£¨ÀýÈçCAMÇëÇ󣩣¬Ôò ½«ËùÓнøÒ»²½µÄ´¦Àí·ÅÈë»Øµ÷Çý¶¯³ÌÐòÖлá±È½Ï¼òµ¥£¬»Øµ÷½áÊøºó»á ±ê¼ÇÇëÇó¡£Ö®ºó²»ÐèҪ̫¶à¶îÍâµÄͬ²½¡£ÓÉÓÚÁ÷¿ØÖƵÄÔÒò£¬¶³½áÇëÇó ¶ÓÁÐÖ±µ½ÇëÇóÍê³É²ÅÊÍ·Å¿ÉÄÜÊǸöºÃÖ÷Òâ¡£
¡¡¡¡ 2. Èç¹ûÇëÇóÊÇÔÚº¯Êý·µ»ØÊ±Íê³É£¨ÀýÈç×Ö·ûÉ豸ÉÏ´«Í³µÄ¶ÁдÇëÇ󣩣¬
ÔòÐèÒªÔÚ»º³åÇøÃèÊö·ûÉÏÉèÖÃͬ²½±êÖ¾£¬²¢µ÷Óà tsleep()
¡£ºóÃæµ±»Øµ÷º¯Êý±»µ÷ÓÃʱ£¬Ëü½«
Ö´Ðд¦Àí²¢¼ì²éͬ²½±êÖ¾¡£Èç¹ûÉèÖÃÁËͬ²½±êÖ¾£¬ËüÓ¦¸Ã·¢³öÒ»¸ö
»½ÐѲÙ×÷¡£ÔÚÕâÖÖ·½·¨ÖУ¬»Øµ÷º¯Êý»òÕß½øÐÐËùÓɱØÐèµÄ´¦Àí£¨¾ÍÏñ
Ç°ÃæµÄÇé¿ö£©£¬»òÕß¼òµ¥ÔÚ»º³åÇøÃèÊö·ûÖд洢¶ÎÊý×é¡£»Øµ÷Íê³É
ºó£¬»Øµ÷º¯Êý¾ÍÄÜʹÓÃÕâ¸ö´æ´¢µÄ¶ÎÊý×é²¢½øÐÐËùÓеĴ¦Àí¡£
¡¡¡¡ ISA×ÜÏßÖÐDirect Memory Access (DMA)ÊÇͨ¹ýDMA¿ØÖÆÆ÷£¨Êµ¼ÊÉÏÊÇËüÃÇ ÖеÄÁ½¸ö£¬µ«ÕâÖ»ÊÇÎÞ¹ØÏ¸½Ú£©ÊµÏֵġ£ÎªÁËʹÒÔǰµÄISAÉ豸¼òµ¥±ãÒË£¬ ×ÜÏß¿ØÖƺ͵ØÖ·²úÉúµÄÂß¼¶¼¼¯ÖÐÔÚDMA¿ØÖÆÆ÷ÖС£ÐÒÔ˵ÄÊÇ£¬FreeBSD ÌṩÁËÒ»Ì׺¯Êý£¬ÕâЩº¯Êý´ó¶à°ÑDMA¿ØÖÆÆ÷µÄ·±Ëöϸ½Ú¶ÔÉ豸Çý¶¯³ÌÐò Òþ²ØÁËÆðÀ´¡£
¡¡¡¡ ×î¼òµ¥Çé¿öÊÇÄÇЩ±È½ÏÖÇÄܵÄÉ豸¡£¾ÍÏóPCIÉϵÄ×ÜÏßÖ÷É豸һÑù£¬ ËüÃÇ×Ô¼ºÄܲúÉú×ÜÏßÖÜÆÚºÍÄÚ´æµØÖ·¡£ËüÃÇÕæÕý´ÓDMA¿ØÖÆÆ÷ÐèÒªµÄ ΨһÊÂÇéÊÇ×ÜÏßÖٲá£ËùÒÔΪÁË´ËÄ¿µÄ£¬ËüÃǼÙ×°ÊǼ¶Áª´ÓDMA¿ØÖÆÆ÷¡£ µ±Á¬½ÓÇý¶¯³ÌÐòʱ£¬ÏµÍ³DMA¿ØÖÆÆ÷ÐèÒª×öµÄΨһÊÂÇé¾ÍÊÇͨ¹ýµ÷Óà ÈçϺ¯ÊýÔÚÒ»¸öDMAͨµÀÉϼ¤»î¼¶ÁªÄ£Ê½¡£
¡¡¡¡ void isa_dmacascade(int channel_number)
¡¡¡¡ ËùÓнøÒ»²½µÄ»î¶¯Í¨¹ý¶ÔÉ豸±à³ÌÍê³É¡£µ±Ð¶ÔØÇý¶¯³ÌÐòʱ£¬²»ÐèÒª µ÷ÓÃDMAÏà¹ØµÄº¯Êý¡£
¡¡¡¡ ¶ÔÓڽϼòµ¥µÄÉ豸£¬ÊÂÇé·´¶ø±äµÃ¸´ÔÓ¡£Ê¹Óõĺ¯Êý°üÀ¨£º
int isa_dma_acquire(int chanel_number)
±£ÁôÒ»¸öDMAͨµÀ¡£³É¹¦Ôò·µ»Ø0£¬Èç¹ûͨµÀÒѾ±»±£Áô»ò±»ÆäËü Çý¶¯³ÌÐò±£ÁôÔò·µ»ØEBUSY¡£´ó¶àÊýµÄISAÉ豸¶¼²»Äܹ²ÏíDMAͨµÀ£¬ Òò´ËÕâ¸öº¯Êýͨ³£ÔÚÁ¬½ÓÉ豸ʱµ÷Óá£×ÜÏß×ÊÔ´µÄÏÖ´ú½Ó¿ÚʹµÃ ÕâÖÖ±£Áô³ÉΪ¶àÓ࣬µ«Ä¿Ç°ÈÔ±ØÐëʹÓá£Èç¹û²»Ê¹Óã¬ÔòºóÃæÆäËü DMAÀý³Ì½«»ápanic¡£
int isa_dma_release(int chanel_number)
ÊÍ·ÅÏÈǰ±£ÁôµÄDMAͨµÀ¡£ÊÍ·ÅͨµÀʱ±ØÐë²»ÄÜÓÐÕýÔÚ½øÐÐÖÐµÄ ´«Ê䣨ÁíÍ⣬ÊÍ·ÅͨµÀºóÉ豸±ØÐë²»ÄÜÔÙÊÔͼ·¢Æð´«Ê䣩¡£
void isa_dmainit(int chan, u_int bouncebufsize)
·ÖÅäÓÉÌØ¶¨Í¨µÀʹÓõķ´µ¯»º³åÇø¡£ÇëÇóµÄ»º³åÇø´óС²»Äܳ¬¹ý
64KB¡£ÒÔºó£¬Èç¹û´«Ê仺³åÇøÅöÇɲ»ÊÇÎïÀíÁ¬ÐøµÄ£¬»ò³¬³öISA
×ÜÏ߿ɷÃÎʵÄÄڴ淶Χ£¬»ò¿çÔ½64KBµÄ±ß½ç£¬Ôò»á×Ô¶¯Ê¹Ó÷´µ¯
»º³åÇø¡£Èç¹û´«Êä×ÜÊÇʹÓ÷ûºÏÉÏÊöÌõ¼þµÄ»º³åÇø£¨ÀýÈ磬ÓÉ bus_dmamem_alloc()
·ÖÅäµÄÄÇЩ£©£¬Ôò ²»ÐèÒªµ÷ÓÃisa_dmainit()
¡£µ«Ê¹Óô˺¯Êý
»áÈÃͨ¹ýDMA¿ØÖÆÆ÷´«ÊäÈÎÒâÊý¾Ý±äµÃ·Ç³£·½±ã¡£
chan - ͨµÀºÅ
bouncebufsize - ÒÔ×Ö½Ú¼ÆÊýµÄ·´µ¯ »º³åÇøµÄ´óС
void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int
chan)
×¼±¸Æô¶¯DMA´«Ê䡣ʵ¼ÊÆô¶¯É豸ÉϵĴ«Êä֮ǰ±ØÐèµ÷Óô˺¯Êý
À´ÉèÖÃDMA¿ØÖÆÆ÷¡£Ëü¼ì²é»º³åÇøÊÇ·ñÁ¬ÐøµÄÇÒÔÚISAÄڴ淶Χ
Ö®ÄÚ£¬Èç¹û²»ÊÇÔò×Ô¶¯Ê¹Ó÷´µ¯»º³åÇø¡£Èç¹ûÐèÒª·´µ¯»º³åÇø£¬ µ«·´µ¯»º³åÇøÃ»ÓÐÓÃisa_dmainit()
ÉèÖ㬻ò¶ÔÓÚÇëÇóµÄ´«Êä´óСÀ´ËµÌ«Ð¡£¬Ôòϵͳ½«panic¡£
дÇëÇóÇÒʹÓ÷´µ¯»º³åÇøµÄÇé¿öÏ£¬Êý¾Ý½«±»×Ô¶¯¿½±´µ½·´µ¯ »º³åÇø¡£
flags - λÑÚÂ룬¾ö¶¨½«ÒªÍê³ÉµÄ²Ù×÷µÄÀàÐÍ¡£·½ÏòλB_READºÍ B_WRITE»¥³â¡£
B_READ - ´ÓISA×ÜÏß¶Áµ½ÄÚ´æ
B_WRITE - ´ÓÄÚ´æÐ´µ½ISA×ÜÏßÉÏ
B_RAW - Èç¹ûÉèÖÃÔòDMA¿ØÖÆÆ÷½«»á¼Çס»º³åÇø£¬²¢ÔÚ´«Êä½áÊøºó
×Ô¶¯ÖØÐ³õʼ»¯Ëü×Ô¼º£¬ÔÙ´ÎÖØ¸´´«Êäͬһ»º³åÇø£¨µ±È»£¬Çý¶¯
³ÌÐò¿ÉÄÜ·¢ÆðÉ豸µÄÁíÒ»¸ö´«Êä֮ǰ¸Ä±ä»º³åÇøÖеÄÊý¾Ý£©¡£
Èç¹ûûÓÐÉèÖ㬲ÎÊýÖ»¶ÔÒ»´Î´«ÊäÓÐЧ£¬ÔÚ·¢ÆðÏÂÒ»´Î´«Êä֮ǰ ±ØÐëÔٴε÷ÓÃisa_dmastart()
¡£Ö»ÓÐÔÚ²» ʹÓ÷´µ¯»º³åÇøÊ±Ê¹ÓÃB_RAW²ÅÓÐÒâÒå¡£
addr - »º³åÇøµÄÐ鵨ַ
nbytes - »º³åÇø³¤¶È¡£±ØÐëСÓÚµÈÓÚ64KB¡£²»ÔÊÐí³¤¶ÈΪ0£ºÒòΪ DMA¿ØÖÆÆ÷½«»áÀí½âΪ64KB£¬¶øÄں˴úÂë°ÑËüÀí½âΪ0£¬ÄÇÑù¾Í»áµ¼Ö ²»¿ÉÔ¤²âµÄЧ¹û¡£¶ÔÓÚͨµÀºÅµÈÓں͸ßÓÚ4µÄÇé¿ö£¬³¤¶È±ØÐèΪżÊý£¬ ÒòΪÕâЩͨµÀÿ´Î´«Êä2×Ö½Ú¡£ÆæÊý³¤¶ÈÇé¿öÏ£¬×îºóÒ»¸ö×Ö½Ú²»±» ´«Êä¡£
chan - ͨµÀºÅ
void isa_dmadone(int flags, caddr_t addr, int nbytes, int
chan)
É豸±¨¸æ´«ÊäÍê³Éºó£¬Í¬²½ÄÚ´æ¡£Èç¹ûÊÇʹÓ÷´µ¯»º³åÇøµÄ¶Á²Ù×÷£¬
Ôò½«Êý¾Ý´Ó·´µ¯»º³åÇø¿½±´µ½Ôʼ»º³åÇø¡£²ÎÁ¿Óë isa_dmastart()
µÄÏàͬ¡£ÔÊÐíʹÓÃB_RAW±êÖ¾£¬
µ«ËüÒ»µãÒ²²»»áÓ°Ïìisa_dmadone()
¡£
int isa_dmastatus(int channel_number)
·µ»Øµ±Ç°´«ÊäÖÐÊ£ÓàµÄ×Ö½ÚÊý¡£ÔÚ isa_dmastart()
ÖÐÉèÖÃÁËB_READµÄÇé¿öÏ£¬
·µ»ØµÄÊý×ÖÒ»¶¨²»»áµÈÓÚÁã¡£´«Êä½áÊøÊ±Ëü»á±»×Ô¶¯¸´Î»µ½»º³åÇøµÄ
³¤¶È¡£ÕýʽµÄÓ÷¨ÊÇÔÚÉ豸·¢ÐźÅָʾ´«ÊäÒÑÍê³Éʱ¼ì²éÊ£ÓàµÄ×Ö½ÚÊý¡£
Èç¹û×Ö½ÚÊý²»Îª0£¬Ôò´Ë´Î´«Êä¿ÉÄÜÓÐÎÊÌâ¡£
int isa_dmastop(int channel_number)
·ÅÆúµ±Ç°µÄ´«Êä²¢·µ»ØÊ£Óàδ´«ÊäµÄ×Ö½ÚÊý¡£
¡¡¡¡ Õâ¸öº¯Êý̽²âÉ豸ÊÇ·ñ´æÔÚ¡£Èç¹ûÇý¶¯³ÌÐòÖ§³Ö×Ô¶¯Õì²âÉ豸ÅäÖÃµÄ Ä³Ð©²¿·Ö£¨ÈçÖжÏÏòÁ¿»òÄÚ´æµØÖ·£©£¬Ôò×Ô¶¯Õì²â±ØÐëÔÚ´ËÀý³ÌÖÐÍê³É¡£
¡¡¡¡ ¶ÔÓÚÈÎÒâÆäËû×ÜÏߣ¬Èç¹û²»ÄÜÕì²âµ½É豸£¬»òÕßÕì²âµ½µ«×Ô¼ìʧ°Ü£¬ »òÕß·¢ÉúijЩÆäËûÎÊÌ⣬ÔòÓ¦µ±·µ»ØÒ»¸öÕýÖµµÄ´íÎó¡£Èç¹ûÉ豸²» ´æÔÚÔò±ØÐë·µ»ØÖµ ¡°ENXIO¡±¡£ ÆäËû´íÎóÖµ¿ÉÄܱíʾÆäËûÌõ¼þ¡£Áã»ò¸ºÖµ Òâζ×ųɹ¦¡£´ó¶àÊýÇý¶¯³ÌÐò·µ»ØÁã±íʾ³É¹¦¡£
¡¡¡¡ µ±PnPÉ豸֧³Ö¶à¸ö½Ó¿ÚʱʹÓøº·µ»ØÖµ¡£ÀýÈ磬²»Í¬Çý¶¯³ÌÐòÖ§³Ö ÀϵļæÈݽӿںͽÏеĸ߼¶½Ó¿Ú¡£ÔòÁ½¸öÇý¶¯³ÌÐò¶¼½«Õì²âÉ豸¡£ ÔÚ̽²âÀý³ÌÖзµ»Ø½Ï¸ßÖµµÄÇý¶¯³ÌÐò»ñµÃÓÅÏÈ£¨»»¾ä»°Ëµ£¬·µ»Ø0µÄ Çý¶¯³ÌÐò¾ßÓÐ×î¸ßµÄÓÅÏȼ¶£¬·µ»Ø-1µÄÆä´Î£¬·µ»Ø-2µÄ¸üºó£¬µÈµÈ£©¡£ ÕâÑù£¬½öÖ§³ÖÀϽӿڵÄÉ豸½«±»ÀÏÇý¶¯³ÌÐò´¦Àí£¨ÆäÓ¦µ±´Ó̽²âÀý³ÌÖÐ ·µ»Ø-1£©£¬¶øÍ¬Ê±Ò²Ö§³ÖнӿڵÄÉ豸½«ÓÉÐÂÇý¶¯³ÌÐò´¦Àí£¨ÆäÓ¦µ±´Ó ̽²âÀý³ÌÖзµ»Ø0£©¡£
¡¡¡¡ É豸ÃèÊö·û½á¹¹xxx_softcÓÉϵͳÔÚµ÷ÓÃ̽²âÀý³Ì֮ǰ·ÖÅä¡£Èç¹û
̽²âÀý³Ì·µ»Ø´íÎó£¬ÃèÊö·û»á±»ÏµÍ³×Ô¶¯È¡Ïû·ÖÅä¡£Òò´ËÈç¹û³öÏÖ
̽²â´íÎó£¬Çý¶¯³ÌÐò±ØÐ뱣֤ȡÏû·ÖÅä̽²âÆÚ¼äËüʹÓõÄËùÓÐ×ÊÔ´£¬
ÇÒÈ·±£Ã»ÓÐʲôÄܹ»×èÖ¹ÃèÊö·û±»°²È«µØÈ¡Ïû·ÖÅä¡£Èç¹û̽²â³É¹¦
Íê³É£¬ÃèÊö·û½«ÓÉϵͳ±£´æ²¢ÔÚÒԺ󴫵ݸøÀý³Ì xxx_isa_attach()
¡£Èç¹ûÇý¶¯³ÌÐò·µ»Ø¸ºÖµ£¬
¾Í²»Äܱ£Ö¤Ëü½«»ñµÃ×î¸ßÓÅÏÈȨÇÒÆäÁ¬½ÓÀý³Ì»á±»µ÷Óá£Òò´ËÕâÖÖ
Çé¿öÏÂËüÒ²±ØÐëÔÚ·µ»ØÇ°ÊÍ·ÅËùÓеÄ×ÊÔ´£¬²¢ÔÚÐèÒªµÄʱºòÔÚÁ¬½Ó
Àý³ÌÖÐÖØÐ·ÖÅäËüÃÇ¡£µ±xxx_isa_probe()
·µ»Ø0ʱ£¬ÔÚ·µ»ØÇ°ÊÍ·Å×ÊÔ´Ò²ÊÇÒ»¸öºÃÖ÷Ò⣬¶øÇÒÖйæÖоصÄÇý¶¯
³ÌÐòÓ¦µ±ÕâÑù×ö¡£µ«ÔÚÊÍ·Å×ÊÔ´»á´æÔÚijЩÎÊÌâµÄÇé¿öÏ£¬ÔÊÐíÇý¶¯
³ÌÐòÔÚ´Ó̽²âÀý³Ì·µ»Ø0ºÍÁ¬½ÓÀý³ÌµÄÖ´ÐÐÖ®¼ä±£³Ö×ÊÔ´¡£
¡¡¡¡ µäÐ͵Ä̽²âÀý³ÌÒÔÈ¡µÃÉ豸ÃèÊö·ûºÍµ¥ÔªºÅ¿ªÊ¼£º
struct xxx_softc *sc = device_get_softc(dev); int unit = device_get_unit(dev); int pnperror; int error = 0; sc->dev = dev; /* Á´½Ó»ØÀ´ */ sc->unit = unit;
¡¡¡¡ È»ºó¼ì²éPnPÉ豸¡£¼ì²éÊÇͨ¹ýÒ»¸ö°üº¬PnP IDÁбíµÄ±í½øÐеġ£´Ë±í °üº¬Õâ¸öÇý¶¯³ÌÐòÖ§³ÖµÄPnP IDºÍÒÔÈ˹¤¿É¶ÁÐÎʽ¸ø³öµÄ¶ÔÓ¦ÕâЩIDµÄ É豸ÐͺŵÄÃèÊö¡£
pnperror=ISA_PNP_PROBE(device_get_parent(dev), dev, xxx_pnp_ids); if(pnperror == ENXIO) return ENXIO;
¡¡¡¡ ISA_PNP_PROBEµÄÂß¼ÈçÏ£ºÈç¹û¿¨£¨É豸µ¥Ôª£©Ã»Óб»×÷ΪPnPÕì²âµ½£¬
Ôò·µ»ØENOENT¡£Èç¹û±»×÷ΪPnPÕì²âµ½£¬µ«Õì²âµ½µÄID²»Æ¥Åä±íÖеÄ
ÈÎÒ»ID£¬Ôò·µ»ØENXIO¡£×îºó£¬Èç¹ûÉ豸ÄÜÖ§³ÖPnPÇÒÆ¥Åä±íÖеÄÒ»¸ö
ID£¬Ôò·µ»Ø0£¬²¢ÇÒÓÉdevice_set_desc()
´Ó
±íÖÐÈ¡µÃÊʵ±µÄÃèÊö½øÐÐÉèÖá£
¡¡¡¡ Èç¹ûÉ豸Çý¶¯³ÌÐò½öÖ§³ÖPnPÉ豸£¬ÔòÇé¿ö¿´ÆðÀ´ÈçÏ£º
if(pnperror != 0) return pnperror;
¡¡¡¡ ¶ÔÓÚ²»Ö§³ÖPnPµÄÇý¶¯³ÌÐò²»ÐèÒªÌØÊâ´¦Àí£¬ÒòΪÇý¶¯³ÌÐò»á´«µÝ¿ÕµÄ PnP ID±í£¬ÇÒÈç¹ûÔÚPnP¿¨Éϵ÷ÓûáµÃµ½ENXIO¡£
¡¡¡¡ ̽²âÀý³Ìͨ³£ÖÁÉÙÐèҪijЩ×îÉÙÁ¿µÄ×ÊÔ´£¬ÈçI/O¶Ë¿ÚºÅ£¬À´·¢ÏÖ²¢Ì½²â¿¨¡£ ¶ÔÓÚ²»Í¬µÄÓ²¼þ£¬Çý¶¯³ÌÐò¿ÉÄÜ»á×Ô¶¯·¢ÏÖÆäËû±ØÐèµÄ×ÊÔ´¡£PnPÉ豸µÄ ËùÓÐ×ÊÔ´ÓÉPnP×ÓϵͳԤÏÈÉèÖã¬Òò´ËÇý¶¯³ÌÐò²»ÐèÒª×Ô¼º·¢ÏÖËüÃÇ¡£
¡¡¡¡ ͨ³£·ÃÎÊÉ豸ËùÐèÒªµÄ×îÉÙÐÅÏ¢¾ÍÊǶ˿ںš£È»ºóijЩÉ豸ÔÊÐí´ÓÉ豸 ÅäÖüĴæÆ÷ÖÐÈ¡µÃÆäÓàÐÅÏ¢£¨¾¡¹Ü²»ÊÇËùÓеÄÉ豸¶¼ÕâÑù£©¡£Òò´ËÊ×ÏÈ ÎÒÃdz¢ÊÔÈ¡µÃ¶Ë¿ÚÆðʼֵ£º
sc->port0 = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/); if(sc->port0 == 0) return ENXIO;
¡¡¡¡ »ù¶Ë¿ÚµØÖ·±»±£´æÔÚsoftc½á¹¹ÖУ¬ÒԱ㽫À´Ê¹Óá£Èç¹ûÐèÒª¾³£Ê¹Óà ¶Ë¿Ú£¬Ôòÿ´Î¶¼µ÷ÓÃ×ÊÔ´º¯Êý½«»áÂýµÄÎÞ·¨ÈÌÊÜ¡£Èç¹ûÎÒÃÇûÓеõ½ ¶Ë¿Ú£¬Ôò·µ»Ø´íÎó¼´¿É¡£Ïà·´£¬Ò»Ð©É豸Çý¶¯³ÌÐòÏ൱´ÏÃ÷£¬³¢ÊÔ̽²â ËùÓпÉÄܵĶ˿ڣ¬ÈçÏ£º
/* ´ËÉ豸ËùÓпÉÄܵĻùI/O¶Ë¿ÚµØÖ·±í */ static struct xxx_allports { u_short port; /* ¶Ë¿ÚµØÖ· */ short used; /* Æì±ê£º´Ë¶Ë¿ÚÊÇ·ñÒѱ»ÆäËûµ¥ÔªÊ¹Óà */ } xxx_allports = { { 0x300, 0 }, { 0x320, 0 }, { 0x340, 0 }, { 0, 0 } /* ±í½áÊø */ }; ... int port, i; ... port = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/); if(port !=0 ) { for(i=0; xxx_allports[i].port!=0; i++) { if(xxx_allports[i].used || xxx_allports[i].port != port) continue; /* ÕÒµ½ÁË */ xxx_allports[i].used = 1; /* ÔÚÒÑÖª¶Ë¿ÚÉÏ̽²â */ return xxx_really_probe(dev, port); } return ENXIO; /* ¶Ë¿ÚÎÞ·¨Ê¶±ð»òÒѾ±»Ê¹Óà */ } /* ½öÔÚÐèÒª²Â²â¶Ë¿ÚµÄʱºò²Å»áµ½´ïÕâ¶ù */ for(i=0; xxx_allports[i].port!=0; i++) { if(xxx_allports[i].used) continue; /* ±ê¼ÇΪÒѱ»Ê¹Óà - ¼´Ê¹ÎÒÃÇÔڴ˶˿ÚʲôҲûÓз¢ÏÖ * ÖÁÉÙÎÒÃÇÒÔºó²»»áÔÙ´Î̽²â */ xxx_allports[i].used = 1; error = xxx_really_probe(dev, xxx_allports[i].port); if(error == 0) /* ÔÚÄǸö¶Ë¿ÚÕÒµ½Ò»¸öÉ豸 */ return 0; } /* ̽²â¹ýËùÓпÉÄܵĵØÖ·£¬µ«Ã»ÓпÉÓÃµÄ */ return ENXIO;
¡¡¡¡ µ±È»£¬×öÕâЩÊÂÇéͨ³£Ó¦¸ÃʹÓÃÇý¶¯³ÌÐòµÄ identify()
Àý³Ì¡£µ«¿ÉÄÜÓÐÒ»¸öÕýµ±µÄÀíÓÉÀ´ ˵Ã÷ΪʲôÔÚº¯Êýprobe()
ÖÐÍê³É¸üºÃ£ºÈç¹û
ÕâÖÖ̽²â»áÈÃһЩÆäËûÃô¸ÐÉ豸·¢·è¡£Ì½²âÀý³Ì°´Æì±ê sensitiveÅÅÐò£ºÃô¸ÐÉ豸Ê×Ïȱ»Ì½²â£¬È»ºóÊÇ ÆäËûÉ豸¡£µ«identify()
Àý³ÌÔÚËùÓÐ̽²â֮ǰ
±»µ÷Óã¬Òò´ËËüÃDz»»á¿¼ÂÇÃô¸ÐÉ豸²¢¿ÉÄÜÈÅÂÒÕâЩÉ豸¡£
¡¡¡¡ ÏÖÔÚ£¬ÎÒÃǵõ½Æðʼ¶Ë¿ÚÒÔºó¾ÍÐèÒªÉèÖö˿ÚÊý£¨PnPÉ豸³ýÍ⣩£¬ÒòΪ ÄÚºËÔÚÅäÖÃÎļþÖÐûÓÐÕâ¸öÐÅÏ¢¡£
if(pnperror /* Ö»¶Ô·ÇPnPÉ豸 */ && bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->port0, XXX_PORT_COUNT)<0) return ENXIO;
¡¡¡¡ ×îºó·ÖÅä²¢¼¤»îһƬ¶Ë¿ÚµØÖ·¿Õ¼ä£¨ÌØÊâÖµstartºÍendÒâ˼ÊÇ˵
¡°Ê¹ÓÃÎÒÃÇͨ¹ýbus_set_resource()
ÉèÖõÄÄÇЩֵ¡±£©£º
sc->port0_rid = 0; sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port0_rid, /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE); if(sc->port0_r == NULL) return ENXIO;
¡¡¡¡ ÏÖÔÚ¿ÉÒÔ·ÃÎʶ˿ÚÓ³ÉäµÄ¼Ä´æÆ÷ºó£¬ÎÒÃǾͿÉÒÔÒÔijÖÖ·½Ê½ÏòÉ豸дÈë Êý¾Ý²¢¼ì²éÉ豸ÊÇ·ñÈçÎÒÃÇÆÚÍûµÄÄÇÑù×÷³ö·´Ó¦¡£Èç¹ûûÓУ¬Ôò˵Ã÷ ¿ÉÄÜÆäËûµÄÉ豸ÔÚÕâ¸öµØÖ·ÉÏ£¬»òÕßÕâ¸öµØÖ·Éϸù±¾Ã»ÓÐÉ豸¡£
¡¡¡¡ ͨ³£Çý¶¯³ÌÐòÖ±µ½Á¬½ÓÀý³Ì²Å»áÉèÖÃÖжϴ¦Àíº¯Êý¡£Õâ֮ǰÎÒÃÇÌæ´úÒÔ
ÂÖѯģʽ½øÐÐ̽²â£¬³¬Ê±ÔòÒÔDELAY()
ʵÏÖ¡£
̽²âÀý³Ì±ØÐëÈ·±£²»ÄÜÓÀ¾Ã¹ÒÆð£¬É豸ÉϵÄËùÓеȴý±ØÐëÔÚ³¬Ê±ÄÚÍê³É¡£
Èç¹ûÉ豸²»ÔÚÕâ¶Îʱ¼äÄÚÏìÓ¦£¬Ôò¿ÉÄÜÉ豸³ö¹ÊÕÏ»òÅäÖôíÎó£¬Çý¶¯³ÌÐò
±ØÐë·µ»Ø´íÎ󣬵±È·¶¨³¬Ê±¼ä¸ôʱ£¬¸øÉ豸һЩ¶îÍâʱ¼äÒÔÈ·±£¿É¿¿£º ¾¡¹Ü¼Ù¶¨DELAY()
ÔÚÈκλúÆ÷É϶¼ÑÓʱÏàͬÊýÁ¿µÄ
ʱ¼ä£¬µ«Ëæ¾ßÌåCPUµÄ²»Í¬£¬´Ëº¯Êý»¹ÊÇÓÐÒ»¶¨µÄÎó²î·ù¶È¡£
¡¡¡¡ Èç¹û̽²âÀý³ÌÕæµÄÏë¼ì²éÖжÏÊÇ·ñÕæµÄ¹¤×÷£¬Ëü¿ÉÒÔÒ²ÅäÖúÍ̽²âÖжϡ£ µ«²»½¨ÒéÕâÑù¡£
/* ÒÔÑÏÖØÒÀÀµÓÚ¾ßÌåÉ豸µÄ·½Ê½ÊµÏÖ */ if(error = xxx_probe_ports(sc)) goto bad; /* ·µ»ØÇ°ÊÍ·Å×ÊÔ´ */
¡¡¡¡ ÒÀÀµÓÚËù·¢ÏÖÉ豸µÄÈ·ÇÐÐͺţ¬º¯Êý xxx_probe_ports()
Ò²¿ÉÄÜÉèÖÃÉ豸ÃèÊö¡£µ«
Èç¹ûÖ»Ö§³ÖÒ»ÖÖÉ豸Ðͺţ¬ÔòÒ²¿ÉÒÔÓ²±àÂëµÄÐÎʽÍê³É¡£µ±È»£¬¶ÔÓÚ
PnPÉ豸£¬PnPÖ§³Ö´Ó±íÖÐ×Ô¶¯ÉèÖÃÃèÊö¡£
if(pnperror) device_set_desc(dev, "Our device model 1234");
¡¡¡¡ ̽²âÀý³ÌÓ¦µ±»òÕßͨ¹ý¶ÁÈ¡É豸ÅäÖüĴæÆ÷À´·¢ÏÖËùÓÐ×ÊÔ´µÄ·¶Î§£¬ »òÕßÈ·±£ÓÉÓû§ÏÔʽÉèÖá£ÎÒÃǽ«¼Ù¶¨Ò»¸ö´ø°åÉÏÄÚ´æµÄÀý×Ó¡£ ̽²âÀý³ÌÓ¦µ±¾¡¿ÉÄÜÊǷDzåÈëʽµÄ£¬ÕâÑù·ÖÅäºÍ¼ì²éÆäÓà×ÊÔ´¹¦ÄÜÐÔ µÄ¹¤×÷¾Í¿ÉÒÔ¸üºÃµØÁô¸øÁ¬½ÓÀý³ÌÀ´×ö¡£
¡¡¡¡ ÄÚ´æµØÖ·¿ÉÒÔÔÚÄÚºËÅäÖÃÎļþÖÐÖ¸¶¨£¬»òÕß¶ÔӦijЩÉ豸¿ÉÒÔÔÚ·ÇÒ×ʧÐÔ ÅäÖüĴæÆ÷ÖÐÔ¤ÏÈÅäÖá£Èç¹ûÁ½ÖÖ×ö·¨¾ù¿ÉÓÃÈ´²»Í¬£¬ÄÇôӦµ±Óà ÄĸöÄØ£¿¿ÉÄÜÓû§Ñá·³ÔÚÄÚºËÅäÖÃÎļþÖÐÃ÷È·ÉèÖõØÖ·£¬µ«ËûÃÇÖªµÀ ×Ô¼ºÔÚ¸Éʲô£¬ÔòÓ¦µ±ÓÅÏÈʹÓÃÕâ¸ö¡£Ò»¸öʵÏÖµÄÀý×Ó¿ÉÄÜÊÇÕâÑùµÄ£º
/* Ê×ÏÈÊÔͼÕÒ³öÅäÖõØÖ· */ sc->mem0_p = bus_get_resource_start(dev, SYS_RES_MEMORY, 0 /*rid*/); if(sc->mem0_p == 0) { /* ûÓУ¬Óû§Ã»Ö¸¶¨ */ sc->mem0_p = xxx_read_mem0_from_device_config(sc); if(sc->mem0_p == 0) /* ´ÓÉ豸ÅäÖüĴæÆ÷Ò²µ½²»ÁËÕâ¶ù */ goto bad; } else { if(xxx_set_mem0_address_on_device(sc) < 0) goto bad; /* É豸²»Ö§³ÖÄǵØÖ· */ } /* ¾ÍÏñ¶Ë¿Ú£¬ÉèÖÃÄÚ´æ´óС£¬ * ¶ÔÓÚijЩÉ豸£¬ÄÚ´æ´óС²»Êdz£Êý£¬ * ¶øÓ¦µ±´ÓÉ豸ÅäÖüĴæÆ÷ÖжÁÈ¡£¬ÒÔÊÊÓ¦É豸µÄ²»Í¬ÐͺŠ* ÁíÒ»¸öÑ¡ÔñÊÇÈÃÓû§°ÑÄÚ´æ´óСÉèÖÃΪ¡°msize¡±ÅäÖÃ×ÊÔ´£¬ * ÓÉISA×ÜÏß×Ô¶¯´¦Àí */ if(pnperror) { /*½ö¶Ô·ÇPnPÉ豸 */ sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 /*rid*/); if(sc->mem0_size == 0) /* Óû§Ã»ÓÐÖ¸¶¨ */ sc->mem0_size = xxx_read_mem0_size_from_device_config(sc); if(sc->mem0_size == 0) { /* ¼Ù¶¨ÕâÊÇÉ豸·Ç³£ÀϵÄÒ»ÖÖÐͺţ¬Ã»ÓÐ×Ô¶¯ÅäÖÃÌØÐÔ£¬ * Óû§Ò²Ã»ÓÐÆ«ºÃÉèÖã¬Òò´Ë¼Ù¶¨×îµÍÒªÇóµÄÇé¿ö * £¨µ±È»£¬ÕæÊµÖµ½«¸ù¾ÝÉ豸Çý¶¯³ÌÐò¶ø²»Í¬£© */ sc->mem0_size = 8*1024; } if(xxx_set_mem0_size_on_device(sc) < 0) goto bad; /*É豸²»Ö§³ÖÄǸö´óС */ if(bus_set_resource(dev, SYS_RES_MEMORY, /*rid*/0, sc->mem0_p, sc->mem0_size)<0) goto bad; } else { sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 /*rid*/); }
¡¡¡¡ ÀàËÆ, ºÜÈÝÒ×¼ì²éIRQºÍDRQËùÓõÄ×ÊÔ´¡£
¡¡¡¡ Èç¹ûÒ»ÇнøÐÐÕý³££¬È»ºó¾Í¿ÉÒÔÊÍ·ÅËùÓÐ×ÊÔ´²¢·µ»Ø³É¹¦¡£
xxx_free_resources(sc); return 0;
¡¡¡¡ ×îºó£¬´¦Àí¼¬ÊÖÇé¿ö¡£ËùÓÐ×ÊÔ´Ó¦µ±ÔÚ·µ»ØÇ°±»ÊÍ·Å¡£ÎÒÃÇÀûÓÃÕâÑùÒ»¸ö ÊÂʵ£ºsoftc½á¹¹ÔÚ´«µÝ¸øÎÒÃÇÒÔǰ±»Á㻯£¬Òò´ËÎÒÃÇÄܹ»ÕÒ³öÊÇ·ñ·ÖÅäÁË Ä³Ð©×ÊÔ´£ºÈç¹û·ÖÅäÔòÕâЩ×ÊÔ´µÄÃèÊö·û·ÇÁã¡£
bad: xxx_free_resources(sc); if(error) return error; else /* È·ÇдíÎóδ֪ */ return ENXIO;
¡¡¡¡ ÕâÊÇÍêÕûµÄ̽²âÀý³Ì¡£×ÊÔ´µÄÊÍ·Å´Ó¶à¸öµØ·½Íê³É£¬Òò´Ë½«ËüŲµ½Ò»¸ö º¯ÊýÖУ¬¿´ÆðÀ´¿ÉÄÜÏñÏÂÃæµÄÑù×Ó£º
static void xxx_free_resources(sc) struct xxx_softc *sc; { /* ¼ì²éÿ¸ö×ÊÔ´£¬Èç¹û·Ç0ÔòÊÍ·Å */ /* Öжϴ¦Àíº¯Êý */ if(sc->intr_r) { bus_teardown_intr(sc->dev, sc->intr_r, sc->intr_cookie); bus_release_resource(sc->dev, SYS_RES_IRQ, sc->intr_rid, sc->intr_r); sc->intr_r = 0; } /* ÎÒÃÇ·ÖÅä¹ýµÄËùÓÐÖÖÀàµÄÄÚ´æ */ if(sc->data_p) { bus_dmamap_unload(sc->data_tag, sc->data_map); sc->data_p = 0; } if(sc->data) { /* sc->data_mapµÈÓÚ0ÓпÉÄܺϷ¨ */ /* the map will also be freed */ bus_dmamem_free(sc->data_tag, sc->data, sc->data_map); sc->data = 0; } if(sc->data_tag) { bus_dma_tag_destroy(sc->data_tag); sc->data_tag = 0; } ... Èç¹ûÓУ¬ÊÍ·ÅÆäËûµÄÓ³ÉäºÍ±êÇ© ... if(sc->parent_tag) { bus_dma_tag_destroy(sc->parent_tag); sc->parent_tag = 0; } /* ÊÍ·ÅËùÓÐ×ÜÏß×ÊÔ´ */ if(sc->mem0_r) { bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->mem0_rid, sc->mem0_r); sc->mem0_r = 0; } ... if(sc->port0_r) { bus_release_resource(sc->dev, SYS_RES_IOPORT, sc->port0_rid, sc->port0_r); sc->port0_r = 0; } }
¡¡¡¡Èç¹û̽²âÀý³Ì·µ»Ø³É¹¦²¢ÇÒϵͳѡÔñÁ¬½ÓÄǸöÇý¶¯³ÌÐò£¬ÔòÁ¬½ÓÀý³Ì ¸ºÔð½«Çý¶¯³ÌÐòʵ¼ÊÁ¬½Óµ½ÏµÍ³¡£Èç¹û̽²âÀý³Ì·µ»Ø0 £¬ÔòÁ¬½ÓÀý³ÌÆÚÍû ½ÓÊÕÍêÕûµÄÉ豸½á¹¹softc£¬´Ë½á¹¹ÓÉ̽²âÀý³ÌÉèÖá£Í¬Ê±£¬Èç¹û̽²âÀý³Ì ·µ»Ø0£¬Ëü¿ÉÄÜÆÚÍûÕâ¸öÉ豸µÄÁ¬½ÓÀý³ÌÓ¦µ±ÔÚ½«À´µÄijµã±»µ÷Óá£Èç¹û ̽²âÀý³Ì·µ»Ø¸ºÖµ£¬ÔòÇý¶¯³ÌÐò¿ÉÄܲ»»á×÷´Ë¼ÙÉè¡£
¡¡¡¡Èç¹û³É¹¦Íê³É£¬Á¬½ÓÀý³Ì·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£
¡¡¡¡Á¬½ÓÀý³ÌµÄÆô¶¯¸ú̽²âÀý³ÌÏàËÆ£¬½«Ò»Ð©³£ÓÃÊý¾ÝÈ¡µ½Ò»Ð©¸üÈÝÒ× ·ÃÎʵıäÁ¿ÖС£
struct xxx_softc *sc = device_get_softc(dev); int unit = device_get_unit(dev); int error = 0;
¡¡¡¡È»ºó·ÖÅä²¢¼¤»îËùÐè×ÊÔ´¡£ÓÉÓڶ˿ڷ¶Î§Í¨³£ÔÚ´Ó̽²â·µ»ØÇ°¾Í ±»ÊÍ·Å£¬Òò´ËÐèÒªÖØÐ·ÖÅä¡£ÎÒÃÇÏ£Íû̽²âÀý³ÌÒѾÊʵ±µØÉèÖÃÁË ËùÓеÄ×ÊÔ´·¶Î§£¬²¢½«ËüÃDZ£´æÔڽṹsoftcÖС£Èç¹û̽²âÀý³ÌÁôÏÂÁË Ò»Ð©±»·ÖÅäµÄ×ÊÔ´£¬¾Í²»ÐèÒªÔٴηÖÅ䣍֨зÖÅä±»ÊÓΪ´íÎ󣩡£
sc->port0_rid = 0; sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port0_rid, /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE); if(sc->port0_r == NULL) return ENXIO; /* °åÉÏÄÚ´æ */ sc->mem0_rid = 0; sc->mem0_r = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem0_rid, /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE); if(sc->mem0_r == NULL) goto bad; /* È¡µÃÐ鵨ַ */ sc->mem0_v = rman_get_virtual(sc->mem0_r);
¡¡¡¡DMAÇëÇóͨµÀ(DRQ)ÒÔÏàËÆ·½Ê½±»·ÖÅ䡣ʹÓà isa_dma*()
º¯Êý×å½øÐгõʼ»¯¡£ÀýÈ磺
¡¡¡¡isa_dmacascade(sc->drq0);
¡¡¡¡ÖжÏÇëÇóÏß(IRQ)ÓеãÌØÊâ¡£³ýÁË·ÖÅäÒÔÍ⣬Çý¶¯³ÌÐòµÄÖжϴ¦Àí º¯ÊýÒ²Ó¦µ±ÓëËü¹ØÁª¡£ÔÚ¹ÅÀϵÄISAÇý¶¯³ÌÐòÖУ¬ÓÉϵͳ´«µÝ¸øÖжϴ¦Àí º¯ÊýµÄ²ÎÁ¿ÊÇÉ豸µ¥ÔªºÅ¡£µ«ÔÚÏÖ´úÇý¶¯³ÌÐòÖУ¬°´ÕÕÔ¼¶¨£¬½¨Òé´«µÝ Ö¸Ïò½á¹¹softcµÄÖ¸Õë¡£Ò»¸öºÜÖØÒªµÄÔÒòÔÚÓÚµ±½á¹¹softc±»¶¯Ì¬·ÖÅäºó£¬ ´ÓsoftcÈ¡µÃµ¥ÔªºÅºÜÈÝÒ×£¬¶ø´Óµ¥ÔªºÅÈ¡µÃsoftcºÜÀ§ÄÑ¡£Í¬Ê±£¬Õâ¸ö Ô¼¶¨Ò²Ê¹µÃÓÃÓÚ²»Í¬×ÜÏßµÄÓ¦ÓóÌÐò¿´ÆðÀ´Í³Ò»£¬²¢ÔÊÐíËüÃǹ²Ïí´úÂ룺 ÿ¸ö×ÜÏßÓÐÆä×Ô¼ºµÄ̽²â£¬Á¬½Ó£¬·ÖÀëºÍÆäËû×ÜÏßÏà¹ØµÄÀý³Ì£¬¶øËüÃÇ Ö®¼ä¿ÉÒÔ¹²Ïí´ó¿éµÄÇý¶¯³ÌÐò´úÂë¡£
sc->intr_rid = 0; sc->intr_r = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->intr_rid, /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE); if(sc->intr_r == NULL) goto bad; /* * ¼Ù¶¨¶ÔXXX_INTR_TYPEµÄ¶¨ÒåÒÀÀµÓÚÇý¶¯³ÌÐòµÄÀàÐÍ£¬ * ÀýÈçINTR_TYPE_CAMÓÃÓÚCAMµÄÇý¶¯³ÌÐò */ error = bus_setup_intr(dev, sc->intr_r, XXX_INTR_TYPE, (driver_intr_t *) xxx_intr, (void *) sc, &sc->intr_cookie); if(error) goto bad;
¡¡¡¡Èç¹ûÇý¶¯³ÌÐòÐèÒªÓëÄÚ´æ½øÐÐDMA£¬ÔòÕâ¿éÄÚ´æÓ¦µ±°´Ç°Êö·½Ê½·ÖÅ䣺
error=bus_dma_tag_create(NULL, /*alignment*/ 4, /*boundary*/ 0, /*lowaddr*/ BUS_SPACE_MAXADDR_24BIT, /*highaddr*/ BUS_SPACE_MAXADDR, /*filter*/ NULL, /*filterarg*/ NULL, /*maxsize*/ BUS_SPACE_MAXSIZE_24BIT, /*nsegments*/ BUS_SPACE_UNRESTRICTED, /*maxsegsz*/ BUS_SPACE_MAXSIZE_24BIT, /*flags*/ 0, &sc->parent_tag); if(error) goto bad; /* ºÜ¶à¶«Î÷ÊÇ´Ó¸¸±êÇ©¼Ì³Ð¶øÀ´ * ¼ÙÉèsc->dataÖ¸Ïò´æ´¢¹²ÏíÊý¾ÝµÄ½á¹¹£¬ÀýÈçÒ»¸ö»·»º³åÇø¿ÉÄÜÊÇ£º * struct { * u_short rd_pos; * u_short wr_pos; * char bf[XXX_RING_BUFFER_SIZE] * } *data; */ error=bus_dma_tag_create(sc->parent_tag, 1, 0, BUS_SPACE_MAXADDR, 0, /*filter*/ NULL, /*filterarg*/ NULL, /*maxsize*/ sizeof(* sc->data), /*nsegments*/ 1, /*maxsegsz*/ sizeof(* sc->data), /*flags*/ 0, &sc->data_tag); if(error) goto bad; error = bus_dmamem_alloc(sc->data_tag, &sc->data, /* flags*/ 0, &sc->data_map); if(error) goto bad; /* ÔÚ&sc->data_pµÄÇé¿öÏ£¬xxx_alloc_callback()Ö»Êǽ«ÎïÀíµØÖ· * ±£´æµ½×÷ΪÆä²ÎÁ¿´«µÝ½øÈ¥µÄÖ¸ÕëÖС£ * ²Î¿´¹ØÓÚ×ÜÏßÄÚ´æÓ³ÉäÒ»½ÚÖеÄÏêϸÄÚÈÝ¡£ * ÆäʵÏÖ¿ÉÒÔÏñÕâÑù£º * * static void * xxx_alloc_callback(void *arg, bus_dma_segment_t *seg, * int nseg, int error) * { * *(bus_addr_t *)arg = seg[0].ds_addr; * } */ bus_dmamap_load(sc->data_tag, sc->data_map, (void *)sc->data, sizeof (* sc->data), xxx_alloc_callback, (void *) &sc->data_p, /*flags*/0);
¡¡¡¡·ÖÅäÁËËùÓеÄ×ÊÔ´ºó£¬É豸Ӧµ±±»³õʼ»¯¡£³õʼ»¯¿ÉÄܰüÀ¨²âÊÔ ËùÓÐÌØÐÔ£¬È·±£ËüÃÇÆð×÷Óá£
if(xxx_initialize(sc) < 0) goto bad;
¡¡¡¡×ÜÏß×Óϵͳ½«×Ô¶¯ÔÚ¿ØÖÆÌ¨ÉÏ´òÓ¡ÓÉ̽²âÀý³ÌÉèÖõÄÉ豸ÃèÊö¡£µ« Èç¹ûÇý¶¯³ÌÐòÏë´òӡһЩ¹ØÓÚÉ豸µÄ¶îÍâÐÅÏ¢£¬Ò²ÊÇ¿ÉÄܵģ¬ÀýÈ磺
device_printf(dev, "has on-card FIFO buffer of %d bytes\n", sc->fifosize);
¡¡¡¡Èç¹û³õʼ»¯Àý³ÌÓöµ½ÈκÎÎÊÌ⣬½¨Òé·µ»Ø´íÎó֮ǰ´òÓ¡ÓйØÐÅÏ¢¡£
¡¡¡¡Á¬½ÓÀý³ÌµÄ×îºóÒ»²½Êǽ«É豸Á¬½Óµ½ÄÚºËÖеŦÄÜ×Óϵͳ¡£Íê³É Õâ¸ö²½ÖèµÄ¾«È··½Ê½ÒÀÀµÓÚÇý¶¯³ÌÐòµÄÀàÐÍ£º×Ö·ûÉ豸¡¢¿éÉ豸¡¢ÍøÂç É豸¡¢CAM SCSI×ÜÏßÉ豸µÈµÈ¡£
¡¡¡¡Èç¹ûËùÓоù¹¤×÷Õý³£Ôò·µ»Ø³É¹¦¡£
error = xxx_attach_subsystem(sc); if(error) goto bad; return 0;
¡¡¡¡×îºó£¬´¦Àí¼¬ÊÖÇé¿ö¡£·µ»Ø´íÎóǰ£¬ËùÓÐ×ÊÔ´Ó¦µ±±»È¡Ïû·ÖÅä¡£ ÎÒÃÇÀûÓÃÕâÑùÒ»¸öÊÂʵ£º½á¹¹softc´«µÝ¸øÎÒÃÇ֮ǰ±»Á㻯£¬Òò´ËÎÒÃÇ ÄÜÕÒ³öÊÇ·ñ·ÖÅäÁËijЩ×ÊÔ´£ºÈç¹û·ÖÅäÔòËüÃǵÄÃèÊö·û·ÇÁã¡£
bad: xxx_free_resources(sc); if(error) return error; else /* exact error is unknown */ return ENXIO;
¡¡¡¡Õâ¾ÍÊÇÁ¬½ÓÀý³ÌµÄÈ«²¿¡£
¡¡¡¡ Èç¹ûÇý¶¯³ÌÐòÖдæÔÚÕâ¸öº¯Êý£¬ÇÒÇý¶¯³ÌÐò±»±àÒëΪ¿É¼ÓÔØÄ£¿é£¬Ôò Çý¶¯³ÌÐò¾ßÓб»Ð¶ÔصÄÄÜÁ¦¡£Èç¹ûÓ²¼þÖ§³ÖÈȲå°Î£¬ÕâÊÇÒ»¸öºÜÖØÒªµÄ ÌØÐÔ¡£µ«ISA×ÜÏß²»Ö§³ÖÈȲå°Î£¬Òò´ËÕâ¸öÌØÐÔ¶ÔÓÚISAÉ豸²»ÊÇÌØ±ð ÖØÒª¡£Ð¶ÔØÇý¶¯³ÌÐòµÄÄÜÁ¦¿ÉÄÜÔÚµ÷ÊÔʱÓÐÓ㬵«ºÜ¶àÇé¿öÏÂÖ»ÓÐÔÚ Àϰ汾µÄÇý¶¯³ÌÐòĪÃûÆäÃîµØ¿¨×¡ÏµÍ³µÄÇé¿öϲÅÐèÒª°²×°Ð°汾µÄ Çý¶¯³ÌÐò£¬²¢ÇÒÎÞÂÛÈçºÎ¶¼ÐèÒªÖØÆô£¬ÕâÑùʹµÃ»¨·Ñ¾«Á¦Ð´·ÖÀëÀý³Ì ÓÐЩ²»ÖµµÃ¡£ÁíÒ»¸öÐû³ÆÐ¶ÔØÔÊÐíÔÚÓÃÓÚÉú²úµÄ»úÆ÷ÉÏÉý¼¶Çý¶¯³ÌÐòµÄ Â۵㿴ÆðÀ´Ëƺõ¸ü¶àµÄÖ»ÊÇÀíÂÛ¶øÒÑ¡£Éý¼¶Çý¶¯³ÌÐòÊÇÒ»ÏîΣÏյIJÙ×÷£¬ ¾ö²»²»Ó¦µ±ÔÚÓÃÓÚÉú²úµÄ»úÆ÷ÉÏʵÐУ¨²¢ÇÒµ±ÏµÍ³ÔËÐÐÓÚ°²È«Ä£Ê½Ê±Õâ Ò²ÊDz»±»ÔÊÐíµÄ£©¡£È»¶ø£¬³öÓÚÍêÕûÐÔ¿¼ÂÇ£¬»¹ÊÇ»áÌṩ·ÖÀëÀý³Ì¡£
¡¡¡¡ Èç¹ûÇý¶¯³ÌÐò³É¹¦·ÖÀ룬·ÖÀëÀý³Ì·µ»Ø0£¬·ñÔò·µ»Ø´íÎóÂë¡£
¡¡¡¡ ·ÖÀëÂß¼ÊÇÁ¬½ÓµÄ¾µÏñ¡£Òª×öµÄµÚÒ»¼þÊÂÇé¾ÍÊǽ«Çý¶¯³ÌÐò´ÓÄÚºË ×Óϵͳ·ÖÀë¡£Èç¹ûÉ豸µ±Ç°Õý´ò¿ª×Å£¬Çý¶¯³ÌÐòÓÐÁ½¸öÑ¡Ôñ£º¾Ü¾ø·ÖÀë »òÕßÇ¿ÖÆ¹Ø±Õ²¢¼ÌÐø½øÐзÖÀ롣ѡÓÃÄÄÖÖ·½Ê½È¡¾öÓÚÌØ¶¨ÄÚºË×Óϵͳ Ö´ÐÐÇ¿ÖÆ¹Ø±ÕµÄÄÜÁ¦ºÍÇý¶¯³ÌÐò×÷Õߵį«ºÃ¡£Í¨³£Ç¿ÖƹرÕËÆºõÊÇ ¸üºÃµÄÑ¡Ôñ¡£
struct xxx_softc *sc = device_get_softc(dev); int error; error = xxx_detach_subsystem(sc); if(error) return error;
¡¡¡¡ ÏÂÒ»²½£¬Çý¶¯³ÌÐò¿ÉÄÜÏ£Íû¸´Î»Ó²¼þµ½Ä³ÖÖÒ»ÖµÄ״̬¡£°üÀ¨Í£Ö¹ÈκΠ½«Òª½øÐеĴ«Ê䣬½ûÓÃDMAͨµÀºÍÖжÏÒÔ±ÜÃâÉè±¸ÆÆ»µÄÚ´æ¡£¶ÔÓÚ´ó¶àÊý Çý¶¯³ÌÐò¶øÑÔ£¬ÕâÕýÊǹرÕÀý³ÌËù×öµÄ£¬Òò´ËÈç¹ûÇý¶¯³ÌÐòÖаüÀ¨¹Ø±Õ Àý³Ì£¬ÎÒÃÇÖ»Òªµ÷ÓÃËü¾Í¿ÉÒÔÁË¡£
¡¡¡¡xxx_isa_shutdown(dev);
¡¡¡¡ ×îºóÊÍ·ÅËùÓÐ×ÊÔ´²¢·µ»Ø³É¹¦¡£
xxx_free_resources(sc); return 0;
¡¡¡¡ µ±ÏµÍ³Òª¹Ø±ÕµÄʱºòµ÷ÓôËÀý³Ì¡£Í¨¹ýËüʹӲ¼þ½øÈëijÖÖÒ»ÖµÄ״̬¡£ ¶ÔÓÚ´ó¶àÊýISAÉ豸¶øÑÔ²»ÐèÒªÌØÊ⶯×÷£¬Òò´ËÕâ¸öº¯Êý²¢·ÇÕæÕý±ØÐ裬 ÒòΪ²»¹ÜÔõÑùÖØÆô¶¯Ê±É豸»á±»ÖØÐ³õʼ»¯¡£µ«ÓÐЩÉ豸±ØÐë°´ÌØ¶¨ ²½Öè¹Ø±Õ£¬ÒÔÈ·±£ÔÚÈíÖØÆôºóÄܱ»ÕýÈ·µØ¼ì²âµ½£¨¶ÔÓںܶàʹÓÃ˽ÓРʶ±ðÐÒéµÄÉè±¸ÌØ±ðÓÐÓã©¡£ºÜ¶àÇé¿öÏ£¬ÔÚÉ豸¼Ä´æÆ÷ÖнûÓÃDMAºÍ Öжϣ¬²¢Í£Ö¹½«Òª½øÐеĴ«ÊäÊǸöºÃÖ÷Ò⡣ȷÇж¯×÷È¡¾öÓÚÓ²¼þ£¬Òò´Ë ÎÒÃÇÎÞ·¨ÔÚ´ËÏêϸÌÖÂÛ¡£
¡¡¡¡ µ±ÊÕµ½À´×ÔÌØ¶¨É豸µÄÖжÏʱ¾Í»áµ÷ÓÃÖжϴ¦Àíº¯Êý¡£ISA×ÜÏß²»Ö§³Ö ÖжϹ²Ïí£¨Ä³Ð©ÌØÊâÇé¿öÀýÍ⣩£¬Òò´Ëʵ¼ÊÉÏÈç¹ûÖжϴ¦Àíº¯Êý±»µ÷Ó㬠¼¸ºõ¿ÉÒÔÈ·ÐÅÖжÏÊÇÀ´×ÔÆäÉ豸¡£È»¶ø£¬Öжϴ¦Àíº¯Êý±ØÐëÂÖѯÉ豸 ¼Ä´æÆ÷²¢È·±£ÖжÏÊÇÓÉËüµÄÉ豸²úÉúµÄ¡£Èç¹û²»ÊÇ£¬Öжϴ¦Àíº¯ÊýÓ¦µ± ·µ»Ø¡£
¡¡¡¡ ISAÇý¶¯³ÌÐòµÄ¾ÉÔ¼¶¨ÊÇÈ¡É豸µ¥ÔªºÅ×÷Ϊ²ÎÁ¿¡£ÏÖÔÚÒѾ·ÏÆú£¬µ± µ÷ÓÃbus_setup_intr()
ʱÐÂÇý¶¯³ÌÐò½ÓÊÕÈκÎ
ÔÚÁ¬½ÓÀý³ÌÖÐΪËûÃÇÖ¸¶¨µÄ²ÎÁ¿¡£¸ù¾ÝÐÂÔ¼¶¨£¬ËüÓ¦µ±ÊÇÖ¸Ïò½á¹¹
softcµÄÖ¸Õë¡£Òò´ËÖжϴ¦Àíº¯Êýͨ³£ÏñÏÂÃæÄÇÑù¿ªÊ¼£º
static void xxx_intr(struct xxx_softc *sc) {
¡¡¡¡ ËüÔËÐÐÔÚÓÉbus_setup_intr()
µÄÖжÏÀàÐͲÎÊýÖ¸¶¨
µÄÖжÏÓÅÏȼ¶ÉÏ¡£ÕâÒâζ׎ûÓÃËùÓÐÆäËûͬÀàÐ͵ÄÖжϺÍËùÓÐÈí¼þÖжϡ£
¡¡¡¡ ΪÁ˱ÜÃ⾺Õù£¬Öжϴ¦ÀíÀý³Ìͨд³ÉÑ»·ÐÎʽ£º
while(xxx_interrupt_pending(sc)) { xxx_process_interrupt(sc); xxx_acknowledge_interrupt(sc); }
¡¡¡¡ Öжϴ¦Àíº¯Êý±ØÐëÖ»ÏòÉ豸Ӧ´ðÖжϣ¬µ«²»ÄÜÏòÖжϿØÖÆÆ÷Ó¦´ð£¬ºóÕßÓÉ ÏµÍ³¸ºÔð´¦Àí¡£
¡¡¡¡±¾Õ½«ÌÖÂÛFreeBSDΪÁ˸øPCI×ÜÏßÉϵÄÉ豸±àдÇý¶¯³ÌÐò¶øÌṩµÄ»úÖÆ¡£
¡¡¡¡Õâ¶ùµÄÐÅÏ¢ÊǹØÓÚPCI×ÜÏß´úÂëÈçºÎµü´úͨ¹ýδÁ¬½ÓµÄÉ豸£¬²¢²é¿´Ð ¼ÓÔØµÄkldÊÇ·ñ»áÁ¬½ÓÆäÖÐÒ»¸ö¡£
/* * ÓëPCIº¯Êý½øÐн»»¥µÄ¼òµ¥KLD * * Murray Stokely */ #include <sys/param.h> /* kernel.hÖÐʹÓõ͍Òå */ #include <sys/module.h> #include <sys/systm.h> #include <sys/errno.h> #include <sys/kernel.h> /* Ä£¿é³õʼ»¯ÖÐʹÓõÄÀàÐÍ */ #include <sys/conf.h> /* cdevsw½á¹¹ */ #include <sys/uio.h> /* uio½á¹¹ */ #include <sys/malloc.h> #include <sys/bus.h> /* pci×ÜÏßÓõ½µÄ½á¹¹¡¢ÔÐÍ */ #include <machine/bus.h> #include <sys/rman.h> #include <machine/resource.h> #include <dev/pci/pcivar.h> /* ΪÁËʹÓÃget_pciºê! */ #include <dev/pci/pcireg.h> /* softc±£´æÎÒÃÇÿ¸öʵÀýµÄÊý¾Ý¡£ */ struct mypci_softc { device_t my_dev; struct cdev *my_cdev; }; /* º¯ÊýÔÐÍ */ static d_open_t mypci_open; static d_close_t mypci_close; static d_read_t mypci_read; static d_write_t mypci_write; /* ×Ö·ûÉ豸Èë¿Úµã */ static struct cdevsw mypci_cdevsw = { .d_version = D_VERSION, .d_open = mypci_open, .d_close = mypci_close, .d_read = mypci_read, .d_write = mypci_write, .d_name = "mypci", }; /* * ÔÚcdevswÀý³ÌÖУ¬ÎÒÃÇͨ¹ý½á¹¹ÌåcdevÖеijÉÔ±si_drv1ÕÒ³öÎÒÃǵÄsoftc¡£ * µ±ÎÒÃǽ¨Á¢/devÏîʱ£¬ÔÚÎÒÃǵÄÒѸ½×ŵÄÀý³ÌÖУ¬ * ÎÒÃÇÉèÖÃÕâ¸ö±äÁ¿Ö¸ÏòÎÒÃǵÄsoftc¡£ */ int mypci_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td) { struct mypci_softc *sc; /* Look up our softc. */ sc = dev->si_drv1; device_printf(sc->my_dev, "Opened successfully.\n"); return (0); } int mypci_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td) { struct mypci_softc *sc; /* Look up our softc. */ sc = dev->si_drv1; device_printf(sc->my_dev, "Closed.\n"); return (0); } int mypci_read(struct cdev *dev, struct uio *uio, int ioflag) { struct mypci_softc *sc; /* Look up our softc. */ sc = dev->si_drv1; device_printf(sc->my_dev, "Asked to read %d bytes.\n", uio->uio_resid); return (0); } int mypci_write(struct cdev *dev, struct uio *uio, int ioflag) { struct mypci_softc *sc; /* Look up our softc. */ sc = dev->si_drv1; device_printf(sc->my_dev, "Asked to write %d bytes.\n", uio->uio_resid); return (0); } /* PCIÖ§³Öº¯Êý */ /* * ½«Ä³¸öÉèÖõıêʶÓëÕâ¸öÇý¶¯³ÌÐòÖ§³ÖµÄ±êʶÏà±È½Ï¡£ * Èç¹ûÏà·û£¬ÉèÖÃÃèÊö×Ö·û²¢·µ»Ø³É¹¦¡£ */ static int mypci_probe(device_t dev) { device_printf(dev, "MyPCI Probe\nVendor ID : 0x%x\nDevice ID : 0x%x\n", pci_get_vendor(dev), pci_get_device(dev)); if (pci_get_vendor(dev) == 0x11c1) { printf("We've got the Winmodem, probe successful!\n"); device_set_desc(dev, "WinModem"); return (BUS_PROBE_DEFAULT); } return (ENXIO); } /* Ö»Óе±Ì½²â³É¹¦Ê±²Åµ÷ÓÃÁ¬½Óº¯Êý */ static int mypci_attach(device_t dev) { struct mypci_softc *sc; printf("MyPCI Attach for : deviceID : 0x%x\n", pci_get_devid(dev)); /* Look up our softc and initialize its fields. */ sc = device_get_softc(dev); sc->my_dev = dev; /* * Create a /dev entry for this device. The kernel will assign us * a major number automatically. We use the unit number of this * device as the minor number and name the character device * "mypci<unit>". */ sc->my_cdev = make_dev(&mypci_cdevsw, device_get_unit(dev), UID_ROOT, GID_WHEEL, 0600, "mypci%u", device_get_unit(dev)); sc->my_cdev->si_drv1 = sc; printf("Mypci device loaded.\n"); return (0); } /* ·ÖÀëÉ豸¡£ */ static int mypci_detach(device_t dev) { struct mypci_softc *sc; /* Teardown the state in our softc created in our attach routine. */ sc = device_get_softc(dev); destroy_dev(sc->my_cdev); printf("Mypci detach!\n"); return (0); } /* ϵͳ¹Ø±ÕÆÚ¼äÔÚsyncÖ®ºóµ÷Óᣠ*/ static int mypci_shutdown(device_t dev) { printf("Mypci shutdown!\n"); return (0); } /* * É豸¹ÒÆðÀý³Ì¡£ */ static int mypci_suspend(device_t dev) { printf("Mypci suspend!\n"); return (0); } /* * É豸»Ö¸´£¨ÖØÐ¿ªÊ¼£©Àý³Ì¡£ */ static int mypci_resume(device_t dev) { printf("Mypci resume!\n"); return (0); } static device_method_t mypci_methods[] = { /* É豸½Ó¿Ú */ DEVMETHOD(device_probe, mypci_probe), DEVMETHOD(device_attach, mypci_attach), DEVMETHOD(device_detach, mypci_detach), DEVMETHOD(device_shutdown, mypci_shutdown), DEVMETHOD(device_suspend, mypci_suspend), DEVMETHOD(device_resume, mypci_resume), { 0, 0 } }; static devclass_t mypci_devclass; DEFINE_CLASS_0(mypci, mypci_driver, mypci_methods, sizeof(struct mypci_softc)); DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);
# Çý¶¯³ÌÐòmypciµÄMakefile KMOD= mypci SRCS= mypci.c SRCS+= device_if.h bus_if.h pci_if.h .include <bsd.kmod.mk>
¡¡¡¡Èç¹ûÄ㽫ÉÏÃæµÄÔ´ÎļþºÍ Makefile·ÅÈëÒ»¸öĿ¼£¬Äã¿ÉÒÔÔËÐÐ make±àÒëʾÀýÇý¶¯³ÌÐò¡£ »¹ÓУ¬Äã¿ÉÒÔÔËÐÐmake load ½«Çý¶¯³ÌÐò×°ÔØµ½µ±Ç°ÕýÔÚÔËÐеÄÄÚºËÖУ¬¶ømake unload¿ÉÔÚ×°ÔØºóÐ¶ÔØÇý¶¯³ÌÐò¡£
¡¡¡¡FreeBSDΪ´Ó¸¸×ÜÏßÇëÇó×ÊÔ´ÌṩÁËÒ»ÖÖÃæÏò¶ÔÏóµÄ»úÖÆ¡£¼¸ºõËùÓÐÉ豸 ¶¼ÊÇijÖÖÀàÐ͵Ä×ÜÏߣ¨PCI, ISA, USB, SCSIµÈµÈ£©µÄº¢×Ó³ÉÔ±£¬²¢ÇÒÕâЩÉ豸 ÐèÒª´ÓËûÃǵĸ¸×ÜÏß»ñÈ¡×ÊÔ´£¨ÀýÈçÄÚ´æ¶Î, ÖжÏÏß, »òÕßDMAͨµÀ£©¡£
¡¡¡¡ÎªÁ˶ÔPCIÉ豸×öЩÓÐÓõÄÊÂÇ飬ÄãÐèÒª´ÓPCIÅäÖÿռä»ñÈ¡ Base Address Registers (BARs)¡£»ñÈ¡BARʱµÄ
PCIÌØ¶¨µÄϸ½Ú±»³éÏóÔÚº¯Êýbus_alloc_resource()
ÖС£
¡¡¡¡ÀýÈ磬һ¸öµäÐ͵ÄÇý¶¯³ÌÐò¿ÉÄÜÔÚattach()
º¯ÊýÖÐÓÐЩÀàËÆÏÂÃæµÄ¶«Î÷£º
sc->bar0id = PCIR_BAR(0); sc->bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bar0id, 0, ~0, 1, RF_ACTIVE); if (sc->bar0res == NULL) { printf("Memory allocation of PCI base register 0 failed!\n"); error = ENXIO; goto fail1; } sc->bar1id = PCIR_BAR(1); sc->bar1res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bar1id, 0, ~0, 1, RF_ACTIVE); if (sc->bar1res == NULL) { printf("Memory allocation of PCI base register 1 failed!\n"); error = ENXIO; goto fail2; } sc->bar0_bt = rman_get_bustag(sc->bar0res); sc->bar0_bh = rman_get_bushandle(sc->bar0res); sc->bar1_bt = rman_get_bustag(sc->bar1res); sc->bar1_bh = rman_get_bushandle(sc->bar1res);
¡¡¡¡Ã¿¸ö»ùÖ·¼Ä´æÆ÷µÄ¾ä±ú±»±£´æÔÚsoftc
½á¹¹ÖУ¬ÒÔ±ãÒÔºó¿ÉÒÔʹÓÃËüÃÇÏòÉ豸дÈë¡£
¡¡¡¡È»ºó¾ÍÄÜʹÓÃÕâЩ¾ä±úÓëbus_space_*
º¯ÊýÒ»Æð
¶ÁдÉ豸¼Ä´æÆ÷¡£ÀýÈ磬Çý¶¯³ÌÐò¿ÉÄܰüº¬ÈçϵĿì½Ýº¯Êý£¬ÓÃÀ´¶ÁÈ¡°å×Ó ÌØ¶¨µÄ¼Ä´æÆ÷£º
uint16_t board_read(struct ni_softc *sc, uint16_t address) { return bus_space_read_2(sc->bar1_bt, sc->bar1_bh, address); }
¡¡¡¡ÀàËÆµÄ£¬¿ÉÒÔÓÃÏÂÃæµÄº¯Êýд¼Ä´æÆ÷£º
void board_write(struct ni_softc *sc, uint16_t address, uint16_t value) { bus_space_write_2(sc->bar1_bt, sc->bar1_bh, address, value); }
¡¡¡¡ÕâЩº¯ÊýÒÔ8룬16λºÍ32λµÄ°æ±¾´æÔÚ£¬ÄãÓ¦µ±ÏàÓ¦µØÊ¹Óà bus_space_{read|write}_{1|2|4}
¡£
×¢Òâ: ÔÚ FreeBSD 7.0 ºÍ¸ü¸ß°æ±¾ÖУ¬ ¿ÉÒÔÓÃ
bus_*
º¯ÊýÀ´´úÌæbus_space_*
¡£bus_*
º¯ÊýʹÓõIJÎÊýÊÇ struct resource * Ö¸Õ룬 ¶ø²»ÊÇ bus tag ºÍ¾ä±ú¡£ ÕâÑù£¬ Äú¾Í¿ÉÒÔ½«softc
ÖÐµÄ bus tag ºÍ bus ¾ä±úÕâÁ½¸ö³ÉÔ±±äÁ¿È¥µô£¬ ²¢½«board_read()
º¯Êý¸ÄдΪ£ºuint16_t board_read(struct ni_softc *sc, uint16_t address) { return (bus_read(sc->bar1res, address)); }
¡¡¡¡Öжϰ´ÕպͷÖÅäÄÚ´æ×ÊÔ´ÏàËÆµÄ·½Ê½´ÓÃæÏò¶ÔÏóµÄ×ÜÏß´úÂë·ÖÅä¡£Ê×ÏÈ£¬ ±ØÐë´Ó¸¸×ÜÏß·ÖÅäIRQ×ÊÔ´£¬È»ºó±ØÐëÉèÖÃÖжϴ¦Àíº¯ÊýÀ´´¦ÀíÕâ¸öIRQ¡£
¡¡¡¡ÔÙÒ»´Î£¬À´×ÔÉ豸attach()
º¯ÊýµÄÀý×Ó±ÈÎÄ×Ö
¸ü¾ß˵Ã÷ÐÔ¡£
/* È¡µÃIRQ×ÊÔ´ */ sc->irqid = 0x0; sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &(sc->irqid), 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); if (sc->irqres == NULL) { printf("IRQ allocation failed!\n"); error = ENXIO; goto fail3; } /* ÏÖÔÚÎÒÃÇÓ¦µ±ÉèÖÃÖжϴ¦Àíº¯Êý */ error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_MISC, my_handler, sc, &(sc->handler)); if (error) { printf("Couldn't set up irq\n"); goto fail4; }
¡¡¡¡ÔÚÉ豸µÄ·ÖÀëÀý³ÌÖбØÐë×¢ÒâһЩÎÊÌâ¡£Äã±ØÐëÍ£¶ÙÉ豸µÄÖжÏÁ÷£¬
²¢ÒƳýÖжϴ¦Àíº¯Êý¡£Ò»µ©bus_teardown_intr()
·µ»Ø£¬ÄãÖªµÀÄãµÄÖжϴ¦Àíº¯Êý²»»áÔÙ±»µ÷Ó㬲¢ÇÒËùÓпÉÄÜÒѾִÐÐÁË
Õâ¸öÖжϴ¦Àíº¯ÊýµÄÏ̶߳¼ÒѾ·µ»Ø¡£ÓÉÓڴ˺¯Êý¿ÉÒÔ˯Ãߣ¬µ÷Óô˺¯Êýʱ
Äã±ØÐë²»ÄÜÓµÓÐÈκλ¥³âÌå¡£
¡¡¡¡±¾½ÚÒÑ·ÏÆú£¬Ö»ÊÇÓÉÓÚÀúÊ·ÔÒò¶ø¸ø³ö¡£´¦ÀíÕâЩÎÊÌâµÄÊʵ±·½·¨ÊÇ Ê¹ÓÃbus_space_dma*()
º¯Êý¡£µ±¸üÐÂÕâÒ»½ÚÒÔ·´Ó³
ÄÇÑùÓ÷¨Ê±£¬Õâ¶Î¾Í¿ÉÄܱ»È¥µô¡£È»¶ø£¬Ä¿Ç°API»¹²»¶ÏÓÐЩ±ä¶¯£¬Òò´ËÒ»µ©
ËüÃǹ̶¨ÏÂÀ´ºó£¬¸üÐÂÕâÒ»½ÚÀ´·´Ó³ÄÇЩ¸Ä¶¯¾ÍºÜºÃÁË¡£
¡¡¡¡ÔÚPCÉÏ£¬Ïë½øÐÐ×ÜÏßÖ÷¿ØDMAµÄÍâΧÉ豸±ØÐë´¦ÀíÎïÀíµØÖ·£¬ÓÉÓÚ
FreeBSDʹÓÃÐéÄâÄÚ´æ²¢ÇÒÖ»´¦ÀíÐ鵨ַ£¬ÕâÈÔÊǸöÎÊÌâ¡£ÐÒÔ˵ÄÊÇ£¬Óиö º¯Êý£¬vtophys()
¿ÉÒÔ°ïÖúÎÒÃÇ¡£
#include <vm/vm.h> #include <vm/pmap.h> #define vtophys(virtual_address) (...)
¡¡¡¡È»¶øÕâ¸ö½â¾ö°ì·¨ÔÚalphaÉÏÓе㲻һÑù£¬²¢ÇÒÎÒÃÇÕæÕýÏëÒªµÄÊÇÒ»¸ö ³ÆÎªvtobus()
µÄº¯Êý¡£
#if defined(__alpha__) #define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va) #else #define vtobus(va) vtophys(va) #endif
¡¡¡¡È¡Ïûattach()
ÆÚ¼ä·ÖÅäµÄËùÓÐ×ÊÔ´·Ç³£ÖØÒª¡£
±ØÐëСÐĽ÷É÷£¬¼´Ê¹ÔÚʧ°ÜµÄÌõ¼þÏÂÒ²Òª±£Ö¤È¡Ïû·ÖÅäÄÇЩÕýÈ·µÄ¶«Î÷£¬
ÕâÑùµ±ÄãµÄÇý¶¯³ÌÐòÈ¥µôºóϵͳÈÔÈ»¿ÉÒÔʹÓá£
¡¡¡¡±¾Îĵµ¼Ù¶¨¶ÁÕß¶ÔFreeBSDµÄÉ豸Çý¶¯³ÌÐòºÍSCSIÐÒéÓдóÖÂÁ˽⣬ ±¾ÎĵµÖкܶàÐÅÏ¢ÊÇ´ÓÒÔÏÂÇý¶¯³ÌÐòÖУº
ncr (/sys/pci/ncr.c) ÓÉWolfgang Stanglmeier and Stefan Esser±àд
sym (/sys/dev/sym/sym_hipd.c) ÓÉGerard Roudier±àд
aic7xxx (/sys/dev/aic7xxx/aic7xxx.c) ÓÉJustin T. Gibbs±àд
¡¡¡¡ºÍ´ÓCAMµÄ´úÂë±¾Éí£¨×÷Õß Justin T. Gibbs£¬ ¼û/sys/cam/*£©ÖÐժ¼¡£µ±Ò»Ð©½â¾ö·½·¨¿´ÆðÀ´ ¼«¾ßÂß¼ÐÔ£¬²¢ÇÒ»ù±¾ÉÏÊÇ´Ó Justin T. Gibbs µÄ´úÂëÖÐÒ»×Ö²»²îµØÕªÂ¼Ê±£¬ ÎÒ½«Æä±ê¼ÇΪ¡°recommended¡±¡£
¡¡¡¡±¾ÎĵµÒÔα´úÂëÀý×Ó½øÐÐ˵Ã÷¡£¾¡¹ÜÓÐʱÀý×ÓÖаüº¬ºÜ¶àϸ½Ú£¬²¢ÇÒ ¿´ÆðÀ´ºÜÏñÕæÕý´úÂ룬µ«ËüÈÔȻֻÊÇα´úÂë¡£ÕâÑùдÊÇΪÁËÒÔÒ»ÖÖ¿ÉÀí½â µÄ·½Ê½À´Õ¹Ê¾¸ÅÄî¡£¶ÔÓÚÕæÕýµÄÇý¶¯³ÌÐò£¬ÆäËü·½·¨¿ÉÄܸüÄ£¿é»¯£¬²¢ÇÒ ¸ü¼Ó¸ßЧ¡£ÎĵµÒ²¶ÔÓ²¼þϸ½Ú½øÐгéÏ󣬶ÔÓÚÄÇЩ»áÄ£ºýÎÒÃÇËùҪչʾµÄ ¸ÅÄîµÄÎÊÌ⣬»ò±»ÈÏΪÔÚ¿ª·¢ÕßÊÖ²áµÄÆäËûÕ½ÚÖÐÒÑÓÐÃèÊöµÄÎÊÌâÒ²×öͬÑù ´¦Àí¡£ÕâЩϸ½Úͨ³£ÒÔµ÷ÓþßÓÐÃèÊöÐÔÃû×ֵĺ¯Êý¡¢×¢ÊÍ»òαÓï¾äµÄÐÎʽչÏÖ¡£ ÐÒÔ˵ÄÊÇ£¬¾ßÓÐʵ¼Ê¼ÛÖµµÄÍêÕûÀý×Ó£¬°üÀ¨ËùÓÐϸ½Ú£¬¿ÉÒÔÔÚÕæÕýµÄÇý¶¯ ³ÌÐòÖÐÕÒµ½¡£
¡¡¡¡CAM´ú±íͨÓ÷ÃÎÊ·½·¨£¨Common Access Method£©¡£ËüÒÔÀàSCSI·½Ê½Ñ°Ö· I/O×ÜÏß¡£Õâ¾ÍÔÊÐí½«Í¨ÓÃÉ豸Çý¶¯³ÌÐòºÍ¿ØÖÆI/O×ÜÏßµÄÇý¶¯³ÌÐò·ÖÀ뿪À´£º ÀýÈç´ÅÅÌÇý¶¯³ÌÐòÄÜͬʱ¿ØÖÆSCSI¡¢IDE¡¢ÇÒ/»òÈÎºÎÆäËû×ÜÏßÉϵĴÅÅÌ£¬ ÕâÑù´ÅÅÌÇý¶¯³ÌÐò²¿·Ö²»±ØÎªÃ¿ÖÖеÄI/O×ÜÏß¶øÖØÐ´£¨»ò¿½±´Ð޸ģ©¡£ ÕâÑù£¬Á½¸ö×îÖØÒªµÄ»î¶¯ÊµÌåÊÇ£º
ÍâΧÉ豸ģ¿é - ÍâΧÉ豸£¨´ÅÅÌ£¬ ´Å´ø£¬ CD-ROMµÈ£©µÄÇý¶¯³ÌÐò
SCSI½Ó¿ÚÄ£¿é(SIM) - Á¬½Óµ½I/O×ÜÏߣ¬ÈçSCSI»òIDE£¬µÄÖ÷»ú×ÜÏßÊÊÅäÆ÷Çý¶¯³ÌÐò¡£
¡¡¡¡ÍâΧÉ豸Çý¶¯³ÌÐò´ÓOS½ÓÊÕÇëÇ󣬽«ËüÃÇת»»ÎªSCSIÃüÁîÐòÁв¢½« ÕâЩSCSIÃüÁî´«µÝµ½SCSI½Ó¿ÚÄ£¿é¡£SCSI½Ó¿ÚÄ£¿é¸ºÔð½«ÕâЩÃüÁî´«µÝ¸ø ʵ¼ÊÓ²¼þ£¨»òÕßÈç¹ûʵ¼ÊÓ²¼þ²»ÊÇSCSI£¬¶øÊÇÀýÈçIDE£¬ÔòÒ²Òª½«ÕâЩSCSI ÃüÁîת»»ÎªÓ²¼þµÄnativeÃüÁ¡£
¡¡¡¡ÓÉÓÚÕâ¶ùÎÒÃǸÐÐËȤµÄÊDZàдSCSIÊÊÅäÆ÷Çý¶¯³ÌÐò£¬´Ó´Ë´¦¿ªÊ¼ÎÒÃÇ ½«´ÓSIMµÄ½Ç¶È¿¼ÂÇËùÓеÄÊÂÇé¡£
¡¡¡¡µäÐ͵ÄSIMÇý¶¯³ÌÐòÐèÒª°üÀ¨ÈçϵÄCAMÏà¹ØµÄÍ·Îļþ£º
#include <cam/cam.h> #include <cam/cam_ccb.h> #include <cam/cam_sim.h> #include <cam/cam_xpt_sim.h> #include <cam/cam_debug.h> #include <cam/scsi/scsi_all.h>
¡¡¡¡Ã¿¸öSIMÇý¶¯³ÌÐò±ØÐë×öµÄµÚÒ»¼þÊÂÇéÊÇÏòCAM×Óϵͳע²áËü×Ô¼º¡£
ÕâÔÚÇý¶¯³ÌÐòµÄxxx_attach()
º¯Êý£¨´Ë´¦ºÍÒÔºóµÄ
xxx_ÓÃÓÚÖ¸´øÎ¨Ò»µÄÇý¶¯³ÌÐòÃû×Öǰ׺£©ÆÚ¼äÍê³É¡£ xxx_attach()
º¯Êý×ÔÉíÓÉϵͳ×ÜÏß×Ô¶¯ÅäÖôúÂë
µ÷Óã¬ÎÒÃÇÔڴ˲»ÃèÊöÕⲿ·Ö´úÂë¡£
¡¡¡¡ÕâÐèÒªºÃ¼¸²½À´Íê³É£ºÊ×ÏÈÐèÒª·ÖÅäÓëSIM¹ØÁªµÄÇëÇó¶ÓÁУº
struct cam_devq *devq; if(( devq = cam_simq_alloc(SIZE) )==NULL) { error; /* һЩ´¦Àí´íÎóµÄ´úÂë */ }
¡¡¡¡´Ë´¦ SIZE ΪҪ·ÖÅäµÄ¶ÓÁеĴóС£¬ ËüÄܰüº¬µÄ×î´óÇëÇóÊýÄ¿¡£ ËüÊÇ SIM Çý¶¯³ÌÐòÔÚ SCSI ¿¨ÉÏÄܹ»²¢Ðд¦ÀíµÄÇëÇóµÄÊýÄ¿¡£Ò»°ã¿ÉÒÔÈçϹÀË㣺
SIZE = NUMBER_OF_SUPPORTED_TARGETS * MAX_SIMULTANEOUS_COMMANDS_PER_TARGET
¡¡¡¡ÏÂÒ»²½ÎªÎÒÃǵÄSIM´´½¨ÃèÊö·û£º
struct cam_sim *sim; if(( sim = cam_sim_alloc(action_func, poll_func, driver_name, softc, unit, max_dev_transactions, max_tagged_dev_transactions, devq) )==NULL) { cam_simq_free(devq); error; /* һЩ´íÎó´¦Àí´úÂë */ }
¡¡¡¡×¢ÒâÈç¹ûÎÒÃDz»ÄÜ´´½¨SIMÃèÊö·û£¬ÎÒÃÇÒ²ÊÍ·Å devq
£¬ÒòΪÎÒÃÇ¶ÔÆäÎÞ·¨×öÈÎºÎÆäËûÊÂÇ飬 ¶øÇÒÎÒÃÇÏë½ÚÔ¼ÄÚ´æ¡£
¡¡¡¡Èç¹ûSCSI¿¨ÉÏÓжàÌõSCSI×ÜÏߣ¬ÔòÿÌõ×ÜÏßÐèÒªËü×Ô¼ºµÄ cam_sim
½á¹¹¡£
¡¡¡¡Ò»¸öÓÐȤµÄÎÊÌâÊÇ£¬Èç¹ûSCSI¿¨Óв»Ö»Ò»ÌõSCSI×ÜÏßÎÒÃǸÃÔõô×ö£¬
ÿ¸ö¿¨ÐèÒªÒ»¸ödevq
½á¹¹»¹ÊÇÿÌõSCSI×ÜÏߣ¿
ÔÚCAM´úÂëµÄ×¢ÊÍÖиø³öµÄ´ð°¸ÊÇ£ºÈÎÒ»·½Ê½¾ù¿É£¬ÓÉÇý¶¯³ÌÐòµÄ×÷Õß Ñ¡Ôñ¡£
¡¡¡¡²ÎÁ¿Îª£º
action_func
- Ö¸ÏòÇý¶¯³ÌÐò xxx_action
º¯ÊýµÄÖ¸Õë¡£
poll_func
- Ö¸ÏòÇý¶¯³ÌÐò xxx_poll()
º¯ÊýµÄÖ¸Õë¡£
driver_name - ʵ¼ÊÇý¶¯³ÌÐòµÄÃû×Ö£¬ÀýÈç ¡°ncr¡±»ò¡°wds¡±¡£
softc
- Ö¸ÏòÕâ¸öSCSI¿¨
Çý¶¯³ÌÐòµÄÄÚ²¿ÃèÊö·ûµÄÖ¸Õë¡£Õâ¸öÖ¸ÕëÒÔºó±»Çý¶¯³ÌÐòÓÃÀ´»ñÈ¡ ˽ÓÐÊý¾Ý¡£
unit - ¿ØÖÆÆ÷µ¥ÔªºÅ£¬ÀýÈç¶ÔÓÚ¿ØÖÆÆ÷ ¡°wds0¡±µÄ´ËÊý×Ö½«Îª0¡£
max_dev_transactions - ÎÞ±êǩģʽÏÂÿ¸öSCSIÄ¿±êµÄ ×î´ó²¢·¢£¨simultaneous£©ÊÂÎñÊý¡£Õâ¸öÖµÒ»°ã¼¸ºõ×ÜÊǵÈÓÚ1£¬Ö»ÓÐ·Ç SCSI¿¨²Å¿ÉÄÜÀýÍâ¡£´ËÍ⣬Èç¹ûÇý¶¯³ÌÐòÏ£ÍûÖ´ÐÐÒ»¸öÊÂÎñµÄͬʱ׼±¸Áí Ò»¸öÊÂÎñ£¬¿ÉÒÔ½«ÆäÉèÖÃΪ2£¬µ«Ëƺõ²»ÖµµÃÔö¼ÓÕâÖÖ¸´ÔÓÐÔ¡£
max_tagged_dev_transactions - ͬÑùµÄ¶«Î÷£¬µ«ÊÇ ÔÚ±êǩģʽÏ¡£±êÇ©ÊÇSCSIÔÚÉ豸ÉÏ·¢Æð¶à¸öÊÂÎñµÄ·½Ê½£ºÃ¿¸öÊÂÎñ ±»¸³ÓèÒ»¸öΨһµÄ±êÇ©£¬²¢±»·¢Ë͵½É豸¡£µ±É豸Íê³ÉijЩÊÂÎñ£¬Ëü ½«½á¹ûÁ¬Í¬±êǩһÆð·¢ËÍ»ØÀ´£¬ÕâÑùSCSIÊÊÅäÆ÷£¨ºÍÇý¶¯³ÌÐò£©¾ÍÄÜÖªµÀ ÄĸöÊÂÎñÍê³ÉÁË¡£´Ë²ÎÁ¿Ò²±»ÈÏΪÊÇ×î´ó±êÇ©Éî¶È¡£ËüÈ¡¾öÓÚSCSI ÊÊÅäÆ÷µÄÄÜÁ¦¡£
¡¡¡¡×îºóÎÒÃÇ×¢²áÓëÎÒÃǵÄSCSIÊÊÅäÆ÷¹ØÁªµÄSCSI×ÜÏß¡£
if(xpt_bus_register(sim, bus_number) != CAM_SUCCESS) { cam_sim_free(sim, /*free_devq*/ TRUE); error; /* һЩ´íÎó´¦Àí´úÂë */ }
¡¡¡¡Èç¹ûÿÌõSCSI×ÜÏßÓÐÒ»¸ödevq
½á¹¹£¨¼´£¬
ÎÒÃǽ«´øÓжàÌõ×ÜÏߵĿ¨¿´×÷¶à¸ö¿¨£¬Ã¿¸ö¿¨´øÓÐÒ»Ìõ×ÜÏߣ©£¬Ôò×ÜÏߺÅ
×ÜÊÇΪ0£¬·ñÔòSCSI¿¨ÉϵÄÿÌõ×ÜÏßÓ¦µ±Óв»Í¬µÄºÅ¡£Ã¿Ìõ×ÜÏßÐèÒª Ëü×Ô¼ºµ¥¶ÀµÄcam_sim½á¹¹¡£
¡¡¡¡ÕâÖ®ºóÎÒÃǵĿØÖÆÆ÷ÍêÈ«¹Ò½Óµ½CAMϵͳ¡£ÏÖÔÚ devq
µÄÖµ¿ÉÒÔ±»¶ªÆú£ºÔÚËùÓÐÒÔºó´ÓCAM·¢³öµÄ
µ÷ÓÃÖн«ÒÔsimΪ²ÎÁ¿£¬devq¿ÉÒÔÓÉËüµ¼³ö¡£
¡¡¡¡CAMΪÕâЩÒ첽ʼþÌṩÁË¿ò¼Ü¡£ÓÐЩʼþÀ´×Եײ㣨SIMÇý¶¯³ÌÐò£©£¬ ÓÐЩÀ´×ÔÍâΧÉ豸Çý¶¯³ÌÐò£¬»¹ÓÐһЩÀ´×ÔCAM×Óϵͳ±¾Éí¡£ÈκÎÇý¶¯ ³ÌÐò¶¼¿ÉÒÔΪijЩÀàÐ͵ÄÒ첽ʼþ×¢²á»Øµ÷£¬ÕâÑùÄÇЩʼþ·¢ÉúʱËü¾Í »á±»Í¨Öª¡£
¡¡¡¡ÕâÖÖʼþµÄÒ»¸öµäÐÍÀý×Ó¾ÍÊÇÉ豸¸´Î»¡£Ã¿¸öÊÂÎñºÍʼþÒÔ ¡°path¡±µÄ·½Ê½Çø·ÖËüÃÇËù×÷ÓõÄÉ豸¡£Ä¿±êÌØ¶¨µÄʼþ ͨ³£ÔÚÓëÉ豸½øÐÐÊÂÎñ´¦ÀíÆÚ¼ä·¢Éú¡£Òò´ËÄǸöÊÂÎñµÄ·¾¶¿ÉÒÔ±»ÖØÓà À´±¨¸æ´Ëʼþ£¨ÕâÊǰ²È«µÄ£¬ÒòΪʼþ·¾¶µÄ¿½±´ÊÇÔÚʼþ±¨¸æÀý³ÌÖнøÐеģ¬ ¶øÇҼȲ»»á±»deallocateÒ²²»×÷½øÒ»²½´«µÝ£©¡£ÔÚÈκÎʱ¿Ì£¬°üÀ¨ÖжÏÀý³ÌÖУ¬ ¶¯Ì¬·ÖÅä·¾¶Ò²Êǰ²È«µÄ£¬¾¡¹ÜÄÇÑù»áµ¼ÖÂijЩ¶îÍ⿪Ïú£¬²¢ÇÒÕâÖÖ·½·¨ ¿ÉÄÜ´æÔÚµÄÒ»¸öÎÊÌâÊÇÅöÇÉÄÇʱ¿ÉÄÜûÓпÕÏÐÄÚ´æ¡£¶ÔÓÚ×ÜÏ߸´Î»Ê¼þ£¬ ÎÒÃÇÐèÒª¶¨Òå°üÀ¨×ÜÏßÉÏËùÓÐÉ豸ÔÚÄÚµÄͨÅä·û·¾¶¡£ÕâÑùÎÒÃǾÍÄÜÌáǰΪ ÒÔºóµÄ×ÜÏ߸´Î»Ê¼þ´´½¨Â·¾¶£¬±ÜÃâÒÔºóÄÚ´æ²»×ãµÄÎÊÌ⣺
struct cam_path *path; if(xpt_create_path(&path, /*periph*/NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(sim)); cam_sim_free(sim, /*free_devq*/TRUE); error; /* һЩ´íÎó´¦Àí´úÂë */ } softc->wpath = path; softc->sim = sim;
¡¡¡¡ÕýÈçÄãËù¿´µ½µÄ£¬Â·¾¶°üÀ¨£º
ÍâΧÉ豸Çý¶¯³ÌÐòµÄID£¨ÓÉÓÚÎÒÃÇÒ»¸öҲûÓУ¬¹Ê´Ë´¦Îª¿Õ£©
SIMÇý¶¯³ÌÐòµÄID £¨cam_sim_path(sim)
£©
É豸µÄSCSIÄ¿±êºÅ£¨CAM_TARGET_WILDCARDµÄÒâ˼ָ ¡°ËùÓÐdevices¡±£©
×ÓÉ豸µÄSCSI LUNºÅ£¨CAM_LUN_WILDCARDµÄÒâ˼ָ ¡°ËùÓÐLUNs¡±£©
¡¡¡¡Èç¹ûÇý¶¯³ÌÐò²»ÄÜ·ÖÅäÕâ¸ö·¾¶£¬Ëü½«²»ÄÜÕý³£¹¤×÷£¬Òò´ËÄÇÑùÇé¿öÏ ÎÒÃÇж³ý£¨dismantle£©ÄǸöSCSI×ÜÏß¡£
¡¡¡¡ÎÒÃÇÔÚsoftc
½á¹¹Öб£´æÂ·¾¶Ö¸ÕëÒÔ±ãÒÔºó
ʹÓá£ÕâÖ®ºóÎÒÃDZ£´æsimµÄÖµ£¨»òÕßÈç¹ûÎÒÃÇÔ¸Ò⣬Ҳ¿ÉÒÔÔÚ´Ó xxx_probe()
Í˳öʱ¶ªÆúËü£©¡£
¡¡¡¡Õâ¾ÍÊÇ×îµÍÒªÇóµÄ³õʼ»¯ËùÐèÒª×öµÄÒ»ÇС£ÎªÁ˰ÑÊÂÇé×öÕýÈ·ÎÞÎó£¬ »¹Ê£ÏÂÒ»¸öÎÊÌâ¡£
¡¡¡¡¶ÔÓÚSIMÇý¶¯³ÌÐò£¬ÓÐÒ»¸öÌØÊâ¸ÐÐËȤµÄʼþ£ººÎʱĿ±êÉ豸±»ÈÏΪ ÕÒ²»µ½ÁË¡£ÕâÖÖÇé¿öϸ´Î»ÓëÕâ¸öÉ豸µÄSCSIÐÉÌ¿ÉÄÜÊǸöºÃÖ÷Òâ¡£Òò´ËÎÒÃÇ ÎªÕâ¸öʼþÏòCAM×¢²áÒ»¸ö»Øµ÷¡£Í¨¹ýΪÕâÖÖÀàÐ͵ÄÇëÇóÀ´ÇëÇóCAM¿ØÖÆ¿éÉÏ µÄCAM¶¯×÷£¬ÇëÇó¾Í±»´«µÝµ½CAM£º£¨Òë×¢£º²Î¿´ÏÂÃæÊ¾Àý´úÂëºÍÔÎÄ£©
struct ccb_setasync csa; xpt_setup_ccb(&csa.ccb_h, path, /*ÓÅÏȼ¶*/5); csa.ccb_h.func_code = XPT_SASYNC_CB; csa.event_enable = AC_LOST_DEVICE; csa.callback = xxx_async; csa.callback_arg = sim; xpt_action((union ccb *)&csa);
¡¡¡¡ÏÖÔÚÎÒÃÇ¿´Ò»ÏÂxxx_action()
ºÍxxx_poll()
µÄÇý¶¯³ÌÐòÈë¿Úµã¡£
¡¡¡¡
¡¡¡¡ÏìÓ¦CAM×ÓϵͳµÄÇëÇó²ÉȡijЩ¶¯×÷¡£SimÃèÊöÁËÇëÇóµÄSIM£¬CCBΪ ÇëÇó±¾Éí¡£CCB´ú±í¡°CAM Control Block¡±¡£ËüÊǺܶàÌØ¶¨ ʵÀýµÄÁªºÏ£¬Ã¿¸öʵÀýΪijЩÀàÐ͵ÄÊÂÎñÃèÊö²ÎÁ¿¡£ËùÓÐÕâЩʵÀý¹²Ïí ´æ´¢×ŲÎÁ¿¹«¹²²¿·ÖµÄCCBÍ·²¿¡££¨Òë×¢£ºÕâÒ»¶Î²»ºÜ׼ȷ£¬Çë×ÔÐвο¼ÔÎÄ£©
¡¡¡¡CAM¼ÈÖ§³ÖSCSI¿ØÖÆÆ÷¹¤×÷ÓÚ·¢ÆðÕß(initiator)(¡°normal¡±) ģʽ£¬Ò²Ö§³ÖSCSI¿ØÖÆÆ÷¹¤×÷ÓÚÄ¿±ê(target)£¨Ä£ÄâSCSIÉ豸£©Ä£Ê½¡£Õâ¶ù ÎÒÃÇÖ»¿¼ÂÇÓë·¢ÆðÕßģʽÓйصIJ¿·Ö¡£
¡¡¡¡¶¨ÒåÁ˼¸¸öº¯ÊýºÍºê£¨»»¾ä»°Ëµ£¬·½·¨£©À´·ÃÎʽṹsimÖй«¹²Êý¾Ý£º
cam_sim_path(sim)
- ·¾¶ID £¨²Î¼ûÉÏÃæ£©
cam_sim_name(sim)
- simµÄÃû×Ö
cam_sim_softc(sim)
-
Ö¸Ïòsoftc£¨Çý¶¯³ÌÐò˽ÓÐÊý¾Ý£©½á¹¹µÄÖ¸Õë
cam_sim_unit(sim)
- µ¥ÔªºÅ
cam_sim_bus(sim)
- ×ÜÏßID
¡¡¡¡ÎªÁËʶ±ðÉ豸£¬xxx_action()
¿ÉÒÔʹÓÃÕâЩ
º¯ÊýµÃµ½µ¥ÔªºÅºÍÖ¸ÏòËüµÄsoftc½á¹¹µÄÖ¸Õë¡£
¡¡¡¡ÇëÇóµÄÀàÐͱ»´æ´¢ÔÚ ccb->ccb_h.func_code
¡£Òò´Ë£¬Í¨³£ xxx_action()
ÓÉÒ»¸ö´óµÄswitch×é³É£º
struct xxx_softc *softc = (struct xxx_softc *) cam_sim_softc(sim); struct ccb_hdr *ccb_h = &ccb->ccb_h; int unit = cam_sim_unit(sim); int bus = cam_sim_bus(sim); switch(ccb_h->func_code) { case ...: ... default: ccb_h->status = CAM_REQ_INVALID; xpt_done(ccb); break; }
¡¡¡¡´Ódefault caseÓï¾ä²¿·Ö¿ÉÒÔ¿´³ö£¨Èç¹ûÊÕµ½Î´ÖªÃüÁ£¬ÃüÁîµÄ·µ»ØÂë ±»ÉèÖõ½
ccb->ccb_h.status
ÖУ¬²¢ÇÒͨ¹ý µ÷ÓÃxpt_done(ccb)
½«Õû¸öCCB·µ»Øµ½CAMÖС£
¡¡¡¡xpt_done()
²»±Ø´Ó xxx_action()
Öе÷ÓãºÀýÈçI/OÇëÇó¿ÉÒÔÔÚSIMÇý¶¯³ÌÐò
ºÍ/»òËüµÄSCSI¿ØÖÆÆ÷ÖÐÅŶӡ££¨Òë×¢£ºËüÖ¸I/OÇëÇ󣿣©
È»ºó£¬µ±É豸´«µÝ(post)Ò»¸öÖжÏÐźţ¬Ö¸Ê¾¶Ô´ËÇëÇóµÄ´¦ÀíÒѽáÊøÊ±£¬ xpt_done()
¿ÉÒÔ´ÓÖжϴ¦ÀíÀý³ÌÖб»µ÷Óá£
¡¡¡¡Êµ¼ÊÉÏ£¬CCB״̬²»Êǽö½ö±»¸³ÖµÎªÒ»¸ö·µ»ØÂ룬¶øÊÇʼÖÕÓÐijÖÖ״̬¡£
CCB±»´«µÝ¸øxxx_action()
Àý³Ìǰ£¬ÆäÈ¡µÃ״̬
CCB_REQ_INPROG£¬±íʾÆäÕýÔÚ½øÐÐÖС£/sys/cam/cam.h
Öж¨ÒåÁËÊýÁ¿¾ªÈ˵Ä״ֵ̬£¬ËüÃÇÓ¦¸ÃÄܷdz£Ï꾡µØ±íʾÇëÇóµÄ״̬¡£
¸üÓÐȤµÄÊÇ£¬×´Ì¬Êµ¼ÊÉÏÊÇÒ»¸öö¾Ù״ֵ̬£¨µÍ6룩ºÍһЩ¿ÉÄܳöÏֵĸ½¼Ó
Àà(ËÆ)Æì±ê루¸ß룩µÄ¡°Î»»ò(bitwise or)¡±¡£Ã¶¾ÙÖµ»áÔÚÒÔºó
¸üÏêϸµØÌÖÂÛ¡£¶ÔËüÃǵĻã×Ü¿ÉÒÔÔÚ´íÎó¸ÅÀÀ½Ú(Errors Summary section)
ÕÒµ½¡£¿ÉÄܵÄ״̬Æì±êΪ£º
CAM_DEV_QFRZN - µ±´¦ÀíCCBʱ£¬
Èç¹ûSIMÇý¶¯³ÌÐòµÃµ½Ò»¸öÑÏÖØ´íÎó£¨ÀýÈ磬Çý¶¯³ÌÐò²»ÄÜÏìӦѡÔñ»òÎ¥·´
ÁËSCSIÐÒ飩£¬ËüÓ¦µ±µ÷ÓÃxpt_freeze_simq()
¶³½á
ÇëÇó¶ÓÁУ¬°Ñ´ËÉ豸µÄÆäËûÒÑÈë¶Óµ«ÉÐδ±»´¦ÀíµÄCCB·µ»Øµ½CAM¶ÓÁУ¬
È»ºóΪÓÐÎÊÌâµÄCCBÉèÖÃÕâ¸öÆì±ê²¢µ÷Óà xpt_done()
¡£Õâ¸öÆì±ê»áʹµÃCAM×Óϵͳ´¦Àí´íÎóºó ½â¶³¶ÓÁС£
CAM_AUTOSNS_VALID - Èç¹ûÉ豸 ·µ»Ø´íÎóÌõ¼þ£¬ÇÒCCBÖÐδÉèÖÃÆì±êCAM_DIS_AUTOSENSE£¬SIMÇý¶¯³ÌÐò ±ØÐë×Ô¶¯Ö´ÐÐREQUEST SENSEÃüÁîÀ´´ÓÉ豸³éÈ¡sense£¨À©Õ¹´íÎóÐÅÏ¢£© Êý¾Ý¡£Èç¹ûÕâ¸ö³¢ÊԳɹ¦£¬senseÊý¾ÝÓ¦µ±±»±£´æÔÚCCBÖÐÇÒÉèÖÃ´ËÆì±ê¡£
CAM_RELEASE_SIMQ - ÀàËÆÓÚ
CAM_DEV_QFRZN£¬µ«ÓÃÓÚSCSI¿ØÖÆÆ÷×ÔÉí³öÎÊÌâ(»ò×ÊÔ´¶Ìȱ)µÄÇé¿ö¡£
´Ëºó¶Ô¿ØÖÆÆ÷µÄËùÓÐÇëÇó»á±»xpt_freeze_simq()
Í£Ö¹¡£SIMÇý¶¯³ÌÐò¿Ë·þÕâÖÖ¶ÌȱÇé¿ö£¬²¢Í¨¹ý·µ»ØÉèÖÃÁË´ËÆì±êµÄCCB
֪ͨCAMºó£¬¿ØÖÆÆ÷¶ÓÁн«»á±»ÖØÐÂÆô¶¯¡£
CAM_SIM_QUEUED - µ±SIM½«Ò»¸ö CCB·ÅÈëÆäÇëÇó¶ÓÁÐʱӦµ±ÉèÖÃ´ËÆì±ê£¨»òµ±CCB³ö¶Óµ«ÉÐδ·µ»Ø¸øCAMʱ È¥µô£©¡£ÏÖÔÚ´ËÆì±ê»¹Ã»ÓÐÔÚCAM´úÂëµÄÈκεط½Ê¹Óùý£¬Òò´ËÆäÄ¿µÄ ´¿´âÓÃÓÚÕï¶Ï£©¡£
¡¡¡¡º¯Êýxxx_action()
²»ÔÊÐí˯Ãߣ¬Òò´Ë¶Ô×ÊÔ´
·ÃÎʵÄËùÓÐͬ²½±ØÐëͨ¹ý¶³½áSIM»òÉ豸¶ÓÁÐÀ´Íê³É¡£³ýÁËǰÊöµÄÆì±êÍ⣬
CAM×ÓϵͳÌṩÁ˺¯Êýxpt_release_simq()
ºÍ xpt_release_devq()
À´Ö±½Ó½â¶³¶ÓÁУ¬¶ø²»±Ø½« CCB´«µÝµ½CAM¡£
¡¡¡¡CCBÍ·²¿°üº¬ÈçÏÂ×ֶΣº
path - ÇëÇóµÄ·¾¶ID
target_id - ÇëÇóµÄÄ¿±êÉ豸ID
target_lun - Ä¿±êÉ豸µÄLUN ID
timeout - Õâ¸öÃüÁîµÄ³¬Ê±¼ä¸ô£¬ÒÔºÁÃë¼Æ
timeout_ch - Ò»¸öΪSIMÇý¶¯ ³ÌÐò´æ´¢³¬Ê±´¦Àíº¯ÊýµÄ·½±ãÖ®Ëù£¨CAM×Óϵͳ×ÔÉí²¢²»¶Ô´Ë×÷ÈκμÙÉ裩
flags - ÓйØÇëÇóµÄ¸÷¸ö ÐÅϢλ
spriv_ptr0£¬spriv_ptr1 - SIMÇý¶¯³ÌÐò±£Áô˽ÓõÄ×Ö¶Î £¨ÀýÈçÁ´½Óµ½SIM¶ÓÁлòSIM˽ÓпØÖƿ飩£»Êµ¼ÊÉÏ£¬ËüÃÇ×÷ΪÁªºÏ´æÔÚ£º spriv_ptr0ºÍspriv_ptr1¾ßÓÐÀàÐÍ(void *)£¬spriv_field0ºÍ spriv_field1¾ßÓÐÀàÐÍunsigned long£¬sim_priv.entries[0].bytesºÍ sim_priv.entries[1].bytesΪÓëÁªºÏµÄÆäËûÐÎʽ´óСһÖµÄ×Ö½ÚÊý×飬 sim_priv.bytesΪһ¸öÁ½±¶´óСµÄÊý×é
¡¡¡¡Ê¹ÓÃCCBµÄSIM˽ÓÐ×ֶεĽ¨Òé·½·¨ÊÇΪËüÃǶ¨ÒåһЩÓÐÒâÒåµÄÃû×Ö£¬ ²¢ÇÒÔÚÇý¶¯³ÌÐòÖÐʹÓÃÕâЩÓÐÒâÒåµÄÃû×Ö£¬¾ÍÏñÏÂÃæÕâÑù£º
#define ccb_some_meaningful_name sim_priv.entries[0].bytes #define ccb_hcb spriv_ptr1 /* ÓÃÓÚÓ²¼þ¿ØÖÆ¿é */
¡¡¡¡×î³£¼ûµÄ·¢ÆðÕßģʽµÄÇëÇóÊÇ£º
XPT_SCSI_IO - Ö´ÐÐI/OÊÂÎñ
ÁªºÏccbµÄ¡°struct ccb_scsiio csio¡±ÊµÀýÓÃÓÚ´«µÝ²ÎÁ¿¡£ ËüÃÇÊÇ£º
cdb_io - Ö¸ÏòSCSIÃüÁ³åÇøµÄÖ¸Õë»ò»º³åÇø±¾Éí
cdb_len - SCSIÃüÁ¶È
data_ptr - Ö¸ÏòÊý¾Ý»º³åÇøµÄÖ¸Õ루Èç¹ûʹÓ÷ÖÉ¢/¼¯ÖлḴÔÓÒ»µã£©
dxfer_len - ´ý´«ÊäÊý¾ÝµÄ³¤¶È
sglist_cnt - ·ÖÉ¢/¼¯ÖжεļÆÊý
scsi_status - ·µ»ØSCSI״̬µÄµØ·½
sense_data - ÃüÁî·µ»Ø´íÎóʱ±£´æSCSI senseÐÅÏ¢µÄ»º³åÇø£¨ÕâÖÖÇé¿öÏ£¬Èç¹ûûÓÐ ÉèÖÃCCBµÄÆì±êCAM_DIS_AUTOSENSE£¬Ôò¼Ù¶¨SIMÇý¶¯³ÌÐò»á×Ô¶¯ÔËÐÐ REQUEST SENSEÃüÁ
sense_len - »º³åÇøµÄ³¤¶È£¨Èç¹ûÅöÇÉ´óÓÚsense_dataµÄ´óС£¬SIMÇý¶¯³ÌÐò±ØÐë ÇÄÇĵزÉÓýÏСֵ£©£¨Òë×¢£ºÒ»µã¸Ä¶¯£¬²Î¿¼ÔÎļ°´úÂ룩
resid, sense_resid - Èç¹ûÊý¾Ý´«Êä»òSCSI sense·µ»Ø´íÎó£¬ÔòËüÃÇ ¾ÍÊÇ·µ»ØµÄÊ£Óࣨδ´«Ê䣩Êý¾ÝµÄ¼ÆÊý¡£ËüÃÇ¿´ÆðÀ´²¢²»ÊÇÌØ±ðÓÐÒâÒ壬 Òò´Ëµ±ºÜÄѼÆËãµÄÇé¿öÏ£¨ÀýÈ磬¼ÆÊýSCSI¿ØÖÆÆ÷FIFO»º³åÇøÖеÄ×Ö½Ú Êý£©£¬Ê¹ÓýüËÆÖµÒ²Í¬Ñù¿ÉÒÔ¡£¶ÔÓڳɹ¦Íê³ÉµÄ´«Ê䣬ËüÃDZØÐë±»ÉèÖà Ϊ0¡£
tag_action - ʹÓõıêÇ©µÄÖÖÀàÓУº
CAM_TAG_ACTION_NONE - ÊÂÎñ²»Ê¹ÓñêÇ©
MSG_SIMPLE_Q_TAG, MSG_HEAD_OF_Q_TAG, MSG_ORDERED_Q_TAG - ÖµµÈÓÚÊʵ±µÄ±êÇ©ÐÅÏ¢ £¨¼û/sys/cam/scsi/scsi_message.h£©£»½ö¸ø³ö±êÇ©ÀàÐÍ£¬SIMÇý¶¯³ÌÐò ±ØÐë×Ô¼º¸³±êǩֵ
´¦ÀíÇëÇóµÄͨ³£Âß¼ÈçÏ£º
Òª×öµÄµÚÒ»¼þÊÂÇéÊǼì²é¿ÉÄܵľºÕùÌõ¼þ£¬È·±£ÃüÁîλÓÚ¶ÓÁÐÖÐʱ ²»»á±»ÖÐÖ¹£º
struct ccb_scsiio *csio = &ccb->csio; if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { xpt_done(ccb); return; }
ÎÒÃÇÒ²¼ì²éÎÒÃǵĿØÖÆÆ÷Íêȫ֧³ÖÉ豸£º
if(ccb_h->target_id > OUR_MAX_SUPPORTED_TARGET_ID || cch_h->target_id == OUR_SCSI_CONTROLLERS_OWN_ID) { ccb_h->status = CAM_TID_INVALID; xpt_done(ccb); return; } if(ccb_h->target_lun > OUR_MAX_SUPPORTED_LUN) { ccb_h->status = CAM_LUN_INVALID; xpt_done(ccb); return; }
È»ºó·ÖÅäÎÒÃÇ´¦ÀíÇëÇóËùÐèµÄÊý¾Ý½á¹¹£¨È翨Ïà¹ØµÄÓ²¼þ¿ØÖÆ¿éµÈ£©¡£ Èç¹ûÎÒÃDz»ÄÜ·ÖÅäÔò¶³½áSIM¶ÓÁУ¬¼Ç¼ÏÂÎÒÃÇÓÐÒ»¸ö¹ÒÆðµÄ²Ù×÷£¬·µ»Ø CCB£¬ÇëÇóCAM½«CCBÖØÐÂÈë¶Ó¡£ÒÔºóµ±×ÊÔ´¿ÉÓÃʱ£¬±ØÐëͨ¹ý·µ»ØÆä ״̬ÖÐÉèÖà CAM_SIMQ_RELEASE λµÄccbÀ´½â¶³SIM¶ÓÁС£·ñÔò£¬Èç¹ûËùÓÐ Õý³££¬Ôò½«CCBÓëÓ²¼þ¿ØÖƿ飨HCB£©Á´½Ó£¬²¢½«Æä±ê־ΪÒÑÈë¶Ó¡£
struct xxx_hcb *hcb = allocate_hcb(softc, unit, bus); if(hcb == NULL) { softc->flags |= RESOURCE_SHORTAGE; xpt_freeze_simq(sim, /*count*/1); ccb_h->status = CAM_REQUEUE_REQ; xpt_done(ccb); return; } hcb->ccb = ccb; ccb_h->ccb_hcb = (void *)hcb; ccb_h->status |= CAM_SIM_QUEUED;
´ÓCCBÖÐÌáȡĿ±êÊý¾Ýµ½Ó²¼þ¿ØÖƿ顣¼ì²éÊÇ·ñÒªÇóÎÒÃÇ·ÖÅäÒ»¸ö ±êÇ©£¬Èç¹ûÊÇÔò²úÉúÒ»¸öΨһµÄ±êÇ©²¢¹¹ÔìSCSI±êÇ©ÐÅÏ¢¡£SIMÇý¶¯³ÌÐò Ò²¸ºÔðÓëÉ豸ÐÉÌÉ趨±Ë´ËÖ§³ÖµÄ×î´ó×ÜÏß¿í¶È¡¢Í¬²½ËÙÂÊºÍÆ«ÒÆ¡£
hcb->target = ccb_h->target_id; hcb->lun = ccb_h->target_lun; generate_identify_message(hcb); if( ccb_h->tag_action != CAM_TAG_ACTION_NONE ) generate_unique_tag_message(hcb, ccb_h->tag_action); if( !target_negotiated(hcb) ) generate_negotiation_messages(hcb);
È»ºóÉèÖÃSCSIÃüÁî¡£¿ÉÒÔÔÚCCBÖÐÒÔ¶àÖÖÓÐȤµÄ·½Ê½Ö¸¶¨ÃüÁîµÄ´æ´¢£¬ ÕâЩ·½Ê½ÓÉCCBÖÐµÄÆì±êÖ¸¶¨¡£ÃüÁ³åÇø¿ÉÒÔ°üº¬ÔÚCCBÖлòÕßÓÃÖ¸Õë Ö¸Ïò£¬ºóÕßÇé¿öÏÂÖ¸Õë¿ÉÒÔÖ¸ÏòÎïÀíµØÖ·»òÐ鵨ַ¡£ÓÉÓÚÓ²¼þͨ³£ÐèÒª ÎïÀíµØÖ·£¬Òò´ËÎÒÃÇ×ÜÊǽ«µØÖ·×ª»»ÎªÎïÀíµØÖ·¡£
²»Ì«Ïà¹ØµÄÌáʾ£ºÍ¨³£ÕâÊÇͨ¹ýµ÷ÓÃvtophys()
À´Íê³ÉµÄ£¬µ«ÓÉÓÚ
ÌØÊâµÄAlpha¹ÖÒìÖ®´¦£¬ÎªÁËPCIÉ豸£¨ËüÃÇÏÖÔÚÕ¼SCSI¿ØÖÆÆ÷µÄ´ó¶àÊý£©
Çý¶¯³ÌÐòÏòAlpha¼Ü¹¹µÄ¿ÉÒÆÖ²ÐÔ£¬×ª»»±ØÐëÌæ´úÒÔ vtobus()
À´Íê³É¡£ [IMHO ÌṩÁ½¸öµ¥¶ÀµÄº¯Êý vtop()
ºÍ ptobus()
£¬¶ø vtobus()
Ö»ÊÇËüÃǵÄ
¼òµ¥µþ´ú£¬ÕâÑù×öÒªºÃµÃ¶à¡£] ÔÚÇëÇóÎïÀíµØÖ·µÄÇé¿öÏ£¬·µ»Ø´øÓÐ״̬ ¡°CAM_REQ_INVALID¡± µÄCCBÊÇ¿ÉÒԵ쬵±Ç°µÄÇý¶¯³ÌÐò¾ÍÊÇÄÇÑù×öµÄ¡£µ«Ò²
¿ÉÄÜÏñÕâ¸öÀý×Ó£¨Çý¶¯³ÌÐòÖÐÓ¦µ±Óв»´øÌõ¼þ±àÒëµÄ¸üÖ±½Ó×ö·¨£©ÖÐÄÇÑù
±àÒëAlphaÌØ¶¨µÄ´úÂëÆ¬¶Ï¡£Èç¹ûÐèÒªÎïÀíµØÖ·Ò²ÄÜת»»»òÓ³É仨Ð鵨ַ£¬
µ«ÄÇÑù´ú¼ÛºÜ´ó£¬Òò´ËÎÒÃDz»ÄÇÑù×ö¡£
if(ccb_h->flags & CAM_CDB_POINTER) { /* CDB is a pointer */ if(!(ccb_h->flags & CAM_CDB_PHYS)) { /* CDBÖ¸ÕëÊÇÐéÄâµÄ */ hcb->cmd = vtobus(csio->cdb_io.cdb_ptr); } else { /* CDBÖ¸ÕëÊÇÎïÀíµÄ */ #if defined(__alpha__) hcb->cmd = csio->cdb_io.cdb_ptr | alpha_XXX_dmamap_or ; #else hcb->cmd = csio->cdb_io.cdb_ptr ; #endif } } else { /* CDBÔÚccb(»º³åÇø)ÖÐ */ hcb->cmd = vtobus(csio->cdb_io.cdb_bytes); } hcb->cmdlen = csio->cdb_len;
ÏÖÔÚÊÇÉèÖÃÊý¾ÝµÄʱºòÁË£¬ÓÖÒ»´Î£¬¿ÉÒÔÔÚCCBÖÐÒÔ¶àÖÖÓÐȤµÄ·½Ê½ Ö¸¶¨Êý¾Ý´æ´¢£¬ÕâЩ·½Ê½ÓÉCCBÖÐµÄÆì±êÖ¸¶¨¡£Ê×ÏÈÎÒÃǵõ½Êý¾Ý´«ÊäµÄ ·½Ïò¡£×î¼òµ¥µÄÇé¿öÊÇûÓÐÊý¾ÝÐèÒª´«ÊäµÄÇé¿ö£º
int dir = (ccb_h->flags & CAM_DIR_MASK); if (dir == CAM_DIR_NONE) goto end_data;
È»ºóÎÒÃǼì²éÊý¾ÝÔÚÒ»¸öchunkÖл¹ÊÇÔÚ·ÖÉ¢/¼¯ÖÐÁбíÖУ¬²¢ÇÒÊÇ ÎïÀíµØÖ·»¹ÊÇÐ鵨ַ¡£SCSI¿ØÖÆÆ÷¿ÉÄÜÖ»ÄÜ´¦ÀíÓÐÏÞÊýÄ¿ÓÐÏÞ³¤¶ÈµÄ ´ó¿é¡£Èç¹ûÇëÇóµ½´ïµ½Õâ¸öÏÞÖÆÎÒÃǾͷµ»Ø´íÎó¡£ÎÒÃÇʹÓÃÒ»¸öÌØÊâ º¯Êý·µ»ØCCB£¬²¢ÔÚÒ»¸öµØ·½´¦ÀíHCB×ÊÔ´¶Ìȱ¡£Ôö¼ÓchunkµÄº¯ÊýÊÇ Çý¶¯³ÌÐòÏà¹ØµÄ£¬´Ë´¦ÎÒÃDz»½øÈëËüÃǵÄÏêϸʵÏÖ¡£¶ÔÓÚµØÖ··ÒëÎÊÌâ µÄϸ½Ú¿ÉÒԲο´SCSIÃüÁî(CDB)´¦ÀíµÄÃèÊö¡£Èç¹ûijЩ±äÌå¶ÔÓÚÌØ¶¨µÄ¿¨ Ì«À§ÄÑ»ò²»¿ÉÄÜʵÏÖ£¬·µ»Ø×´Ì¬ ¡°CAM_REQ_INVALID¡± ÊÇ¿ÉÒԵġ£Êµ¼ÊÉÏ£¬ ÏÖÔÚµÄCAM´úÂëÖÐËÆºõÄĶùҲûÓÐʹÓ÷ÖÉ¢/¼¯ÖÐÄÜÁ¦¡£µ«ÖÁÉÙ±ØÐëʵÏÖ µ¥¸ö·Ç·ÖÉ¢ÐéÄ⻺³åÇøµÄÇé¿ö£¬CAMÖÐÕâÖÖÇé¿öÓõúܶࡣ
int rv; initialize_hcb_for_data(hcb); if((!(ccb_h->flags & CAM_SCATTER_VALID)) { /* µ¥¸ö»º³åÇø */ if(!(ccb_h->flags & CAM_DATA_PHYS)) { rv = add_virtual_chunk(hcb, csio->data_ptr, csio->dxfer_len, dir); } } else { rv = add_physical_chunk(hcb, csio->data_ptr, csio->dxfer_len, dir); } } else { int i; struct bus_dma_segment *segs; segs = (struct bus_dma_segment *)csio->data_ptr; if ((ccb_h->flags & CAM_SG_LIST_PHYS) != 0) { /* SGÁбíÖ¸ÕëÊÇÎïÀíµÄ */ rv = setup_hcb_for_physical_sg_list(hcb, segs, csio->sglist_cnt); } else if (!(ccb_h->flags & CAM_DATA_PHYS)) { /* SG»º³åÇøÖ¸ÕëÊÇÐéÄâµÄ */ for (i = 0; i < csio->sglist_cnt; i++) { rv = add_virtual_chunk(hcb, segs[i].ds_addr, segs[i].ds_len, dir); if (rv != CAM_REQ_CMP) break; } } else { /* SG»º³åÇøÖ¸ÕëÊÇÎïÀíµÄ */ for (i = 0; i < csio->sglist_cnt; i++) { rv = add_physical_chunk(hcb, segs[i].ds_addr, segs[i].ds_len, dir); if (rv != CAM_REQ_CMP) break; } } } if(rv != CAM_REQ_CMP) { /* Èç¹û³É¹¦Ìí¼ÓÁËÒ»chunk£¬ÎÒÃÇÏ£Íûadd_*_chunk()º¯Êý·µ»Ø * CAM_REQ_CMP£¬Èç¹ûÇëÇóÌ«´ó£¨Ì«¶à×Ö½Ú»òÌ«¶àchunks£© * Ôò·µ»ØCAM_REQ_TOO_BIG, ÆäËûÇé¿öÏ·µ»Ø¡°CAM_REQ_INVALID¡±¡£ */ free_hcb_and_ccb_done(hcb, ccb, rv); return; } end_data:
Èç¹ûÕâ¸öCCB²»ÔÊÐí¶Ï¿ªÁ¬½Ó£¬ÎÒÃǾʹ«µÝÕâ¸öÐÅÏ¢µ½hcb£º
if(ccb_h->flags & CAM_DIS_DISCONNECT) hcb_disable_disconnect(hcb);
Èç¹û¿ØÖÆÆ÷Äܹ»ÍêÈ«×Ô¼ºÔËÐÐREQUEST SENSEÃüÁÔòÒ²Ó¦µ±½«Æì±ê CAM_DIS_AUTOSENSEµÄÖµ´«µÝ¸øËü£¬ÕâÑù¿ÉÒÔÔÚCAM×Óϵͳ²»ÏëREQUEST SENSE ʱ×èÖ¹×Ô¶¯REQUEST SENSE¡£
ʣϵÄΨһÊÂÇéÊÇÉèÖó¬Ê±£¬½«ÎÒÃǵÄhcb´«µÝ¸øÓ²¼þ²¢·µ»Ø£¬ÓàÏ嵀 ÓÉÖжϴ¦Àíº¯Êý£¨»ò³¬Ê±´¦Àíº¯Êý£©Íê³É¡£
ccb_h->timeout_ch = timeout(xxx_timeout, (caddr_t) hcb, (ccb_h->timeout * hz) / 1000); /* ½«ºÁÃëת»»ÎªµÎ´ðÊý */ put_hcb_into_hardware_queue(hcb); return;
Õâ¶ùÊÇ·µ»ØCCBµÄº¯ÊýµÄÒ»¸ö¿ÉÄÜʵÏÖ£º
static void free_hcb_and_ccb_done(struct xxx_hcb *hcb, union ccb *ccb, u_int32_t status) { struct xxx_softc *softc = hcb->softc; ccb->ccb_h.ccb_hcb = 0; if(hcb != NULL) { untimeout(xxx_timeout, (caddr_t) hcb, ccb->ccb_h.timeout_ch); /* ÎÒÃÇÒªÊÍ·Åhcb£¬Òò´Ë×ÊÔ´¶ÌȱÎÊÌâÒ²¾Í²»´æÔÚÁË */ if(softc->flags & RESOURCE_SHORTAGE) { softc->flags &= ~RESOURCE_SHORTAGE; status |= CAM_RELEASE_SIMQ; } free_hcb(hcb); /* ͬʱ´ÓÈκÎÄÚ²¿ÁбíÖÐÒÆ³ýhcb */ } ccb->ccb_h.status = status | (ccb->ccb_h.status & ~(CAM_STATUS_MASK|CAM_SIM_QUEUED)); xpt_done(ccb); }
XPT_RESET_DEV - ·¢ËÍSCSI ¡°BUS DEVICE RESET¡±ÏûÏ¢µ½É豸
³ýÁËÍ·²¿ÍâCCBÖÐûÓÐÊý¾Ý´«Ê䣬ÆäÖÐ×îÈÃÈ˸ÐÐËȤµÄ²ÎÁ¿Îªtarget_id¡£ ÒÀÀµÓÚ¿ØÖÆÆ÷Ó²¼þ£¬Ó²¼þ¿ØÖÆ¿é¾ÍÏñXPT_SCSI_IOÇëÇóÖÐÄÇÑù±»´´½¨ £¨²Î¿´XPT_SCSI_IOÇëÇóµÄÃèÊö£©²¢±»·¢Ë͵½¿ØÖÆÆ÷£¬»òÕßÁ¢¼´±à³ÌÈÃSCSI ¿ØÖÆÆ÷·¢ËÍRESETÏûÏ¢µ½É豸£¬»òÕßÕâ¸öÇëÇó¿ÉÄÜÖ»ÊDz»±»Ö§³Ö £¨²¢·µ»Ø×´Ì¬ ¡°CAM_REQ_INVALID¡±£©¡£¶øÇÒÇëÇóÍê³Éʱ£¬Ä¿±êµÄËùÓÐÒѶϿª Á¬½Ó(disconnected)µÄÊÂÎñ±ØÐë±»ÖÐÖ¹£¨¿ÉÄÜÔÚÖжÏÀý³ÌÖУ©¡£
¶øÇÒÄ¿±êµÄËùÓе±Ç°ÐÉÌÔÚ¸´Î»Ê±»á¶ªÊ§£¬Òò´ËËüÃÇÒ²¿ÉÄܱ»Çå³ý¡£ »òÕßÇå³ý¿ÉÄܱ»ÑÓ³Ù£¬ÒòΪ²»¹ÜÔõÑùÄ¿±ê½«»áÔÚÏÂÒ»´ÎÊÂÎñʱÇëÇóÖØÐÂÐÉÌ¡£
XPT_RESET_BUS - ·¢ËÍRESETÐźŵ½SCSI×ÜÏß
CCBÖв¢²»´«µÝ²ÎÁ¿£¬Î¨Ò»¸ÐÐËȤµÄ²ÎÁ¿ÊÇÓÉÖ¸Ïò½á¹¹simµÄÖ¸Õë±êʶ µÄSCSI×ÜÏß¡£
×îСʵÏÖ»áÍü¼Ç×ÜÏßÉÏËùÓÐÉ豸µÄSCSIÐÉÌ£¬²¢·µ»Ø×´Ì¬ CAM_REQ_CMP¡£
Ç¡µ±µÄʵÏÖʵ¼ÊÉÏ»áÁíÍ⸴λSCSI×ÜÏߣ¨¿ÉÄÜÒ²¸´Î»SCSI¿ØÖÆÆ÷£©²¢ ½«ËùÓÐÔÚÓ²¼þ¶ÓÁÐÖеĺͶϿªÁ¬½ÓµÄÄÇЩÕý±»´¦ÀíµÄCCBµÄÍê³É״̬±ê¼ÇΪ CAM_SCSI_BUS_RESET¡£ÏñÕâÑù£º
int targ, lun; struct xxx_hcb *h, *hh; struct ccb_trans_settings neg; struct cam_path *path; /* SCSI×ÜÏ߸´Î»¿ÉÄܻỨ·ÑºÜ³¤Ê±¼ä£¬ÕâÖÖÇé¿öÏÂÓ¦µ±Ê¹ÓÃÖжϻò³¬Ê±À´¼ì²é * ¸´Î»ÊÇ·ñÍê³É¡£µ«ÎªÁ˼òµ¥£¬ÎÒÃÇÕâ¶ù¼ÙÉ踴λºÜ¿ì¡£ */ reset_scsi_bus(softc); /* ¶ªÆúËùÓÐÈë¶ÓµÄCCB */ for(h = softc->first_queued_hcb; h != NULL; h = hh) { hh = h->next; free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET); } /* ÐÉ̵ģ¨Çå³ý²Ù×÷ºóµÄ£©¸É¾»Öµ£¬ÎÒÃDZ¨¸æÕâ¸öÖµ */ neg.bus_width = 8; neg.sync_period = neg.sync_offset = 0; neg.valid = (CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID); /* ¶ªÆúËùÓжϿªÁ¬½ÓµÄCCBºÍ¸É¾»µÄÐÉÌ£¨Òë×¢£º¸É¾»£½clean£© */ for(targ=0; targ <= OUR_MAX_SUPPORTED_TARGET; targ++) { clean_negotiations(softc, targ); /* Èç¹û¿ÉÄܱ¨¸æÊ¼þ */ if(xpt_create_path(&path, /*periph*/NULL, cam_sim_path(sim), targ, CAM_LUN_WILDCARD) == CAM_REQ_CMP) { xpt_async(AC_TRANSFER_NEG, path, &neg); xpt_free_path(path); } for(lun=0; lun <= OUR_MAX_SUPPORTED_LUN; lun++) for(h = softc->first_discon_hcb[targ][lun]; h != NULL; h = hh) { hh=h->next; free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET); } } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); /* ±¨¸æÊ¼þ */ xpt_async(AC_BUS_RESET, softc->wpath, NULL); return;
½«SCSI×ÜÏ߸´Î»×÷Ϊº¯ÊýÀ´ÊµÏÖ¿ÉÄÜÊǸöºÃÖ÷Ò⣬ÒòΪÈç¹ûÊÂÇé³öÁ˲î´í£¬ Ëü»á±»³¬Ê±º¯Êý×÷Ϊ×îºóµÄ±¨¸æÀ´ÖØÓá£
XPT_ABORT - ÖÐÖ¹Ö¸¶¨µÄCCB
²ÎÁ¿ÔÚÁªºÏccbµÄʵÀý¡°struct ccb_abort cab¡± Öд«Êä¡£ÆäÖÐΨһµÄ²ÎÁ¿×Ö¶ÎΪ£º
abort_ccb - Ö¸Ïò±»ÖÐÖ¹µÄccbµÄÖ¸Õë
Èç¹û²»Ö§³ÖÖжϾͷµ»ØCAM_UA_ABORT¡£ÕâÒ²ÊÇ×îС»¯ÊµÏÖÕâ¸öµ÷ÓÃµÄ ¼òÒ×·½Ê½£¬ÈκÎÇé¿ö϶¼·µ»ØCAM_UA_ABORT¡£
À§ÄÑ·½Ê½ÔòÊÇÕæÕýµØÊµÏÖÕâ¸öÇëÇó¡£Ê×Ïȼì²éÓ¦Óõ½SCSIÊÂÎñµÄÖÐÖ¹£º
struct ccb *abort_ccb; abort_ccb = ccb->cab.abort_ccb; if(abort_ccb->ccb_h.func_code != XPT_SCSI_IO) { ccb->ccb_h.status = CAM_UA_ABORT; xpt_done(ccb); return; }
È»ºóÐèÒªÔÚÎÒÃǵĶÓÁÐÖÐÕÒµ½Õâ¸öCCB¡£Õâ¿ÉÒÔͨ¹ý±éÀúÎÒÃÇËùÓÐÓ²¼þ ¿ØÖÆ¿éÁÐ±í£¬²éÕÒÓëÕâ¸öCCB¹ØÁªµÄ¿ØÖÆ¿éÀ´Íê³É£º
struct xxx_hcb *hcb, *h; hcb = NULL; /* ÎÒÃǼÙÉèsoftc->first_hcbÊÇÓë´Ë×ÜÏß¹ØÁªµÄËùÓÐHCBµÄÁбíÍ·ÔªËØ£¬ * °üÀ¨ÄÇЩÈë¶Ó´ý´¦ÀíµÄ¡¢Ó²¼þÕýÔÚ´¦ÀíµÄºÍ¶Ï¿ªÁ¬½ÓµÄÄÇЩ¡£ */ for(h = softc->first_hcb; h != NULL; h = h->next) { if(h->ccb == abort_ccb) { hcb = h; break; } } if(hcb == NULL) { /* ÎÒÃǵĶÓÁÐÖÐûÓÐÕâÑùµÄCCB */ ccb->ccb_h.status = CAM_PATH_INVALID; xpt_done(ccb); return; } hcb=found_hcb;
ÏÖÔÚÎÒÃÇÀ´¿´Ò»ÏÂHCBµ±Ç°µÄ´¦Àí״̬¡£Ëü¿ÉÄÜ»ò´ôÔÚ¶ÓÁÐÖÐÕýµÈ´ý ±»·¢Ë͵½SCSI×ÜÏߣ¬»ò´ËʱÕýÔÚ´«ÊäÖУ¬»òÒѶϿªÁ¬½Ó²¢µÈ´ýÃüÁî½á¹û£¬ »òÕßʵ¼ÊÉÏÒÑÓÉÓ²¼þÍê³Éµ«ÉÐδ±»Èí¼þ±ê¼ÇΪÍê³É¡£ÎªÁËÈ·±£ÎÒÃDz»»á ÓëÓ²¼þ²úÉú¾ºÕùÌõ¼þ£¬ÎÒÃǽ«HCB±ê¼ÇΪÖÐÖ¹(aborted)£¬ÕâÑùÈç¹ûÕâ¸ö HCBÒª±»·¢Ë͵½SCSI×ÜÏߵϰ£¬SCSI¿ØÖÆÆ÷½«»á¿´µ½Õâ¸öÆì±ê²¢Ìø¹ýËü¡£
int hstatus; /* ´Ë´¦ÏÔʾΪһ¸öº¯Êý£¬ÓÐʱÐèÒªÌØÊ⶯×÷²ÅÄÜʹµÃÕâ¸öÆì±ê¶ÔÓ²¼þ¿É¼û */ set_hcb_flags(hcb, HCB_BEING_ABORTED); abort_again: hstatus = get_hcb_status(hcb); switch(hstatus) { case HCB_SITTING_IN_QUEUE: remove_hcb_from_hardware_queue(hcb); /* ¼ÌÐøÖ´ÐÐ */ case HCB_COMPLETED: /* ÕâÊÇÒ»ÖÖ¼òµ¥µÄÇé¿ö */ free_hcb_and_ccb_done(hcb, abort_ccb, CAM_REQ_ABORTED); break;
Èç¹ûCCB´ËʱÕýÔÚ´«ÊäÖУ¬ÎÒÃÇÒ»°ã»áÒÔijÖÖÓ²¼þÏà¹ØµÄ·½Ê½·¢ÐźŠ¸øSCSI¿ØÖÆÆ÷£¬Í¨ÖªËüÎÒÃÇÏ£ÍûÖÐÖ¹µ±Ç°µÄ´«Êä¡£SCSI¿ØÖÆÆ÷»áÉèÖà SCSI ATTENTIONÐźţ¬²¢µ±Ä¿±ê¶ÔÆä½øÐÐÏìÓ¦ºó·¢ËÍABORTÏûÏ¢¡£ÎÒÃÇÒ²¸´Î» ³¬Ê±£¬ÒÔÈ·±£Ä¿±ê²»»áÓÀԶ˯Ãß¡£Èç¹ûÃüÁî²»ÄÜÔÚij¸öºÏÀíµÄʱ¼ä£¬Èç 10ÃëÄÚÖÐÖ¹£¬³¬Ê±Àý³Ì¾Í»áÔËÐв¢¸´Î»Õû¸öSCSI×ÜÏß¡£ÓÉÓÚÃüÁî»áÔÚij¸ö ºÏÀíµÄʱ¼äºó±»ÖÐÖ¹£¬Òò´ËÎÒÃÇÏÖÔÚ¿ÉÒÔÖ»½«ÖÐÖ¹ÇëÇ󷵻أ¬µ±×÷³É¹¦Íê³É£¬ ²¢½«±»ÖÐÖ¹µÄCCB±ê¼ÇΪÖÐÖ¹£¨µ«»¹Ã»Óн«Ëü±ê¼ÇΪÍê³É£©¡£
case HCB_BEING_TRANSFERRED: untimeout(xxx_timeout, (caddr_t) hcb, abort_ccb->ccb_h.timeout_ch); abort_ccb->ccb_h.timeout_ch = timeout(xxx_timeout, (caddr_t) hcb, 10 * hz); abort_ccb->ccb_h.status = CAM_REQ_ABORTED; /* ÒªÇó¿ØÖÆÆ÷ÖÐÖ¹CCB£¬È»ºó²úÉúÒ»¸öÖжϲ¢Í£Ö¹ */ if(signal_hardware_to_abort_hcb_and_stop(hcb) < 0) { /* °¥Ñ½£¬ÎÒÃÇûÓлñµÃÓëÓ²¼þµÄ¾ºÕùÌõ¼þ£¬ÔÚÎÒÃÇÖÐÖ¹ * Õâ¸öÊÂÎñ֮ǰËü¾ÍÍÑÀë×ÜÏߣ¬ÔÙ³¢ÊÔÒ»´Î * £¨Òë×¢£ºÍÑÀ룽getoff£©*/ goto abort_again; } break;
Èç¹ûCCBλÓÚ¶Ï¿ªÁ¬½ÓµÄÁбíÖУ¬Ôò½«ËüÉèÖÃΪÖÐÖ¹ÇëÇ󣬲¢ÔÚÓ²¼þ ¶ÓÁеÄǰ¶Ë½«ËüÖØÐÂÈë¶Ó¡£¸´Î»³¬Ê±£¬²¢±¨¸æÖÐÖ¹ÇëÇóÍê³É¡£
case HCB_DISCONNECTED: untimeout(xxx_timeout, (caddr_t) hcb, abort_ccb->ccb_h.timeout_ch); abort_ccb->ccb_h.timeout_ch = timeout(xxx_timeout, (caddr_t) hcb, 10 * hz); put_abort_message_into_hcb(hcb); put_hcb_at_the_front_of_hardware_queue(hcb); break; } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return;
Õâ¾ÍÊǹØÓÚABORTÇëÇóµÄÈ«²¿£¬¾¡¹Ü»¹ÓÐÒ»¸öÎÊÌâ¡£ÓÉÓÚABORTÏûÏ¢ Çå³ýLUNÉÏËùÓÐÕýÔÚ½øÐÐÖеÄÊÂÎñ£¬ÎÒÃDZØÐ뽫LUNÉÏËùÓÐÆäËû»î¶¯ÊÂÎñ ±ê¼ÇΪÖÐÖ¹¡£ÄÇÓ¦µ±ÔÚÖжÏÀý³ÌÖÐÍê³É£¬ÇÒÔÚÖÐÖ¹ÊÂÎñÖ®ºó¡£
½«CCBÖÐÖ¹×÷Ϊº¯ÊýÀ´ÊµÏÖ¿ÉÄÜÊǸöºÜºÃµÄÖ÷Ò⣬ÒòΪÈç¹ûI/OÊÂÎñ³¬Ê± Õâ¸öº¯ÊýÄܹ»±»ÖØÓá£Î¨Ò»µÄ²»Í¬Êdz¬Ê±ÊÂÎñ½«Îª³¬Ê±ÇëÇó·µ»Ø×´Ì¬ CAM_CMD_TIMEOUT¡£ÓÚÊÇXPT_ABORTµÄcaseÓï¾ä¾Í»áºÜС£¬ÏñÏÂÃæÕâÑù£º
case XPT_ABORT: struct ccb *abort_ccb; abort_ccb = ccb->cab.abort_ccb; if(abort_ccb->ccb_h.func_code != XPT_SCSI_IO) { ccb->ccb_h.status = CAM_UA_ABORT; xpt_done(ccb); return; } if(xxx_abort_ccb(abort_ccb, CAM_REQ_ABORTED) < 0) /* no such CCB in our queue */ ccb->ccb_h.status = CAM_PATH_INVALID; else ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return;
XPT_SET_TRAN_SETTINGS - ÏÔʽÉèÖÃSCSI´«ÊäÉèÖõÄÖµ
ÔÚÁªºÏccbµÄʵÀý¡°struct ccb_trans_setting cts¡± Öд«ÊäµÄ²ÎÁ¿£º
valid - λÑÚÂ룬ÏÔʾӦµ±¸üÐÂÄÇЩÉèÖãº
CCB_TRANS_SYNC_RATE_VALID - ͬ²½´«ÊäËÙÂÊ
CCB_TRANS_SYNC_OFFSET_VALID - ͬ²½Î»ÒÆ
CCB_TRANS_BUS_WIDTH_VALID - ×ÜÏß¿í¶È
CCB_TRANS_DISC_VALID - ÉèÖÃÆôÓÃ/½ûÓöϿªÁ¬½Ó
CCB_TRANS_TQ_VALID - ÉèÖÃÆôÓÃ/½ûÓôø±êÇ©µÄÅŶÓ
flags - ÓÉÁ½²¿·Ö×é³É£¬Á½Ôª²ÎÁ¿ºÍ×Ó²Ù×÷±êʶ¡£Á½Ôª²ÎÁ¿Îª£º
CCB_TRANS_DISC_ENB - ÆôÓöϿªÁ¬½Ó
CCB_TRANS_TAG_ENB - ÆôÓôø±êÇ©µÄÅŶÓ
×Ó²Ù×÷Ϊ£º
CCB_TRANS_CURRENT_SETTINGS - ¸Ä±äµ±Ç°µÄÐÉÌ
CCB_TRANS_USER_SETTINGS - ¼ÇסϣÍûµÄÓû§Öµ
sync_period, sync_offset - ×Ô½âÊ͵ģ¬Èç¹ûsync_offset==0ÔòÇëÇóͬ²½Ä£Ê½
bus_width - ×ÜÏß´ø¿í£¬ÒÔλ¼Æ£¨¶ø²»ÊÇ×Ö½Ú£©
Òë×¢: ²Î¿¼ÔÎĺÍÔ´Âë
Ö§³ÖÁ½×éÐÉ̲ÎÊý£¬Óû§ÉèÖú͵±Ç°ÉèÖá£Óû§ÉèÖÃÔÚSIMÇý¶¯³ÌÐòÖРʵ¼ÊÉÏÓõò»¶à£¬Õâͨ³£Ö»ÊÇһƬÄڴ棬¹©ÉÏ²ã´æ´¢£¨²¢ÔÚÒÔºó»Ö¸´£©Æä¹ØÓÚ ²ÎÊýµÄһЩÖ÷ÕÅ¡£ÉèÖÃÓû§²ÎÊý²¢²»»áµ¼ÖÂÖØÐÂÐÉÌ´«ÊäËÙÂÊ¡£µ«µ±SCSI ¿ØÖÆÆ÷ÐÉÌʱ£¬Ëü±ØÐëÓÀÔ¶²»ÄÜÉèÖøßÓÚÓû§²ÎÊýµÄÖµ£¬Òò´ËËüʵÖÊÉÏÊÇ ÉÏÏÞ¡£
µ±Ç°ÉèÖã¬ÕýÈçÆäÃû×ÖËùʾ£¬Ö¸µ±Ç°µÄ¡£¸Ä±äËüÃÇÒâζ×ÅÏÂÒ»´Î´«Êäʱ ±ØÐëÖØÐÂÐÉ̲ÎÊý¡£ÓÖÒ»´Î£¬ÕâЩ¡°new current settings¡± ²¢Ã»Óб»¼Ù¶¨ÎªÇ¿ÖÆÓÃÓÚÉ豸ÉÏ£¬ËüÃÇÖ»ÊÇÓÃ×÷ÐÉÌµÄÆðʼ²½Öè¡£´ËÍ⣬ ËüÃDZØÐëÊÜSCSI¿ØÖÆÆ÷µÄʵ¼ÊÄÜÁ¦ÏÞÖÆ£ºÀýÈ磬Èç¹ûSCSI¿ØÖÆÆ÷ÓÐ8λ×ÜÏߣ¬ ¶øÇëÇóÒªÇóÉèÖÃ16λ´«Ê䣬ÔòÔÚ·¢Ë͸øÉ豸ǰ²ÎÊý±ØÐë±»ÇÄÇĵؽØÈ¡Îª8λ¡£
Ò»¸öÐèҪעÒâµÄÎÊÌâ¾ÍÊÇ×ÜÏß¿í¶ÈºÍͬ²½Á½¸ö²ÎÊýÊÇÕë¶ÔÿĿ±êµÄ¶øÑԵģ¬ ¶ø¶Ï¿ªÁ¬½ÓºÍÆôÓñêÇ©Á½¸ö²ÎÊýÊÇÕë¶Ôÿlun¶øÑԵġ£
½¨ÒéµÄʵÏÖÊDZ£³Ö3×éÐÉ̲ÎÊý£¨×ÜÏß¿í¶ÈºÍͬ²½´«Ê䣩£º
user - Óû§µÄÒ»×飬ÈçÉÏ
current - ʵ¼ÊÉúЧµÄÄÇЩ
goal - ͨ¹ýÉèÖá°current¡±²ÎÊýËùÇëÇóµÄÄÇЩ
´úÂë¿´ÆðÀ´Ïñ£º
struct ccb_trans_settings *cts; int targ, lun; int flags; cts = &ccb->cts; targ = ccb_h->target_id; lun = ccb_h->target_lun; flags = cts->flags; if(flags & CCB_TRANS_USER_SETTINGS) { if(flags & CCB_TRANS_SYNC_RATE_VALID) softc->user_sync_period[targ] = cts->sync_period; if(flags & CCB_TRANS_SYNC_OFFSET_VALID) softc->user_sync_offset[targ] = cts->sync_offset; if(flags & CCB_TRANS_BUS_WIDTH_VALID) softc->user_bus_width[targ] = cts->bus_width; if(flags & CCB_TRANS_DISC_VALID) { softc->user_tflags[targ][lun] &= ~CCB_TRANS_DISC_ENB; softc->user_tflags[targ][lun] |= flags & CCB_TRANS_DISC_ENB; } if(flags & CCB_TRANS_TQ_VALID) { softc->user_tflags[targ][lun] &= ~CCB_TRANS_TQ_ENB; softc->user_tflags[targ][lun] |= flags & CCB_TRANS_TQ_ENB; } } if(flags & CCB_TRANS_CURRENT_SETTINGS) { if(flags & CCB_TRANS_SYNC_RATE_VALID) softc->goal_sync_period[targ] = max(cts->sync_period, OUR_MIN_SUPPORTED_PERIOD); if(flags & CCB_TRANS_SYNC_OFFSET_VALID) softc->goal_sync_offset[targ] = min(cts->sync_offset, OUR_MAX_SUPPORTED_OFFSET); if(flags & CCB_TRANS_BUS_WIDTH_VALID) softc->goal_bus_width[targ] = min(cts->bus_width, OUR_BUS_WIDTH); if(flags & CCB_TRANS_DISC_VALID) { softc->current_tflags[targ][lun] &= ~CCB_TRANS_DISC_ENB; softc->current_tflags[targ][lun] |= flags & CCB_TRANS_DISC_ENB; } if(flags & CCB_TRANS_TQ_VALID) { softc->current_tflags[targ][lun] &= ~CCB_TRANS_TQ_ENB; softc->current_tflags[targ][lun] |= flags & CCB_TRANS_TQ_ENB; } } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return;
´Ëºóµ±ÏÂÒ»´ÎÒª´¦ÀíI/OÇëÇóʱ£¬Ëü»á¼ì²éÆäÊÇ·ñÐèÒªÖØÐÂÐÉÌ£¬ ÀýÈçͨ¹ýµ÷Óú¯Êýtarget_negotiated(hcb)¡£Ëü¿ÉÒÔÈçÏÂʵÏÖ£º
int target_negotiated(struct xxx_hcb *hcb) { struct softc *softc = hcb->softc; int targ = hcb->targ; if( softc->current_sync_period[targ] != softc->goal_sync_period[targ] || softc->current_sync_offset[targ] != softc->goal_sync_offset[targ] || softc->current_bus_width[targ] != softc->goal_bus_width[targ] ) return 0; /* FALSE */ else return 1; /* TRUE */ }
ÖØÐÂÐÉÌÕâЩֵºó£¬½á¹ûÖµ±ØÐëͬʱ¸³¸øµ±Ç°ºÍÄ¿µÄ(goal)²ÎÊý£¬
ÕâÑù¶ÔÓÚÒÔºóµÄI/OÊÂÎñµ±Ç°ºÍÄ¿µÄ²ÎÊý½«Ïàͬ£¬ÇÒ target_negotiated()
»á·µ»ØTRUE¡£µ±³õʼ»¯¿¨ £¨ÔÚxxx_attach()
ÖУ©µ±Ç°ÐÉÌÖµ±ØÐë±»³õʼ»¯Îª
×îÕͬ²½Ä£Ê½£¬Ä¿µÄºÍµ±Ç°Öµ±ØÐë±»³õʼ»¯Îª¿ØÖÆÆ÷ËùÖ§³ÖµÄ×î´óÖµ¡£
£¨Òë×¢£ºÔÎÄ¿ÉÄÜÓÐÎ󣬴˴¦Î´¸Ä£©
XPT_GET_TRAN_SETTINGS - »ñµÃSCSI´«ÊäÉèÖõÄÖµ
´Ë²Ù×÷ΪXPT_SET_TRAN_SETTINGSµÄÄæ²Ù×÷¡£ÓÃͨ¹ýÆì±ê CCB_TRANS_CURRENT_SETTINGS»òCCB_TRANS_USER_SETTINGS£¨Èç¹ûͬʱÉèÖÃÔò ÏÖÓÐÇý¶¯³ÌÐò·µ»Øµ±Ç°ÉèÖã©ËùÇëÇó¶øµÃµÄÊý¾ÝÌî³äCCBʵÀý ¡°struct ccb_trans_setting cts¡±.
XPT_CALC_GEOMETRY - ¼ÆËã´ÅÅ̵ÄÂß¼£¨BIOS£©½á¹¹(geometry)
²ÎÁ¿ÔÚÁªºÏccbµÄʵÀý¡°struct ccb_calc_geometry ccg¡± Öд«Ê䣺
block_size - ÊäÈ룬ÒÔ×ֽڼƵĿé´óС£¨Ò²³ÆÎªÉÈÇø£©
volume_size - ÊäÈ룬ÒÔ×ֽڼƵľí´óС
cylinders - Êä³ö£¬Âß¼ÖùÃæ
heads - Êä³ö£¬Âß¼´ÅÍ·
secs_per_track - Êä³ö£¬Ã¿´ÅµÀµÄÂß¼ÉÈÇø
Èç¹û·µ»ØµÄ½á¹¹ÓëSCSI¿ØÖÆÆ÷BIOSËùÏëÏóµÄ²î±ðºÜ´ó£¬²¢ÇÒSCSI ¿ØÖÆÆ÷ÉϵĴÅÅ̱»×÷Ϊ¿ÉÒýµ¼µÄ£¬Ôòϵͳ¿ÉÄÜÎÞ·¨Æô¶¯¡£´Óaic7xxx Çý¶¯³ÌÐòÖÐժȡµÄµäÐͼÆËãʾÀý£º
struct ccb_calc_geometry *ccg; u_int32_t size_mb; u_int32_t secs_per_cylinder; int extended; ccg = &ccb->ccg; size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size); extended = check_cards_EEPROM_for_extended_geometry(softc); if (size_mb > 1024 && extended) { ccg->heads = 255; ccg->secs_per_track = 63; } else { ccg->heads = 64; ccg->secs_per_track = 32; } secs_per_cylinder = ccg->heads * ccg->secs_per_track; ccg->cylinders = ccg->volume_size / secs_per_cylinder; ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return;
Õâ¸ø³öÁËÒ»°ã˼·£¬¾«È·¼ÆËãÒÀÀµÓÚÌØ¶¨BIOSµÄñ±ºÃ(quirk)¡£Èç¹û BIOSûÓÐÌṩ·½·¨ÉèÖÃEEPROMÖеġ°extended translation¡± Æì±ê£¬Ôò´ËÆì±êͨ³£Ó¦µ±¼Ù¶¨µÈÓÚ1¡£ÆäËûÁ÷ÐнṹÓУº
128 heads, 63 sectors - Symbios¿ØÖÆÆ÷ 16 heads, 63 sectors - ÀÏʽ¿ØÖÆÆ÷
һЩϵͳBIOSºÍSCSI BIOS»áÏ໥¾ºÕù£¬Ê¤¸º²»¶¨£¬ÀýÈçSymbios 875/895 SCSIºÍPhoenix BIOSµÄ½áºÏÔÚϵͳ¼Óµçʱ»á¸ø³ö½á¹¹128/63£¬ ¶øµ±ÀäÆô¶¯»òÈíÆô¶¯ºó»áÊÇ255/63¡£
XPT_PATH_INQ - ·¾¶ÎÊѯ£¬ »»¾ä»°Ëµ£¬»ñµÃSIMÇý¶¯³ÌÐòºÍSCSI¿ØÖÆÆ÷£¨Ò²³ÆÎªHBA - Ö÷»ú×ÜÏßÊÊÅäÆ÷£© µÄÌØÐÔ¡£
ÌØÐÔÔÚÁªºÏccbµÄʵÀý¡°struct ccb_pathinq cpi¡± Öзµ»Ø£º
version_num - SIMÇý¶¯³ÌÐòºÅ£¬µ±Ç°ËùÓÐÇý¶¯³ÌÐòʹÓÃ1
hba_inquiry - ¿ØÖÆÆ÷ËùÖ§³ÖÌØÐÔµÄλÑÚÂ룺
PI_MDP_ABLE - Ö§³ÖMDPÏûÏ¢£¨À´×ÔSCSI3µÄһЩ¶«Î÷?£©
PI_WIDE_32 - Ö§³Ö32λ¿íSCSI
PI_WIDE_16 - Ö§³Ö16λ¿íSCSI
PI_SDTR_ABLE - ¿ÉÒÔÐÉÌͬ²½´«ÊäËÙÂÊ
PI_LINKED_CDB - Ö§³ÖÁ´½ÓµÄÃüÁî
PI_TAG_ABLE - Ö§³Ö´ø±êÇ©µÄÃüÁî
PI_SOFT_RST - Ö§³ÖÈí¸´Î»Ñ¡Ôñ £¨Ó²¸´Î»ºÍÈí¸´Î»ÔÚSCSI×ÜÏßÖÐÊÇ»¥³âµÄ£©
target_sprt - Ä¿±êģʽ֧³ÖµÄÆì±ê£¬Èç¹û²»Ö§³ÖÔòΪ0
hba_misc - ¿ØÖÆÆ÷ÌØÐÔÔÓÏ
PIM_SCANHILO - ´Ó¸ßIDµ½µÍIDµÄ×ÜÏßɨÃè
PIM_NOREMOVE - ¿ÉÒÆ³ýÉ豸²»°üÀ¨ÔÚɨÃèÖ®ÁÐ
PIM_NOINITIATOR - ²»Ö§³Ö·¢ÆðÕß½ÇÉ«
PIM_NOBUSRESET - Óû§½ûÓóõʼBUS RESET
hba_eng_cnt - ÉñÃØµÄHBAÒýÇæ¼ÆÊý£¬ÓëѹËõÓйصÄһЩ ¶«Î÷£¬µ±Ç°×ÜÊÇÖÃΪ0
vuhba_flags - ¹©Ó¦ÉÌΨһµÄÆì±ê£¬µ±Ç°Î´ÓÃ
max_target - ×î´óÖ§³ÖµÄÄ¿±êID£¨¶Ô8λ×ÜÏßΪ7£¬ 16λ×ÜÏßΪ15£¬¹âÏËͨµÀΪ127£©
max_lun - ×î´óÖ§³ÖµÄLUN ID£¨¶Ô½ÏÀϵÄSCSI¿ØÖÆÆ÷ Ϊ7£¬½ÏеÄΪ63£©
async_flags - °²×°µÄÒì²½´¦Àíº¯ÊýµÄλÑÚÂ룬µ±Ç°Î´ÓÃ
hpath_id - ×ÓϵͳÖÐ×î¸ßµÄ·¾¶ID£¬µ±Ç°Î´ÓÃ
unit_number - ¿ØÖÆÆ÷µ¥ÔªºÅ£¬cam_sim_unit(sim)
bus_id - ×ÜÏߺţ¬cam_sim_bus(sim)
initiator_id - ¿ØÖÆÆ÷×Ô¼ºµÄSCSI ID
base_transfer_speed - Òì²½Õ´«ÊäµÄÃûÒå´«ÊäËÙÂÊ£¬ ÒÔKB/s¼Æ£¬¶ÔÓÚSCSIµÈÓÚ3300
sim_vid - SIMÇý¶¯³ÌÐòµÄ¹©Ó¦ÉÌID£¬ÒÔ0½áÊøµÄ×Ö·û´®£¬ °üº¬½áβ0ÔÚÄÚµÄ×î´ó³¤¶ÈΪSIM_IDLEN
hba_vid - SCSI¿ØÖÆÆ÷µÄ¹©Ó¦ÉÌID£¬ÒÔ0½áÊøµÄ×Ö·û´®£¬ °üº¬½áβ0ÔÚÄÚµÄ×î´ó³¤¶ÈΪHBA_IDLEN
dev_name - É豸Çý¶¯³ÌÐòÃû×Ö£¬ÒÔ0½áβµÄ×Ö·û´®£¬ °üº¬½áβ0ÔÚÄÚµÄ×î´ó³¤¶ÈΪDEV_IDLEN£¬µÈÓÚcam_sim_name(sim)
ÉèÖÃ×Ö·û´®×ֶεĽ¨Òé·½·¨ÊÇʹÓÃstrncpy£¬È磺
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
ÉèÖÃÕâЩֵºó½«×´Ì¬ÉèÖÃΪCAM_REQ_CMP£¬²¢½«CCB±ê¼ÇΪÍê³É¡£
¡¡¡¡ÂÖѯº¯ÊýÓÃÓÚµ±ÖжÏ×Óϵͳ²»Æð×÷ÓÃʱ£¨ÀýÈ磬ϵͳ±ÀÀ£»òÕýÔÚ´´½¨
ϵͳת´¢£©Ä£ÄâÖжϡ£CAM×ÓϵͳÔÚµ÷ÓÃÂÖѯº¯ÊýǰÉèÖÃÊʵ±µÄÖжϼ¶±ð¡£
Òò´ËËüËùÐè×öÈ«²¿µÄÖ»Êǵ÷ÓÃÖжÏÀý³Ì£¨»òÆäËû·½·¨£¬ÂÖѯÀý³ÌÀ´ ½øÐÐʵ¼Ê¶¯×÷,
¶øÖжÏÀý³ÌÖ»Êǵ÷ÓÃÂÖѯÀý³Ì£©¡£ÄÇôΪʲôҪÕÒÂé·³
Ū³öÒ»¸öµ¥¶ÀµÄº¯ÊýÀ´ÄØ£¿ÕâÊÇÓÉÓÚ²»Í¬µÄµ÷ÓÃÔ¼¶¨¡£ xxx_poll
Àý³ÌÈ¡½á¹¹cam_simµÄÖ¸Õë×÷Ϊ²ÎÁ¿£¬
¶øPCIÖжÏÀý³Ì°´ÕÕÆÕͨԼ¶¨È¡µÄÊÇÖ¸Ïò½á¹¹ xxx_softc
µÄÖ¸Õ룬ISAÖжÏÀý³ÌÖ»ÊÇÈ¡É豸ºÅ£¬
Òò´ËÂÖѯÀý³ÌÒ»°ã¿´ÆðÀ´Ïñ£º
static void xxx_poll(struct cam_sim *sim) { xxx_intr((struct xxx_softc *)cam_sim_softc(sim)); /* for PCI device */ }
¡¡¡¡or
static void xxx_poll(struct cam_sim *sim) { xxx_intr(cam_sim_unit(sim)); /* for ISA device */ }
¡¡¡¡Èç¹û½¨Á¢ÁËÒ첽ʼþ»Øµ÷£¬ÔòÓ¦µ±¶¨Ò廨µ÷º¯Êý¡£
static void ahc_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
callback_arg - ×¢²á»Øµ÷ʱÌṩµÄÖµ
code - ±êʶʼþÀàÐÍ
path - ±êʶʼþ×÷ÓÃÓÚÆäÉϵÄÉ豸
arg - ʼþÌØ¶¨µÄ²ÎÁ¿
¡¡¡¡µ¥Ò»ÀàÐÍʼþµÄʵÏÖ£¬AC_LOST_DEVICE£¬¿´ÆðÀ´ÈçÏ£º
struct xxx_softc *softc; struct cam_sim *sim; int targ; struct ccb_trans_settings neg; sim = (struct cam_sim *)callback_arg; softc = (struct xxx_softc *)cam_sim_softc(sim); switch (code) { case AC_LOST_DEVICE: targ = xpt_path_target_id(path); if(targ <= OUR_MAX_SUPPORTED_TARGET) { clean_negotiations(softc, targ); /* send indication to CAM */ neg.bus_width = 8; neg.sync_period = neg.sync_offset = 0; neg.valid = (CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID); xpt_async(AC_TRANSFER_NEG, path, &neg); } break; default: break; }
¡¡¡¡ÖжÏÀý³ÌµÄÈ·ÇÐÀàÐÍÒÀÀµÓÚSCSI¿ØÖÆÆ÷ËùÁ¬½Óµ½µÄÍâΧ×ÜÏßµÄÀàÐÍ£¨PCI£¬ ISAµÈµÈ£©¡£
¡¡¡¡SIMÇý¶¯³ÌÐòµÄÖжÏÀý³ÌÔËÐÐÔÚÖжϼ¶±ðsplcamÉÏ¡£Òò´ËÓ¦µ±ÔÚÇý¶¯ ³ÌÐòÖÐʹÓÃsplcam()
À´Í¬²½ÖжÏÀý³ÌÓëÇý¶¯³ÌÐò
Ê£Óಿ·ÖµÄ»î¶¯£¨¶ÔÓÚÄܲì¾õ¶à´¦ÀíÆ÷µÄÇý¶¯³ÌÐò£¬ÊÂÇé¸üÒªÓÐȤ£¬µ«
´Ë´¦ÎÒÃǺöÂÔÕâÖÖÇé¿ö£©¡£±¾ÎĵµÖеÄα´úÂë¼òµ¥µØºöÂÔÁËͬ²½ÎÊÌâ¡£
ʵ¼Ê´úÂëÒ»¶¨²»ÄܺöÂÔËüÃÇ¡£Ò»¸ö½Ï±¿µÄ°ì·¨¾ÍÊÇÔÚ½øÈëÆäËûÀý³ÌµÄ Èë¿Úµã´¦Éèsplcam()
£¬²¢ÔÚ·µ»ØÊ±½«Ëü¸´Î»£¬´Ó¶ø
ÓÃÒ»¸ö´óµÄÁÙ½çÇø±£»¤ËüÃÇ¡£ÎªÁËÈ·±£Öжϼ¶±ð×ÜÊǻᱻ»Ö¸´£¬¿ÉÒÔ¶¨Òå Ò»¸ö°ü×°º¯Êý£¬È磺
static void xxx_action(struct cam_sim *sim, union ccb *ccb) { int s; s = splcam(); xxx_action1(sim, ccb); splx(s); } static void xxx_action1(struct cam_sim *sim, union ccb *ccb) { ... process the request ... }
¡¡¡¡ÕâÖÖ·½·¨¼òµ¥¶øÇÒ½¡×³£¬µ«Ëü´æÔÚµÄÎÊÌâÊÇÖжϿÉÄܻᱻ×èÈûÏà¶Ô
ºÜ³¤µÄʼþ£¬Õâ»á¶ÔϵͳÐÔÄܲúÉú¸ºÃæÓ°Ïì¡£ÁíÒ»·½Ã棬 spl()
º¯Êý×åÓÐÏ൱¸ßµÄ¶îÍ⿪Ïú£¬Òò´Ë´óÁ¿ ºÜСµÄÁÙ½çÇø¿ÉÄÜÒ²²»ºÃ¡£
¡¡¡¡ÖжÏÀý³Ì´¦ÀíµÄÇé¿öºÍÆäÖÐϸ½ÚÑÏÖØÒÀÀµÓÚÓ²¼þ¡£ÎÒÃÇ¿¼ÂÇ ¡°µäÐÍ(typical)¡±Çé¿ö¡£
¡¡¡¡Ê×ÏÈ£¬ÎÒÃǼì²é×ÜÏßÉÏÊÇ·ñÓöµ½ÁËSCSI¸´Î»£¨¿ÉÄÜÓÉͬһSCSI×ÜÏßÉÏ µÄÁíÒ»SCSI¿ØÖÆÆ÷ÒýÆð£©¡£Èç¹ûÕâÑùÎÒÃǶªÆúËùÓÐÈë¶ÓµÄºÍ¶Ï¿ªÁ¬½ÓµÄ ÇëÇ󣬱¨¸æÊ¼þ²¢ÖØÐ³õʼ»¯ÎÒÃǵÄSCSI¿ØÖÆÆ÷¡£³õʼ»¯ÆÚ¼ä¿ØÖÆÆ÷ ²»»á·¢³öÁíÒ»¸ö¸´Î»£¬Õâ¶ÔÎÒÃÇÊ®·ÖÖØÒª£¬·ñÔòͬһSCSI×ÜÏßÉϵÄÁ½¸ö¿ØÖÆÆ÷ ¿ÉÄÜ»áÒ»Ö±À´»ØµØ¸´Î»ÏÂÈ¥¡£¿ØÖÆÆ÷ÖÂÃü´íÎó/¹ÒÆðµÄÇé¿ö¿ÉÒÔÔÚͬһ µØ·½½øÐд¦Àí£¬µ«Õâ¿ÉÄÜÐèÒª·¢ËÍRESETÐźŵ½SCSI×ÜÏßÀ´¸´Î»ÓëSCSI É豸µÄÁ¬½Ó״̬¡£
int fatal=0; struct ccb_trans_settings neg; struct cam_path *path; if( detected_scsi_reset(softc) || (fatal = detected_fatal_controller_error(softc)) ) { int targ, lun; struct xxx_hcb *h, *hh; /* ¶ªÆúËùÓÐÈë¶ÓµÄCCB */ for(h = softc->first_queued_hcb; h != NULL; h = hh) { hh = h->next; free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET); } /* Òª±¨¸æµÄÐÉ̵ĸɾ»Öµ */ neg.bus_width = 8; neg.sync_period = neg.sync_offset = 0; neg.valid = (CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID); /* ¶ªÆúËùÓжϿªÁ¬½ÓµÄCCBºÍ¸É¾»ÐÉÌ */ for(targ=0; targ <= OUR_MAX_SUPPORTED_TARGET; targ++) { clean_negotiations(softc, targ); /* report the event if possible */ if(xpt_create_path(&path, /*periph*/NULL, cam_sim_path(sim), targ, CAM_LUN_WILDCARD) == CAM_REQ_CMP) { xpt_async(AC_TRANSFER_NEG, path, &neg); xpt_free_path(path); } for(lun=0; lun <= OUR_MAX_SUPPORTED_LUN; lun++) for(h = softc->first_discon_hcb[targ][lun]; h != NULL; h = hh) { hh=h->next; if(fatal) free_hcb_and_ccb_done(h, h->ccb, CAM_UNREC_HBA_ERROR); else free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET); } } /* ±¨¸æÊ¼þ */ xpt_async(AC_BUS_RESET, softc->wpath, NULL); /* ÖØÐ³õʼ»¯¿ÉÄÜ»¨ºÜ¶àʱ¼ä£¬ÕâÖÖÇé¿öÏÂÓ¦µ±ÓÉÁíÒ»ÖжϷ¢ÐźŠ* ָʾ³õʼ»¯·ñÍê³É£¬»òÔÚ³¬Ê±Ê±¼ì²é - µ«ÎªÁ˼òµ¥ÎÒÃǼÙÉè * ³õʼ»¯ÕæµÄºÜ¿ì */ if(!fatal) { reinitialize_controller_without_scsi_reset(softc); } else { reinitialize_controller_with_scsi_reset(softc); } schedule_next_hcb(softc); return; }
¡¡¡¡Èç¹ûÖжϲ»ÊÇÓÉ¿ØÖÆÆ÷·¶Î§µÄÌõ¼þÒýÆðµÄ£¬ÔòºÜ¿ÉÄܵ±Ç°Ó²¼þ¿ØÖÆ¿é ³öÏÖÁËÎÊÌâ¡£ÒÀÀµÓÚÓ²¼þ£¬¿ÉÄÜÓзÇHCBÏà¹ØµÄʼþ£¬´Ë´¦ÎÒÃÇָʾ²»¿¼ÂÇ ËüÃÇ¡£È»ºóÎÒÃÇ·ÖÎöÕâ¸öHCB·¢ÉúÁËʲô£º
struct xxx_hcb *hcb, *h, *hh; int hcb_status, scsi_status; int ccb_status; int targ; int lun_to_freeze; hcb = get_current_hcb(softc); if(hcb == NULL) { /* »òÕß¶ªÊ§(stray)µÄÖжϣ¬»òÕßijЩ¶«Î÷ÑÏÖØ´íÎó£¬ * »òÕßÕâÊÇÓ²¼þÏà¹ØµÄijЩ¶«Î÷ */ ½øÐбØÒªµÄ´¦Àí; return; } targ = hcb->target; hcb_status = get_status_of_current_hcb(softc);
¡¡¡¡Ê×ÏÈÎÒÃǼì²éHCBÊÇ·ñÍê³É£¬Èç¹ûÍê³ÉÎÒÃǾͼì²é·µ»ØµÄSCSI״̬¡£
if(hcb_status == COMPLETED) { scsi_status = get_completion_status(hcb);
¡¡¡¡È»ºó¿´Õâ¸ö״̬ÊÇ·ñÓëREQUEST SENSEÃüÁîÓйأ¬Èç¹ûÓйØÔò¼òµ¥ µØ´¦ÀíÒ»ÏÂËü¡£
if(hcb->flags & DOING_AUTOSENSE) { if(scsi_status == GOOD) { /* autosense³É¹¦ */ hcb->ccb->ccb_h.status |= CAM_AUTOSNS_VALID; free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_SCSI_STATUS_ERROR); } else { autosense_failed: free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_AUTOSENSE_FAIL); } schedule_next_hcb(softc); return; }
¡¡¡¡·ñÔòÃüÁî×ÔÉíÒѾÍê³É£¬°Ñ¸ü¶à×¢ÒâÁ¦·ÅÔÚϸ½ÚÉÏ¡£Èç¹ûÕâ¸öCCB ûÓнûÓÃauto-sense²¢ÇÒÃüÁîÁ¬Í¬senseÊý¾Ýʧ°Ü£¬ÔòÔËÐÐREQUEST SENSE ÃüÁî½ÓÊÕÄÇЩÊý¾Ý¡£
hcb->ccb->csio.scsi_status = scsi_status; calculate_residue(hcb); if( (hcb->ccb->ccb_h.flags & CAM_DIS_AUTOSENSE)==0 && ( scsi_status == CHECK_CONDITION || scsi_status == COMMAND_TERMINATED) ) { /* Æô¶¯auto-SENSE */ hcb->flags |= DOING_AUTOSENSE; setup_autosense_command_in_hcb(hcb); restart_current_hcb(softc); return; } if(scsi_status == GOOD) free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_REQ_CMP); else free_hcb_and_ccb_done(hcb, hcb->ccb, CAM_SCSI_STATUS_ERROR); schedule_next_hcb(softc); return; }
¡¡¡¡ÊôÓÚÐÉÌʼþµÄÒ»¸öµäÐÍÊÂÇ飺´ÓSCSIÄ¿±ê£¨»Ø´ðÎÒÃǵÄÐÉÌÆóͼ»ò ÓÉÄ¿±ê·¢ÆðµÄ£©½ÓÊÕµ½µÄÐÉÌÏûÏ¢£¬»òÄ¿±êÎÞ·¨ÐÉÌ£¨¾Ü¾øÎÒÃǵÄÐÉÌÏûÏ¢ »ò²»»Ø´ðËüÃÇ£©¡£
switch(hcb_status) { case TARGET_REJECTED_WIDE_NEG: /* »Ö¸´µ½8-bit×ÜÏß */ softc->current_bus_width[targ] = softc->goal_bus_width[targ] = 8; /* ±¨¸æÊ¼þ */ neg.bus_width = 8; neg.valid = CCB_TRANS_BUS_WIDTH_VALID; xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &neg); continue_current_hcb(softc); return; case TARGET_ANSWERED_WIDE_NEG: { int wd; wd = get_target_bus_width_request(softc); if(wd <= softc->goal_bus_width[targ]) { /* ¿É½ÓÊܵĻشð */ softc->current_bus_width[targ] = softc->goal_bus_width[targ] = neg.bus_width = wd; /* ±¨¸æÊ¼þ */ neg.valid = CCB_TRANS_BUS_WIDTH_VALID; xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &neg); } else { prepare_reject_message(hcb); } } continue_current_hcb(softc); return; case TARGET_REQUESTED_WIDE_NEG: { int wd; wd = get_target_bus_width_request(softc); wd = min (wd, OUR_BUS_WIDTH); wd = min (wd, softc->user_bus_width[targ]); if(wd != softc->current_bus_width[targ]) { /* ×ÜÏß¿í¶È¸Ä±äÁË */ softc->current_bus_width[targ] = softc->goal_bus_width[targ] = neg.bus_width = wd; /* ±¨¸æÊ¼þ */ neg.valid = CCB_TRANS_BUS_WIDTH_VALID; xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &neg); } prepare_width_nego_rsponse(hcb, wd); } continue_current_hcb(softc); return; }
¡¡¡¡È»ºóÎÒÃÇÓÃÓëÇ°ÃæÏàͬµÄ±¿°ì·¨´¦Àíauto-senseÆÚ¼ä¿ÉÄܳöÏÖµÄÈκΠ´íÎó¡£·ñÔò£¬ÎÒÃÇÔÙÒ»´Î½øÈëϸ½Ú¡£
if(hcb->flags & DOING_AUTOSENSE) goto autosense_failed; switch(hcb_status) {
¡¡¡¡ÎÒÃÇ¿¼ÂǵÄÏÂһʼþÊÇδԤÆÚµÄÁ¬½Ó¶Ï¿ª£¬Õâ¸öʼþÔÚABORT»ò BUS DEVICE RESETÏûÏ¢Ö®ºó±»¿´×÷ÊÇÕý³£µÄ£¬ÆäËûÇé¿öÏÂÊÇ·ÇÕý³£µÄ¡£
case UNEXPECTED_DISCONNECT: if(requested_abort(hcb)) { /* ÖÐÖ¹Ó°ÏìÄ¿±êºÍLUNÉϵÄËùÓÐÃüÁÒò´Ë½«ÄǸöÄ¿±êºÍLUNÉ쵀 * ËùÓжϿªÁ¬½ÓµÄHCBÒ²±ê¼ÇΪÖÐÖ¹ */ for(h = softc->first_discon_hcb[hcb->target][hcb->lun]; h != NULL; h = hh) { hh=h->next; free_hcb_and_ccb_done(h, h->ccb, CAM_REQ_ABORTED); } ccb_status = CAM_REQ_ABORTED; } else if(requested_bus_device_reset(hcb)) { int lun; /* ¸´Î»Ó°ÏìÄǸöÄ¿±êÉϵÄËùÓÐÃüÁÒò´Ë½«ÄǸöÄ¿±êºÍLUNÉ쵀 * ËùÓжϿªÁ¬½ÓµÄHCB±ê¼ÇΪ¸´Î» */ for(lun=0; lun <= OUR_MAX_SUPPORTED_LUN; lun++) for(h = softc->first_discon_hcb[hcb->target][lun]; h != NULL; h = hh) { hh=h->next; free_hcb_and_ccb_done(h, h->ccb, CAM_SCSI_BUS_RESET); } /* ·¢ËÍʼþ */ xpt_async(AC_SENT_BDR, hcb->ccb->ccb_h.path_id, NULL); /* ÕâÊÇCAM_RESET_DEVÇëÇó±¾Éí£¬ËüÍê³ÉÁË */ ccb_status = CAM_REQ_CMP; } else { calculate_residue(hcb); ccb_status = CAM_UNEXP_BUSFREE; /* request the further code to freeze the queue */ hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN; lun_to_freeze = hcb->lun; } break;
¡¡¡¡Èç¹ûÄ¿±ê¾Ü¾ø½ÓÊܱêÇ©£¬ÎÒÃǾÍ֪ͨCAM£¬²¢·µ»Ø´ËLUNµÄËùÓÐÃüÁ
case TAGS_REJECTED: /* ±¨¸æÊ¼þ */ neg.flags = 0 & ~CCB_TRANS_TAG_ENB; neg.valid = CCB_TRANS_TQ_VALID; xpt_async(AC_TRANSFER_NEG, hcb->ccb.ccb_h.path_id, &neg); ccb_status = CAM_MSG_REJECT_REC; /* ÇëÇóºóÃæµÄ´úÂë¶³½á¶ÓÁÐ */ hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN; lun_to_freeze = hcb->lun; break;
¡¡¡¡È»ºóÎÒÃǼì²éһЩÆäËûÇé¿ö£¬´¦Àí(processing)»ù±¾ÉϽöÏÞÓÚÉèÖÃCCB״̬£º
case SELECTION_TIMEOUT: ccb_status = CAM_SEL_TIMEOUT; /* request the further code to freeze the queue */ hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN; lun_to_freeze = CAM_LUN_WILDCARD; break; case PARITY_ERROR: ccb_status = CAM_UNCOR_PARITY; break; case DATA_OVERRUN: case ODD_WIDE_TRANSFER: ccb_status = CAM_DATA_RUN_ERR; break; default: /*ÒÔͨÓ÷½·¨´¦ÀíËùÓÐÆäËû´íÎó */ ccb_status = CAM_REQ_CMP_ERR; /* ÇëÇóºóÃæµÄ´úÂë¶³½á¶ÓÁÐ */ hcb->ccb->ccb_h.status |= CAM_DEV_QFRZN; lun_to_freeze = CAM_LUN_WILDCARD; break; }
¡¡¡¡È»ºóÎÒÃǼì²éÊÇ·ñ´íÎóÑÏÖØµ½ÐèÒª¶³½áÊäÈë¶ÓÁУ¬Ö±µ½ËüµÃµ½´¦Àí·½¿É ½â¶³£¬Èç¹ûÊÇÕâÑùÄÇô¾ÍÕâÑùÀ´´¦Àí£º
if(hcb->ccb->ccb_h.status & CAM_DEV_QFRZN) { /* ¶³½á¶ÓÁÐ */ xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); * /* ÖØÐÂÈë¶ÓÕâ¸öÄ¿±ê/LUNµÄËùÓÐÃüÁ½«ËüÃÇ·µ»ØCAM */ for(h = softc->first_queued_hcb; h != NULL; h = hh) { hh = h->next; if(targ == h->targ && (lun_to_freeze == CAM_LUN_WILDCARD || lun_to_freeze == h->lun) ) free_hcb_and_ccb_done(h, h->ccb, CAM_REQUEUE_REQ); } } free_hcb_and_ccb_done(hcb, hcb->ccb, ccb_status); schedule_next_hcb(softc); return;
¡¡¡¡Õâ°üÀ¨Í¨ÓÃÖжϴ¦Àí£¬¾¡¹ÜÌØ¶¨´¦ÀíÆ÷¿ÉÄÜÐèҪijЩ¸½¼Ó´¦Àí¡£
¡¡¡¡µ±Ö´ÐÐI/OÇëÇóʱºÜ¶àÊÂÇé¿ÉÄܳö´í¡£¿ÉÒÔÔÚCCB״̬Öзdz£Ï꾡µØ ±¨¸æ´íÎóÔÒò¡£Ê¹ÓõÄÀý×ÓÉ¢²¼ÓÚ±¾ÎĵµÖС£ÎªÁËÍêÕûÆð¼û´Ë´¦¸ø³ö ¶ÔµäÐÍ´íÎóÌõ¼þµÄ½¨ÒéÏìÓ¦µÄÒ»¸ö×ÜÀÀ£º
CAM_RESRC_UNAVAIL - ijЩ×ÊÔ´ ÔÝʱ²»¿ÉÓ㬲¢ÇÒµ±Æä±äΪ¿ÉÓÃʱSIMÇý¶¯³ÌÐò²»ÄܲúÉúʼþ¡£ÕâÖÖ×ÊÔ´ µÄÒ»¸öÀý×Ó¾ÍÊÇijЩ¿ØÖÆÆ÷ÄÚ²¿Ó²¼þ×ÊÔ´£¬µ±Æä¿ÉÓÃʱ¿ØÖÆÆ÷²»»áΪÆä ²úÉúÖжϡ£
CAM_UNCOR_PARITY - ·¢Éú²»¿É»Ö¸´µÄÆæÅ¼Ð£Ñé´íÎó
CAM_DATA_RUN_ERR - Êý¾ÝÍâÒç»òδԤÆÚµÄÊý¾Ý״̬(phase)£¨ÅÜÔÚÁíÒ»¸ö·½ÏòÉ϶ø²»ÊÇ CAM_DIR_MASKÖ¸¶¨µÄ·½Ïò£©£¬»ò¶ÔÓÚ¿í´«Êä³öÏÖÆæÊý´«Ê䳤¶È
CAM_SEL_TIMEOUT - ·¢ÉúÑ¡Ôñ³¬Ê±£¨Ä¿±ê²»ÏìÓ¦£©
CAM_CMD_TIMEOUT - ·¢ÉúÃüÁʱ£¨³¬Ê±º¯ÊýÔËÐУ©
CAM_SCSI_STATUS_ERROR - É豸·µ»ØµÄ´íÎó
CAM_AUTOSENSE_FAIL - É豸·µ»ØµÄ´íÎóÇÒREQUEST SENSEÃüÁîʧ°Ü
CAM_MSG_REJECT_REC - ÊÕµ½MESSAGE REJECTÏûÏ¢
CAM_SCSI_BUS_RESET - ÊÕµ½SCSI×ÜÏ߸´Î»
CAM_REQ_CMP_ERR - ³öÏÖ¡°²»¿ÉÄÜ(impossible)¡±SCSI״̬(phase) »òÕ߯äËû¹ÖÒìÊÂÇ飬»òÕßÈç¹û½øÒ»²½µÄÐÅÏ¢²»¿ÉÓÃÔòÖ»ÊÇͨÓôíÎó
CAM_UNEXP_BUSFREE - ³öÏÖδԤÆÚµÄ¶Ï¿ªÁ¬½Ó
CAM_BDR_SENT - BUS DEVICE RESETÏûÏ¢±»·¢Ë͵½Ä¿±ê
CAM_UNREC_HBA_ERROR - ²»¿É»Ö¸´µÄÖ÷»ú×ÜÏßÊÊÅäÆ÷´íÎó
CAM_REQ_TOO_BIG - ÇëÇó¶ÔÓÚ¿ØÖÆÆ÷Ì«´ó
CAM_REQUEUE_REQ - ´ËÇëÇóÓ¦µ±±»ÖØÐÂÈë¶ÓÒÔ±£³ÖÊÂÎñµÄ´ÎÐòÐÔ¡£ÕâµäÐ͵سöÏÖÔÚÏÂÁРʱ¿Ì£ºSIMʶ±ð³öÁËÓ¦µ±¶³½á¶ÓÁеĴíÎ󣬲¢ÇÒ±ØÐëÔÚsim¼¶±ðÉϽ«Ä¿±êµÄ ÆäËûÈë¶ÓÇëÇó·Å»Øµ½XPT¶ÓÁС£ÕâЩ´íÎóµÄµäÐÍÇé¿öÓÐÑ¡Ôñ³¬Ê±¡¢ÃüÁî ³¬Ê±ºÍÆäËûÀàËÆÇé¿ö¡£ÕâЩÇé¿öϳöÎÊÌâµÄÃüÁî·µ»Ø×´Ì¬À´Ö¸Ê¾´íÎó£¬ ´ËÃüÁîºÍÆäËû»¹Ã»Óб»·¢Ë͵½×ÜÏßµÄÃüÁî±»ÖØÐÂÈë¶Ó¡£
CAM_LUN_INVALID - SCSI¿ØÖÆÆ÷²»Ö§³ÖÇëÇóÖеÄLUN ID
CAM_TID_INVALID - SCSI¿ØÖÆÆ÷²»Ö§³ÖÇëÇóÖеÄÄ¿±êID
¡¡¡¡µ±HCBµÄ³¬Ê±ÆÚÂúʱ£¬ÇëÇó¾ÍÓ¦µ±±»ÖÐÖ¹£¬¾ÍÏñ´¦ÀíXPT_ABORTÇëÇó Ò»Ñù¡£Î¨Ò»Çø±ðÔÚÓÚ±»ÖÐÖ¹µÄÇëÇóµÄ·µ»Ø×´Ì¬Ó¦µ±ÎªCAM_CMD_TIMEOUT ¶ø²»ÊÇCAM_REQ_ABORTED£¨Õâ¾ÍÊÇΪʲôÖÐÖ¹µÄʵÏÖ×îºÃÓɺ¯ÊýÀ´Íê³É£©¡£ µ«»¹ÓÐÒ»¸ö¿ÉÄܵÄÎÊÌ⣺Èç¹ûÖÐÖ¹ÇëÇó×Ô¼º³öÁËÂé·³Ôõô°ì£¿ÕâÖÖÇé¿öÏ Ӧµ±¸´Î»SCSI×ÜÏߣ¬¾ÍÏñ´¦ÀíXPT_RESET_BUSÇëÇóÒ»Ñù£¨²¢ÇÒ½«ÆäʵÏÖΪ º¯Êý£¬´ÓÁ½¸öµØ·½µ÷ÓõÄÏë·¨Ò²ÊÊÓÃÓÚÕâ¶ù£©¡£¶øÇÒÈç¹ûÉ豸¸´Î»ÇëÇó³öÁË ÎÊÌ⣬ÎÒÃÇÓ¦µ±¸´Î»Õû¸öSCSI×ÜÏß¡£Òò´Ë×îÖÕ³¬Ê±º¯Êý¿´ÆðÀ´ÏñÏÂÃæÑù×Ó£º
static void xxx_timeout(void *arg) { struct xxx_hcb *hcb = (struct xxx_hcb *)arg; struct xxx_softc *softc; struct ccb_hdr *ccb_h; softc = hcb->softc; ccb_h = &hcb->ccb->ccb_h; if(hcb->flags & HCB_BEING_ABORTED || ccb_h->func_code == XPT_RESET_DEV) { xxx_reset_bus(softc); } else { xxx_abort_ccb(hcb->ccb, CAM_CMD_TIMEOUT); } }
¡¡¡¡µ±ÎÒÃÇÖÐÖ¹Ò»¸öÇëÇóʱ£¬Í¬Ò»Ä¿±ê/LUNµÄËùÓÐÆäËû¶Ï¿ªÁ¬½ÓµÄÇëÇó Ò²»á±»ÖÐÖ¹¡£Òò´Ë³öÏÖÁËÒ»¸öÎÊÌ⣬ÎÒÃÇÓ¦µ±·µ»ØËüÃǵÄ״̬ CAM_REQ_ABORTED»¹ÊÇCAM_CMD_TIMEOUT£¿µ±Ç°µÄÇý¶¯³ÌÐòʹÓà CAM_CMD_TIMEOUT¡£Õâ¿´ÆðÀ´·ûºÏÂß¼£¬ÒòΪÈç¹ûÒ»¸öÇëÇó³¬Ê±£¬Ôò¿ÉÄÜ É豸³öÏÖÁËijЩµÄÈ·ºÜÔãµÄÊÂÇ飬Òò´ËÈç¹ûËüÃÇûÓб»ÈÅÂÒÔòËüÃÇ×Ô¼º Ó¦µ±³¬Ê±¡£
¡¡¡¡Í¨Óô®ÐÐ×ÜÏß(USB)Êǽ«É豸Á¬½Óµ½¸öÈ˼ÆËã»úµÄÒ»ÖÖз½·¨¡£×ÜÏß ½á¹¹Í»³öÁËË«ÏòͨÐŵÄÌØÉ«£¬²¢ÇÒÆä¿ª·¢³ä·Ö¿¼Âǵ½ÁËÉ豸ÕýÖð½¥ÖÇÄÜ»¯ ºÍÐèÒªÓëhost½øÐиü¶à½»»¥µÄÏÖʵ¡£¶ÔUSBµÄÖ§³Ö°üº¬ÔÚµ±Ç°ËùÓÐоƬÖÐ, Òò´ËÔÚнüÖÆÔìµÄPCÖж¼¿ÉÓá£Æ»¹û(Apple)ÒýÈë½ö´øUSBµÄiMac¶ÔÓ²¼þ ÖÆÔìÉÌÉú²úËûÃÇUSB°æ±¾µÄÉ豸ÊÇÒ»¸öºÜ´óµÄ¼¤Àø¡£Î´À´µÄPC¹æ·¶Ö¸¶¨ PCÉϵÄËùÓÐÀÏÁ¬½ÓÆ÷Ó¦µ±ÓÉÒ»¸ö»ò¶à¸öUSBÁ¬½ÓÆ÷È¡´ú£¬ÌṩͨÓÃµÄ ¼´²å¼´ÓÃÄÜÁ¦¡£¶ÔUSBÓ²¼þµÄÖ§³ÖÔÚNetBSDµÄÏ൱ÔçÆÚ¾ÍÓÐÁË£¬ËüÊÇÓÉ Lennart AugustssonΪNetBSDÏîÄ¿¿ª·¢µÄ¡£´úÂëÒѾ±»ÒÆÖ²µ½FreeBSDÉÏ£¬ ÎÒÃÇĿǰά»¤×ÅÒ»¸öµ×²ã¹²Ïí´úÂë¡£¶ÔUSB×ÓϵͳµÄʵÏÖÀ´Ëµ£¬Ðí¶àUSBµÄ ÌØÐÔºÜÖØÒª¡£
¡¡¡¡Lennart AugustssonÒѾÍê³ÉÁËNetBSDÏîÄ¿ÖÐUSBÖ§³ÖµÄ ´ó²¿·ÖʵÏÖ¡£Ê®·Ö¸ÐлÕâÏ×÷Á¿¾ªÈ˵Ť×÷¡£Ò²Ê®·Ö¸ÐлArdyºÍDirk ¶Ô±¾ÎĸåµÄÆÀÂÛºÍУ¶Ô¡£
É豸ֱ½ÓÁ¬½Óµ½¼ÆËã»úÉϵĶ˿ڣ¬»òÕßÁ¬½Óµ½³ÆÎª ¼¯ÖÐÆ÷µÄÉ豸£¬ÐγÉÊ÷ÐÍÉ豸½á¹¹¡£
É豸¿ÉÔÚÔËÐÐʱÁ¬½Ó»ò¶Ï¿ª¡£
É豸¿ÉÒÔ¹ÒÆð×ÔÉí²¢´¥·¢hostϵͳµÄÖØÐÂͶÈëÔËÐС£
ÓÉÓÚÉ豸¿ÉÓÉ×ÜÏß¹©µç£¬Òò´ËhostÈí¼þ±ØÐë¸ú×Ùÿ¸ö ¼¯ÖÐÆ÷µÄµçÔ´Ô¤Ëã¡£
²»Í¬É豸ÀàÐÍÐèÒª²»Í¬µÄ·þÎñÖÊÁ¿£¬²¢ÇÒͬһ×ÜÏß ¿ÉÒÔÁ¬½Ó×î¶à126¸öÉ豸£¬Õâ¾ÍÐèҪǡµ±µØµ÷¶È×ÜÏßÉϵĴ«ÊäÒÔ³ä·Ö ÀûÓÃ12MbpsµÄ¿ÉÓôø¿í¡££¨USB 2.0³¬¹ý400Mbps£©
É豸ÖÇÄÜ»¯²¢°üº¬ºÜÈÝÒ×·ÃÎʵ½µÄ¹ØÓÚ×ÔÉíµÄÐÅÏ¢¡£
¡¡¡¡ÎªUSB×ÓϵͳÒÔ¼°Á¬½Óµ½ËüµÄÉ豸¿ª·¢Çý¶¯³ÌÐòÊÜÒÑ¿ª·¢»ò½«Òª¿ª·¢µÄ ¹æ·¶µÄÖ§³Ö¡£ÕâЩ¹æ·¶¿ÉÒÔ´ÓUSBÖ÷Ò³¹«¿ª»ñµÃ¡£Æ»¹û(Apple)ͨ¹ýʹµÃ ͨÓÃÀàÇý¶¯³ÌÐò¿É´ÓÆä²Ù×÷ϵͳMacOSÖлñµÃ£¬¶øÇÒ²»¹ÄÀøÎªÃ¿ÖÖÐÂÉ豸 ʹÓõ¥¶ÀµÄÇý¶¯³ÌÐòÀ´Ç¿ÁÒÍÆÐлùÓÚ±ê×¼µÄÇý¶¯³ÌÐò¡£±¾ÕÂÊÔͼÕûÀí»ù±¾ ÐÅÏ¢ÒÔ±ã¶ÔFreeBSD/NetBSDÖÐUSBÕ»µÄµ±Ç°ÊµÏÖÓиö»ù±¾µÄÁ˽⡣Ȼ¶ø£¬ ½¨Ò齫ÏÂÃæ²Î¿¼ÖÐÌá¼°µÄÏà¹Ø¹æ·¶Óë±¾ÕÂͬʱÔĶÁ¡£
¡¡¡¡FreeBSDÖеÄUSBÖ§³Ö¿É±»·ÖΪÈý²ã¡£×îµ×²ã°üº¬Ö÷¿ØÆ÷£¬ÏòÓ²¼þ ¼°Æäµ÷¶ÈÉèÊ©Ìṩһ¸öͨÓýӿڡ£ËüÖ§³ÖÓ²¼þ³õʼ»¯£¬¶Ô´«Êä½øÐе÷¶È£¬ ´¦ÀíÒÑÍê³É/ʧ°ÜµÄ´«Ê䡣ÿ¸öÖ÷¿ØÆ÷Çý¶¯³ÌÐòʵÏÖÒ»¸öÐéÄâhub£¬ ÒÔÓ²¼þÎ޹ط½Ê½Ìṩ¶Ô¿ØÖÆ»úÆ÷±³Ãæ¸ù¶Ë¿ÚµÄ¼Ä´æÆ÷µÄ·ÃÎÊ¡£
¡¡¡¡Öмä²ã´¦ÀíÉ豸Á¬½ÓºÍ¶Ï¿ª£¬É豸µÄ»ù±¾³õʼ»¯£¬Çý¶¯³ÌÐòµÄÑ¡Ôñ£¬ ͨÐÅͨµÀ£¨¹ÜµÀ£©ºÍ×ÊÔ´¹ÜÀí¡£Õâ¸ö·þÎñ²ãÒ²¿ØÖÆÄ¬ÈϹܵÀºÍÆäÉÏ´«ÊäµÄ É豸ÇëÇó¡£
¡¡¡¡¶¥²ã°üº¬Ö§³ÖÌØ¶¨£¨ÀࣩÉ豸µÄ¸÷¸öÇý¶¯³ÌÐò¡£ÕâЩÇý¶¯³ÌÐòʵÏÖ ³ýĬÈϹܵÀÍâµÄÆäËû¹ÜµÀÉÏʹÓõÄÐÒé¡£ËûÃÇҲʵÏÖ¶îÍ⹦ÄÜ£¬Ê¹µÃÉ豸 ¶ÔÄں˻òÓû§¿Õ¼äÊǿɼûµÄ¡£ËûÃÇʹÓ÷þÎñ²ã±©Â¶³öµÄUSBÇý¶¯³ÌÐò½Ó¿Ú (USBDI)¡£
¡¡¡¡Ö÷¿ØÆ÷£¨HC£©¿ØÖÆ×ÜÏßÉϰüµÄ´«Ê䡣ʹÓÃ1ºÁÃëµÄÖ¡¡£ÔÚÿ֡¿ªÊ¼ ʱ£¬Ö÷¿ØÆ÷²úÉúÒ»¸öÖ¡¿ªÊ¼£¨SOF, Start of Frame£©°ü¡£
¡¡¡¡SOF°üÓÃÓÚͬ²½Ö¡µÄ¿ªÊ¼ºÍ¸ú×ÙÖ¡µÄÊýÄ¿¡£°üÔÚÖ¡Öб»´«Ê䣬»òÓÉhost µ½É豸£¨out£©£¬»òÓÉÉ豸µ½host£¨in£©¡£´«Êä×ÜÊÇÓÉhost·¢Æð£¨ÂÖѯ´«Ê䣩¡£ Òò´ËÿÌõUSB×ÜÏßÖ»ÄÜÓÐÒ»¸öhost¡£Ã¿¸ö°üµÄ´«Êä¶¼ÓÐÒ»¸ö״̬½×¶Î£¬ Êý¾Ý½ÓÊÕÕß¿ÉÒÔÔÚÆäÖзµ»ØACK£¨Ó¦´ð½ÓÊÕ£©£¬NAK£¨ÖØÊÔ£©£¬STALL£¨´íÎó Ìõ¼þ£©»òʲôҲûÓУ¨»ìÂÒÊý¾Ý½×¶Î£¬É豸²»¿ÉÓûòÒѶϿª£©¡£USB¹æ·¶ USB specificationµÄµÚ8.5½Ú¸üÏêϸµØ½âÊÍÁ˰üµÄϸ½Ú¡£USB×ÜÏß ÉÏ¿ÉÒÔ³öÏÖËÄÖв»Í¬ÀàÐ͵Ĵ«Ê䣺¿ØÖÆ(control)£¬ ´ó¿é(bulk)£¬ ÖÐ¶Ï (interrupt)ºÍͬ²½(isochronous)¡£´«ÊäµÄÀàÐͺÍËûÃǵÄÌØÐÔÔÚÏÂÃæ ÃèÊö£¨`¹ÜµÀ'×Ó½ÚÖУ©¡£
¡¡¡¡USB×ÜÏßÉϵÄÉ豸ºÍÉ豸Çý¶¯³ÌÐò¼äµÄ´óÐÍ´«Êä±»Ö÷¿ØÆ÷»òHC Çý¶¯³ÌÐò·Ö¸îΪ¶à¸ö°ü¡£
¡¡¡¡µ½Ä¬È϶˵ãµÄÉ豸ÇëÇ󣨿ØÖÆ´«Ê䣩ÓÐÐ©ÌØÊâ¡£ËüÃÇÓÉÁ½»òÈý¸ö½×¶Î ×é³É£ºÆô¶¯£¨SETUP£©£¬Êý¾Ý£¨DATA£¬¿ÉÑ¡£©ºÍ״̬£¨STATUS£©¡£ÉèÖã¨set-up£© °ü±»·¢Ë͵½É豸¡£Èç¹û´æÔÚÊý¾Ý½×¶Î£¬Êý¾Ý°üµÄ·½ÏòÔÚÉèÖðüÖиø³ö¡£ ״̬½×¶ÎÖеķ½ÏòÓëÊý¾Ý½×¶ÎÆÚ¼äµÄ·½ÏòÏà·´£¬»òÕßµ±Ã»ÓÐÊý¾Ý½×¶Îʱ ΪIN¡£Ö÷¿ØÆ÷Ó²¼þÒ²Ìṩ¼Ä´æÆ÷£¬ÓÃÓÚ±£´æ¸ù¶Ë¿ÚµÄµ±Ç°×´Ì¬ºÍ×Ô´Ó ×´Ì¬¸Ä±ä¼Ä´æÆ÷×îºóÒ»´Î¸´Î»ÒÔÀ´Ëù·¢ÉúµÄ¸Ä±ä¡£USB¹æ·¶[2]½¨ÒéʹÓÃÒ»¸ö ÐéÄâhubÀ´Ìṩ¶ÔÕâЩ¼Ä´æÆ÷µÄ·ÃÎÊ¡£ÐéÄâhub±ØÐë·ûºÏ¹æ·¶µÚ11ÕÂÖиø³öµÄ hubÉ豸Àà¡£Ëü±ØÐëÌṩһ¸öĬÈϹܵÀʹµÃÉ豸ÇëÇó¿ÉÒÔ·¢Ë͸øËü¡£Ëü·µ»Ø ±ê×¼ºÍhubÀàÌØ¶¨µÄÒ»×éÃèÊö·û¡£ËüÒ²Ó¦µ±Ìṩһ¸öÖжϹܵÀÓÃÀ´±¨¸æÆä ¶Ë¿Ú·¢ÉúµÄ±ä»¯¡£µ±Ç°¿ÉÓõÄÖ÷¿ØÆ÷¹æ·¶ÓÐÁ½¸ö£º ͨÓÃÖ÷¿ØÆ÷½Ó¿Ú£¨UHCI£»Ó¢Ìضû£©ºÍ ¿ª·ÅÖ÷¿ØÆ÷½Ó¿Ú£¨OHCI£»¿µ°Ø£¬Î¢Èí£¬¹ú¼Ò°ëµ¼Ì壩¡£ UHCI¹æ·¶µÄÉè¼ÆÍ¨¹ýÒªÇóÖ÷¿ØÆ÷Çý¶¯³ÌÐòΪÿ֡µÄ´«ÊäÌṩÍêÕûµÄµ÷¶È£¬ ´Ó¶ø¼õÉÙÁËÓ²¼þ¸´ÔÓÐÔ¡£OHCIÀàÐ͵ĿØÖÆÆ÷×ÔÉíÌṩһ¸ö¸ü³éÏóµÄ½Ó¿ÚÀ´ Íê³ÉºÜ¶à¹¤×÷£¬´Ó¶ø¸ü¼Ó¶ÀÁ¢¡£
¡¡¡¡UHCIÖ÷¿ØÆ÷ά»¤×Å´øÓÐ1024¸öÖ¸Ïòÿ֡Êý¾Ý½á¹¹µÄÖ¡ÁÐ±í¡£ ËüÀí½âÁ½ÖÖ²»Í¬µÄÊý¾ÝÀàÐÍ£º´«ÊäÃèÊö·û£¨TD£©ºÍ¶ÓÁÐÍ·£¨QH£©¡£Ã¿¸ö TD±íʾ±íʾÓëÉ豸¶Ëµã½øÐÐͨÐŵÄÒ»¸ö°ü¡£QHÊǽ«Ò»Ð©TD£¨ºÍQH£©»®·Ö ³É×éµÄÒ»ÖÖ·½·¨¡£
¡¡¡¡Ã¿¸ö´«ÊäÓÉÒ»¸ö»ò¶à¸ö°ü×é³É¡£UHCIÇý¶¯³ÌÐò½«´óµÄ´«Êä·Ö¸î³É ¶à¸ö°ü¡£³ýͬ²½´«ÊäÍ⣬ÿ¸ö´«Êä¶¼»á·ÖÅäÒ»¸öQH¡£¶ÔÓÚÿÖÖÀàÐ굀 ´«Ê䣬¶¼ÓÐÒ»¸öÓë´ËÀàÐͶÔÓ¦µÄQH£¬ËùÓÐÕâЩQH¶¼»á±»¼¯Öе½Õâ¸öQHÉÏ¡£ ÓÉÓÚÓй̶¨µÄʱÑÓÐèÇó£¬Í¬²½´«Ê䱨ÐëÊ×ÏÈÖ´ÐУ¬ËüÊÇͨ¹ýÖ¡ÁбíÖÐµÄ Ö¸ÕëÖ±½ÓÒýÓõġ£×îºóµÄͬ²½TD´«ÊäÒýÓÃÄÇÒ»Ö¡µÄÖжϴ«ÊäµÄQH¡£ÖÐ¶Ï ´«ÊäµÄËùÓÐQHÖ¸Ïò¿ØÖÆ´«ÊäµÄQH£¬¿ØÖÆ´«ÊäµÄQHÓÖÖ¸Ïò´ó¿é´«ÊäµÄQH¡£ ÏÂÃæµÄͼ±í¸ø³öÁËÒ»¸öͼÐθÅÀÀ£º
¡¡¡¡Õâµ¼ÖÂÏÂÃæµÄµ÷¶È»áÔÚÿ֡ÖÐÔËÐС£¿ØÖÆÆ÷´ÓÖ¡ÁбíÖÐÈ¡µÃµ±Ç°Ö¡ µÄÖ¸Õëºó£¬Ê×ÏÈΪÄÇÒ»Ö¡ÖеÄËùÓеÄͬ²½(isochronous)°üÖ´ÐÐTD¡£ ÕâЩTDµÄ×îºóÒ»¸ö ÒýÓÃÄÇÒ»Ö¡µÄÖжϴ«ÊäµÄQH¡£È»ºóÖ÷¿ØÆ÷½«´ÓÄǸöQHÏÂÐе½¸÷¸ö Öжϴ«ÊäµÄQH¡£Íê³ÉÄÇÒ»¶ÓÁкó£¬Öжϴ«ÊäµÄQH»á½«¿ØÖÆÆ÷Ö¸Ïòµ½ËùÓÐ ¿ØÖÆ´«ÊäµÄQH¡£Ëü½«Ö´ÐÐÔÚÄǶùµÈ´ýµ÷¶ÈµÄËùÓÐ×Ó¶ÓÁУ¬È»ºóÊÇÔÚ´ó¿éQHÖÐ ÅŶӵÄËùÓд«Ê䡣ΪÁË·½±ã´¦ÀíÒÑÍê³É»òʧ°ÜµÄ´«Ê䣬Ӳ¼þ»áÔÚÿ֡ĩβ ²úÉú²»Í¬ÀàÐ͵ÄÖжϡ£ÔÚ´«ÊäµÄ×îºóÒ»¸öTDÖУ¬HCÇý¶¯³ÌÐòÉèÖà Interrupt-On-CompletionλÀ´±ê¼Ç´«ÊäÍê³ÉʱµÄÒ»¸öÖжϡ£Èç¹ûTD´ïµ½ÁË Æä×î´ó´íÎóÊý£¬¾Í±ê¼Ç´íÎóÖжϡ£Èç¹ûÔÚTDÖÐÉèÖö̰üÕì²â룬ÇÒ´«ÊäÁË Ð¡ÓÚËùÉèÖõİü³¤¶È£¨µÄ°ü£©£¬¾Í»á±ê¼Ç´ËÖжÏÒÔ֪ͨ¿ØÖÆÆ÷Çý¶¯³ÌÐò´«Êä ÒÑÍê³É¡£ÕÒ³öÄĸö´«ÊäÒÑÍê³É»ò²úÉú´íÎóÊÇÖ÷¿ØÆ÷Çý¶¯³ÌÐòµÄÈÎÎñ¡£ µ±ÖжϷþÎñÀý³Ì±»µ÷ÓÃʱ£¬Ëü½«¶¨Î»ËùÓÐÒÑÍê³ÉµÄ´«Êä²¢µ÷ÓÃËüÃǵĻص÷¡£
¡¡¡¡¸üÏ꾡µÄÃèÊöÇë¿´ UHCI specification¡£
¡¡¡¡¶ÔOHCIÖ÷¿ØÆ÷½øÐбà³ÌÒªÈÝÒ׵öࡣ¿ØÖÆÆ÷¼ÙÉèÓÐÒ»×é¶Ëµã(endpoint)¿ÉÓ㬠²¢ÖªµÀÖ¡Öв»Í¬´«ÊäÀàÐ͵ĵ÷¶ÈÓÅÏȼ¶ºÍÅÅÐò¡£Ö÷¿ØÆ÷ʹÓõÄÖ÷Òª Êý¾Ý½á¹¹ÊǶ˵ãÃèÊö·û£¨ED£©£¬ËüÉÏÃæÁ¬½Ó×ÅÒ»¸ö´«ÊäÃèÊö·û£¨TD£©µÄ¶ÓÁС£ ED°üº¬¶ËµãËùÔÊÐíµÄ×î´óµÄ°ü´óС£¬¿ØÖÆÆ÷Ó²¼þÍê³É°üµÄ·Ö¸î¡£Ã¿´Î´«Êä ºó¶¼»á¸üÐÂÖ¸ÏòÊý¾Ý»º³åÇøµÄÖ¸Õ룬µ±ÆðʼºÍÖÕÖ¹Ö¸ÕëÏàµÈʱ£¬TD¾ÍÍË¹é µ½Íê³É¶ÓÁÐ(done-queue)¡£ËÄÖÖÀàÐ͵Ķ˵ã¸÷ÓÐÆä×Ô¼ºµÄ¶ÓÁС£¿ØÖÆºÍ ´ó¿é(bulk)¶Ëµã·Ö±ðÔÚËüÃÇ×Ô¼ºµÄ¶ÓÁÐÅŶӡ£ÖжÏEDÔÚÊ÷ÖÐÅŶӣ¬ÔÚÊ÷ÖеÄÉî¶È ¶¨ÒåÁËËüÃÇÔËÐÐµÄÆµ¶È¡£
¡¡¡¡Ö¡Áбí ÖÐ¶Ï Í¬²½(isochronous) ¿ØÖÆ ´ó¿é(bulk)
¡¡¡¡Ö÷¿ØÆ÷ÔÚÿ֡ÖÐÔËÐеĵ÷¶È¿´ÆðÀ´ÈçÏ¡£¿ØÖÆÆ÷Ê×ÏÈÔËÐÐ·Ç ÖÜÆÚÐÔ¿ØÖƺʹó¿é¶ÓÁУ¬×¿Éµ½HCÇý¶¯³ÌÐòÉèÖõÄÒ»¸öʱ¼äÏÞÖÆ¡£ È»ºóÒÔÖ¡±àºÅµÍ5λ×÷ΪÖжÏEDÊ÷ÉÏÉî¶ÈΪ0µÄÄÇÒ»²ãÖеÄË÷Òý£¬ÔËÐÐ ÄǸöÖ¡±àºÅµÄÖжϴ«Êä¡£ÔÚÕâ¸öÊ÷µÄĩβ£¬Í¬²½ED±»Á¬½Ó£¬²¢Ëæºó±» ±éÀú¡£Í¬²½TD°üº¬ÁË´«ÊäÓ¦µ±ÔËÐÐÆäÖеĵÚÒ»¸öÖ¡µÄÖ¡±àºÅ¡£ËùÓÐÖÜÆÚ ÐԵĴ«ÊäÔËÐйýÒԺ󣬿ØÖƺʹó¿é¶ÓÁÐÔٴα»±éÀú¡£ÖжϷþÎñÀý³Ì»á±» ÖÜÆÚÐԵص÷Óã¬À´´¦ÀíÍê³ÉµÄ¶ÓÁУ¬ÎªÃ¿¸ö´«Êäµ÷Óûص÷£¬²¢ÖØÐµ÷¶È ÖжϺÍͬ²½¶Ëµã¡£
¡¡¡¡¸üÏ꾡µÄÃèÊöÇë¿´ OHCI specification¡£·þÎñ²ã£¬¼´Öмä²ã£¬ÌṩÁËÒԿɿصķ½Ê½ ¶ÔÉ豸½øÐзÃÎÊ£¬²¢Î¬»¤×ÅÓɲ»Í¬Çý¶¯³ÌÐòºÍ·þÎñ²ãËùʹÓõÄ×ÊÔ´¡£ ´Ë²ã´¦ÀíÏÂÃæ¼¸·½Ã棺
É豸ÅäÖÃÐÅÏ¢
ÓëÉ豸½øÐÐͨÐŵĹܵÀ
̽²âºÍÁ¬½ÓÉ豸£¬ÒÔ¼°´ÓÉ豸·ÖÀë(detach)¡£
¡¡¡¡Ã¿¸öÉ豸ÌṩÁ˲»Í¬¼¶±ðµÄÅäÖÃÐÅÏ¢¡£Ã¿¸öÉ豸¾ßÓÐÒ»¸ö»ò¶à¸ö ÅäÖã¬Ì½²â/Á¬½ÓÆÚ¼ä´ÓÆäÖÐÑ¡¶¨Ò»¸ö¡£ÅäÖÃÌṩ¹¦Âʺʹø¿íÒªÇó¡£ Ã¿¸öÅäÖÃÖпÉÒÔÓжà¸ö½Ó¿Ú¡£É豸½Ó¿ÚÊǶ˵ãµÄ»ã¼¯(collection)¡£ ÀýÈ磬USBÑïÉùÆ÷¿ÉÒÔÓÐÒ»¸öÒôƵ½Ó¿Ú£¨ÒôƵÀࣩ£¬ºÍ¶ÔÐýÅ¥(knob)¡¢ ²¦ºÅÅÌ(dial)ºÍ°´Å¥µÄ½Ó¿Ú£¨HIDÀࣩ¡£ Ò»¸öÅäÖÃÖеÄËùÓнӿڿÉÒÔͬʱÓÐЧ£¬²¢¿É±»²»Í¬µÄ Çý¶¯³ÌÐòÁ¬½Ó¡£Ã¿¸ö½Ó¿Ú¿ÉÒÔÓб¸Óýӿڣ¬ÒÔÌṩ²»Í¬ÖÊÁ¿µÄ·þÎñ²ÎÊý¡£ ÀýÈ磬ÔÚÕÕÏà»úÖУ¬ÕâÓÃÀ´Ìṩ²»Í¬µÄÖ¡´óСÒÔ¼°Ã¿ÃëÖ¡Êý¡£
¡¡¡¡Ã¿¸ö½Ó¿ÚÖпÉÒÔÖ¸¶¨0»ò¶à¸ö¶Ëµã¡£¶ËµãÊÇÓëÉ豸½øÐÐͨÐŵĵ¥Ïò ·ÃÎʵ㡣ËüÃÇÌṩ»º³åÇøÀ´ÁÙʱ´æ´¢´ÓÉ豸¶øÀ´µÄ£¬»òÍâ³öµ½É豸µÄÊý¾Ý¡£ ÿ¸ö¶ËµãÔÚÅäÖÃÖÐÓÐΨһµØÖ·£¬¼´¶ËµãºÅ¼ÓÉÏÆä·½Ïò¡£Ä¬È϶˵㣬¼´ ¶Ëµã0£¬²»ÊÇÈκνӿڵÄÒ»²¿·Ö£¬²¢ÇÒÔÚËùÓÐÅäÖÃÖпÉÓá£ËüÓÉ·þÎñ²ã ¹ÜÀí£¬²¢ÇÒÉ豸Çý¶¯³ÌÐò²»ÄÜÖ±½ÓʹÓá£
¡¡¡¡Level 0 Level 1 Level 2 Slot 0
¡¡¡¡Slot 3 Slot 2 Slot 1
¡¡¡¡(Ö»ÏÔʾÁË32¸ö²ÛÖеÄ4¸ö)
¡¡¡¡ÕâÖÖ²ã´Î»¯ÅäÖÃÐÅÏ¢ÔÚÉ豸ÖÐͨ¹ý±ê×¼µÄÒ»×éÃèÊö·ûÀ´ÃèÊö£¨²Î¿´ USB¹æ·¶[2]µÚ9.6½Ú£©¡£ËüÃÇ¿ÉÒÔͨ¹ýGet Descriptor RequestÀ´ÇëÇó¡£ ·þÎñ²ã»º´æÕâЩÃèÊö·ûÒÔ±ÜÃâÔÚUSB×ÜÏßÉϽøÐв»±ØÒªµÄ´«Êä¡£¶ÔÕâЩ ÃèÊö·ûµÄ·ÃÎÊÊÇͨ¹ýº¯Êýµ÷ÓÃÀ´ÌṩµÄ¡£
É豸ÃèÊö·û£º¹ØÓÚÉ豸µÄͨÓÃÐÅÏ¢£¬È繩ӦÉÌ£¬²úÆ· ºÍÐÞ¶©ID£¬Ö§³ÖµÄÉ豸Àà¡¢×ÓÀàºÍÊÊÓõÄÐÒ飬ĬÈ϶˵ãµÄ×î´ó°ü´óС µÈ¡£
ÅäÖÃÃèÊö·û£º´ËÅäÖÃÖеĽӿÚÊý£¬Ö§³ÖµÄ¹ÒÆðºÍ »Ö¸´ÄÜÁ¦£¬ÒÔ¼°¹¦ÂÊÒªÇó¡£
½Ó¿ÚÃèÊö·û£º½Ó¿ÚÀà¡¢×ÓÀàºÍÊÊÓõÄÐÒ飬½Ó¿Ú±¸Óà ÅäÖõÄÊýÄ¿ºÍ¶ËµãÊýÄ¿¡£
¶ËµãÃèÊö·û£º¶ËµãµØÖ·¡¢·½ÏòºÍÀàÐÍ£¬Ö§³ÖµÄ×î´ó°ü ´óС£¬Èç¹ûÊÇÖжÏÀàÐ͵Ķ˵ãÔò»¹°üÀ¨ÂÖѯƵÂÊ¡£Ä¬È϶˵㣨¶Ëµã0£© ûÓÐÃèÊö·û£¬¶øÇÒ´Ó²»±»¼ÆÈë½Ó¿ÚÃèÊö·ûÖС£
×Ö·û´®ÃèÊö·û£ºÔÚÆäËûÃèÊö·ûÖлáΪijЩ×Ö¶ÎÌṩ ×Ö·û´®Ë÷Òý¡£ËüÃǿɱ»ÓÃÀ´¼ìÈ¡ÃèÊöÐÔ×Ö·û´®£¬¿ÉÄÜÒÔ¶àÖÖÓïÑÔ µÄÐÎʽÌṩ¡£
¡¡¡¡Àà˵Ã÷(specification)¿ÉÒÔÌí¼ÓËüÃÇ×Ô¼ºµÄÃèÊö·ûÀàÐÍ£¬ÕâЩÃèÊö·û Ò²¿ÉÒÔͨ¹ýGetDescriptor RequestÀ´»ñµÃ¡£
¡¡¡¡¹ÜµÀÓëÉ豸É϶˵ãµÄͨÐÅ£¬Á÷¾ËùνµÄ¹ÜµÀ¡£Çý¶¯³ÌÐò½«µ½¶ËµãµÄ ´«ÊäÌá½»µ½¹ÜµÀ£¬²¢Ìṩ´«Ê䣨Òì²½´«Ê䣩ʧ°Ü»òÍê³Éʱµ÷ÓõĻص÷£¬ »òµÈ´ýÍê³É£¨Í¬²½´«Ê䣩¡£µ½¶ËµãµÄ´«ÊäÔڹܵÀÖб»´®Ðл¯¡£´«Êä»òÕßÍê³É£¬ »òÕßʧ°Ü£¬»òÕß³¬Ê±£¨Èç¹ûÉèÖÃÁ˳¬Ê±£©¡£¶ÔÓÚ´«ÊäÓÐÁ½ÖÖÀàÐ͵ij¬Ê±¡£ ³¬Ê±µÄ·¢Éú¿ÉÄÜÓÉÓÚUSB×ÜÏßÉϵij¬Ê±£¨ºÁÃ룩¡£ÕâЩ³¬Ê±±»ÊÓΪʧ°Ü£¬ ¿ÉÄÜÊÇÓÉÓÚÉ豸¶Ï¿ªÁ¬½ÓÒýÆðµÄ¡£ÁíÒ»ÖÖ³¬Ê±ÔÚÈí¼þÖÐʵÏÖ£¬µ±´«ÊäûÓÐ ÔÚÖ¸¶¨µÄʱ¼ä£¨Ã룩ÄÚÍê³Éʱ´¥·¢¡£ÕâÊÇÓÉÓÚÉ豸¶Ô´«ÊäµÄ°ü·ñ¶¨Ó¦´ðÒýÆðµÄ¡£ ÆäÔÒòÊÇÓÉÓÚÉ豸»¹Ã»ÓÐ×¼±¸ºÃ½ÓÊÕÊý¾Ý£¬»º³åÇøÇ·ÔØ»ò³¬ÔØ£¬»òÐÒé´íÎó¡£
¡¡¡¡Èç¹û¹ÜµÀÉϵĴ«Êä´óÓÚ¹ØÁªµÄ¶ËµãÃèÊö·ûÖÐÖ¸¶¨µÄ×î´ó°ü´óС£¬Ö÷ ¿ØÆ÷£¨OHCI£©»òHCÇý¶¯³ÌÐò£¨UHCI£©½«°´×î´ó°ü´óС·Ö¸î´«Ê䣬²¢ÇÒ×îºó Ò»¸ö°ü¿ÉÄÜСÓÚ×î´ó°üµÄ´óС¡£
¡¡¡¡ÓÐʱºò¶ÔÉ豸À´Ëµ·µ»ØÉÙÓÚËùÇëÇóµÄÊý¾Ý²¢²»ÊǸöÎÊÌâ¡£ÀýÈ磬 µ½µ÷ÖÆ½âµ÷Æ÷µÄ´ó¿éin´«Êä¿ÉÄÜÇëÇó200×Ö½ÚµÄÊý¾Ý£¬µ«µ÷ÖÆ½âµ÷Æ÷ ÄÇʱֻÓÐ5¸ö×Ö½Ú¿ÉÓá£Çý¶¯³ÌÐò¿ÉÒÔÉèÖö̰ü(SPD)±êÖ¾¡£ËüÔÊÐíÖ÷ ¿ØÆ÷¼´Ê¹ÔÚ´«ÊäµÄÊý¾ÝÁ¿ÉÙÓÚËùÇëÇóµÄÊý¾ÝÁ¿µÄÇé¿öÏÂÒ²½ÓÊܰü¡£ Õâ¸ö±êÖ¾Ö»ÔÚin´«ÊäÖÐÓÐЧ£¬ÒòΪ½«Òª±»·¢Ë͵½É豸µÄÊý¾ÝÁ¿×ÜÊÇÊÂÏÈ ÖªµÀµÄ¡£Èç¹û´«Êä¹ý³ÌÖÐÉ豸³öÏÖ²»¿É»Ö¸´µÄ´íÎ󣬹ܵÀ»á±»Í£¶Ù¡£ ½ÓÊÜ»ò·¢Ë͸ü¶àÊý¾ÝÒÔǰ£¬Çý¶¯³ÌÐòÐèҪȷ¶¨Í£¶ÙµÄÔÒò£¬²¢Í¨¹ýÔÚ Ä¬ÈϹܵÀÉÏ·¢ËÍÇå³ý¶Ëµã¹ÒÆðÉ豸ÇëÇó(clear endpoint halt device request)À´Çå³ý¶ËµãÍ£¶ÙÌõ¼þ¡£
¡¡¡¡ÓÐËÄÖÖ²»Í¬ÀàÐ͵Ķ˵ãºÍ¶ÔÓ¦µÄ¹ÜµÀ£º -
¿ØÖƹܵÀ/ĬÈϹܵÀ£º ÿ¸öÉ豸ÓÐÒ»¸ö¿ØÖƹܵÀ£¬Á¬½Óµ½Ä¬È϶˵㣨¶Ëµã0£©¡£´Ë¹ÜµÀÔËÔØÉ豸 ÇëÇóºÍ¹ØÁªµÄÊý¾Ý¡£Ä¬ÈϹܵÀºÍÆäËû¹ÜµÀÉϵĴ«ÊäµÄÇø±ðÔÚÓÚ´«ÊäËù ʹÓõÄÐÒ飬ÐÒéÔÚUSB¹æ·¶[2]ÖÐÃèÊö¡£ÕâЩÇëÇóÓÃÓÚ¸´Î»ºÍÅäÖÃÉ豸¡£ ÿ¸öÉ豸±ØÐëÖ§³ÖUSB¹æ·¶[2]µÄµÚ9ÕÂÖÐÌṩµÄÒ»×é»ù±¾ÃüÁî¡£¹ÜµÀÉÏ Ö§³ÖµÄÃüÁî¿ÉÒÔͨ¹ýÉ豸Àà¹æ·¶À©Õ¹£¬ÒÔÖ§³Ö¶îÍâµÄ¹¦ÄÜ¡£
´ó¿é(bulk)¹ÜµÀ£ºÕâÊÇUSBÓëÔʼ´«ÊäýÌå¶ÔÓ¦µÄµÈ¼ÛÎï¡£
ÖжϹܵÀ£ºhostÏòÉ豸·¢ËÍÊý¾ÝÇëÇó£¬Èç¹ûÉ豸ûÓÐ ¶«Î÷·¢ËÍ£¬Ôò½«NAK£¨·ñ¶¨Ó¦´ð£©Êý¾Ý°ü¡£Öжϴ«Êä°´´´½¨¹ÜµÀʱָ¶¨µÄ ƵÂʱ»µ÷¶È¡£
ͬ²½¹ÜµÀ£ºÕâЩ¹ÜµÀÓÃÓÚ¾ßÓй̶¨Ê±ÑÓµÄͬ²½Êý¾Ý£¬ ÀýÈçÊÓÆµ»òÒôƵÁ÷£¬µ«²»±£Ö¤Ò»¶¨´«Êä¡£µ±Ç°ÊµÏÖÖÐÒѾÓжÔÕâÖÖÀàÐÍ ¹ÜµÀµÄijЩ֧³Ö¡£µ±´«ÊäÆÚ¼ä³öÏÖ´íÎ󣬻òÕßÓÉÓÚ£¬ÀýÈçȱ·¦»º³åÇø¿Õ¼ä À´´æ´¢½øÈëµÄÊý¾Ý¶øÒýÆðµÄÉ豸·ñ¶¨Ó¦´ð°ü£¨NAK£©Ê±£¬¿ØÖÆ¡¢´ó¿éºÍÖÐ¶Ï ¹ÜµÀÖеİü»á±»ÖØÊÔ¡£¶øÍ¬²½°üÔÚ´«µÝʧ°Ü»ò¶Ô°üNAKʱ²»»áÖØÊÔ£¬ÒòΪ ÄÇÑù¿ÉÄÜÎ¥·´Í¬²½Ô¼Êø¡£
¡¡¡¡ËùÐè´ø¿íµÄ¿ÉÓÃÐÔÔڹܵÀµÄ´´½¨ÆÚ¼ä±»¼ÆËã¡£´«ÊäÔÚ1ºÁÃëµÄÖ¡ÄÚ ½øÐе÷¶È¡£Ö¡ÖеĴø¿í·ÖÅäÓÉUSB¹æ·¶µÄµÚ5.6½Ú¹æ¶¨¡£Í¬²½ºÍÖжϴ«Êä±» ÔÊÐíÏûºÄÖ¡Öжà´ï90%µÄ´ø¿í¡£¿ØÖƺʹó¿é´«ÊäµÄ°üÔÚËùÓÐͬ²½ºÍÖжϰü Ö®ºó½øÐе÷¶È£¬²¢½«ÏûºÄËùÓÐÊ£Óà´ø¿í¡£
¡¡¡¡¹ØÓÚ´«Êäµ÷¶ÈºÍ´ø¿í»ØÊյĸü¶àÐÅÏ¢¿ÉÒÔÔÚUSB¹æ·¶[2]µÄµÚ5Õ£¬ UHCI¹æ·¶[3]µÄµÄµÚ1.3½Ú£¬OHCI¹æ·¶[4]µÄ3.4.2½ÚÖÐÕÒµ½¡£
¡¡¡¡¼¯ÖÐÆ÷(hub)֪ͨÐÂÉ豸ÒÑÁ¬½Óºó£¬·þÎñ²ã¸ø¶Ë¿Ú¼Óµç(switch on)£¬ ΪÉ豸Ìṩ100mAµÄµçÁ÷¡£ ´ËʱÉ豸´¦ÓÚÆäĬÈÏ״̬£¬²¢¼àÌýÉ豸µØÖ·0¡£·þÎñ²ã»áͨ¹ýĬÈÏ ¹ÜµÀ¼ÌÐø¼ìÈ¡¸÷ÖÖÃèÊö·û¡£´ËºóËü½«ÏòÉ豸·¢ËÍSet AddressÇëÇ󣬽«É豸 ´ÓĬÈÏÉ豸µØÖ·(µØÖ·0)ÒÆ¿ª¡£¿ÉÄÜÓжà¸öÉ豸Çý¶¯³ÌÐòÖ§³Ö´ËÉ豸¡£ÀýÈ磬 Ò»¸öµ÷ÖÆ½âµ÷Æ÷¿ÉÄÜͨ¹ýAT¼æÈݽӿÚÖ§³ÖISDN TA¡£È»¶ø£¬Ìض¨ÐͺŵÄISDN ÊÊÅäÆ÷µÄÇý¶¯³ÌÐò¿ÉÄÜÌṩ¶Ô´ËÉ豸µÄ¸üºÃÖ§³Ö¡£ÎªÁËÖ§³ÖÕâÑùµÄÁé»îÐÔ£¬ ̽²â»á·µ»ØÓÅÏȼ¶£¬Ö¸Ê¾ËûÃǵÄÖ§³Ö¼¶±ð¡£Ö§³Ö²úÆ·µÄÌØ¶¨°æ±¾»á¾ßÓÐ×î¸ß ÓÅÏȼ¶£¬Í¨ÓÃÇý¶¯³ÌÐò¾ßÓÐ×îµÍÓÅÏȼ¶¡£Èç¹ûÒ»¸öÅäÖÃÄÚÓжà¸ö½Ó¿Ú£¬Ò²¿ÉÄÜ ¶à¸öÇý¶¯³ÌÐò»áÁ¬½Óµ½Ò»¸öÉ豸¡£Ã¿¸öÇý¶¯³ÌÐòÖ»ÐèÖ§³ÖËùÓнӿڵÄÒ»¸ö×Ó¼¯¡£
¡¡¡¡ÎªÐÂÁ¬½ÓµÄÉ豸̽²âÇý¶¯³ÌÐòʱ£¬Ê×ÏÈ̽²âÉè±¸ÌØ¶¨µÄÇý¶¯³ÌÐò¡£ Èç¹ûûÓз¢ÏÖ£¬Ôò̽²â´úÂëÔÚËùÓÐÖ§³ÖµÄÅäÖÃÉÏÖØ¸´Ì½²â¹ý³Ì£¬Ö±µ½ ÔÚÒ»¸öÅäÖÃÖÐÁ¬½Óµ½Ò»¸öÇý¶¯³ÌÐò¡£ÎªÁËÖ§³Ö²»Í¬½Ó¿ÚÉÏʹÓöà¸öÇý¶¯ ³ÌÐòµÄÉ豸£¬Ì½²â»áÔÚÒ»¸öÅäÖÃÖеÄËùÓÐÉÐδ±»Çý¶¯³ÌÐòÉùÃ÷(claim)µÄ ½Ó¿ÚÉÏÖØ¸´½øÐС£³¬³ö¼¯ÖÐÆ÷¹¦ÂÊÔ¤ËãµÄÅäÖûᱻºöÂÔ¡£Á¬½ÓÆÚ¼ä£¬Çý¶¯ ³ÌÐòÓ¦µ±°ÑÉ豸³õʼ»¯µ½Êʵ±×´Ì¬£¬µ«²»Äܸ´Î»£¬ÒòΪÄÇÑù»áʹµÃÉ豸½« Ëü×Ô¼º´Ó×ÜÏßÉ϶Ͽª£¬²¢ÖØÐÂÆô¶¯Ì½²â¹ý³Ì¡£ÎªÁ˱ÜÃâÏûºÄ²»±ØÒªµÄ´ø¿í£¬ ²»Ó¦µ±ÔÚÁ¬½ÓʱÉùÃ÷ÖжϹܵÀ£¬¶øÓ¦µ±ÑÓ³Ù·ÖÅä¹ÜµÀ£¬Ö±µ½´ò¿ªÎļþ²¢ÕæµÄ ʹÓÃÊý¾Ý¡£µ±¹Ø±ÕÎļþʱ£¬¹ÜµÀÒ²Ó¦µ±±»Ôٴιرգ¬¾¡¹ÜÉ豸¿ÉÄÜÈÔÈ» Á¬½Ó×Å¡£
¡¡¡¡É豸Çý¶¯³ÌÐòÓëÉ豸½øÐÐÈκÎÊÂÎñÆÚ¼ä£¬Ó¦µ±Ô¤ÆÚ»á½ÓÊÕµ½´íÎó¡£ USBµÄÉè¼ÆÖ§³Ö²¢¹ÄÀøÉ豸ÔÚÈκε㼰ʱ¶Ï¿ªÁ¬½Ó¡£Çý¶¯³ÌÐòÓ¦µ±È·±£ µ±É豸²»ÔÚʱ×öÕýÈ·µÄÊÂÇé¡£
¡¡¡¡´ËÍ⣬¶Ï¿ªÁ¬½Ó(disconnect)ºóÓÖÖØÐÂÁ¬½Ó(reconnect)µÄÉ豸²»»á ±»ÖØÐÂÁ¬½Ó(reattach)ΪÏàͬµÄÉ豸ʵÀý¡£ ½«À´µ±¸ü¶àµÄÉ豸֧³ÖÐòÁкţ¨²Î¿´É豸ÃèÊö·û£©£¬ »ò¿ª·¢³öÆäËû¶¨ÒåÉ豸±êʶµÄ·½·¨µÄʱºò£¬ÕâÖÖÇé¿ö¿ÉÄÜ»á¸Ä±ä¡£
¡¡¡¡É豸¶Ï¿ªÁ¬½ÓÊÇÓɼ¯ÖÐÆ÷ÔÚ´«µÝµ½¼¯ÖÐÆ÷Çý¶¯³ÌÐòµÄÖжϰüÖз¢ ÐźÅ֪ͨ(signal)µÄ¡£×´Ì¬¸Ä±äÐÅϢָʾÄĸö¶Ë¿Ú·¢ÏÖÁËÁ¬½Ó¸Ä±ä¡£ Á¬½Óµ½ÄǸö¶Ë¿ÚÉϵÄÉ豸µÄËùÓÐÉ豸Çý¶¯³ÌÐò¹²ÓõÄÉ豸·ÖÀë·½·¨±»µ÷Ó㬠½á¹¹±»³¹µ×ÇåÀí¡£Èç¹û¶Ë¿Ú״ָ̬ʾͬʱһ¸öÉ豸ÒѾÁ¬½Ó(connect)µ½ÄǸö ¶Ë¿Ú£¬Ôò̽²âºÍÁ¬½ÓÉ豸µÄ¹ý³Ì½«±»Æô¶¯¡£É豸¸´Î»½«ÔÚ¼¯ÖÐÆ÷ÉϲúÉú Ò»¸ö¶Ï¿ª-Á¬½ÓÐòÁУ¬²¢½«°´ÉÏÃæËùÊö½øÐд¦Àí¡£
¡¡¡¡USB¹æ·¶Ã»Óж¨Òå³ýĬÈϹܵÀÍâÆäËû¹ÜµÀÉÏʹÓõÄÐÒé¡£Õâ·½ÃæµÄÐÅÏ¢ ¿ÉÒÔ´Ó¸÷ÖÖÀ´Ô´»ñµÃ¡£×î׼ȷµÄÀ´Ô´ÊÇUSBÖ÷Ò³[1]ÉϵĿª·¢Õß²¿·Ö¡£´ÓÕâЩ Ò³ÃæÉÏ¿ÉÒԵõ½ÊýÄ¿²»¶ÏÔö³¤µÄÉ豸ÀàµÄ¹æ·¶¡£ÕâЩ¹æ·¶Ö¸¶¨´ÓÇý¶¯³ÌÐò ½Ç¶È¿´ÆðÀ´¼æÈÝÉ豸Ӧµ±ÔõÑù£¬ËüÐèÒªÌṩµÄ»ù±¾¹¦ÄܺÍͨÐÅͨµÀÉÏʹÓÃµÄ ÐÒé¡£USB¹æ·¶[2]°üÀ¨Á˼¯ÖÐÆ÷ÀàµÄÃèÊö¡£ÈË»ú½çÃæÉ豸(HID)µÄÀà¹æ·¶ÒѾ ´´½¨³öÀ´£¬ÒÔӺ϶ԼüÅÌ¡¢Êý×ÖÊäÈë°å¡¢ÌõÐÎÂëÔĶÁÆ÷¡¢°´Å¥¡¢ÐýÅ¥(ÊÖ±úknob)¡¢ ¿ª¹ØµÈµÄÒªÇó¡£ÁíÒ»¸öÀý×ÓÊÇÓÃÓÚ´óÈÝÁ¿´æ´¢É豸µÄÀà¹æ·¶¡£É豸ÀàµÄÍêÕûÁÐ±í ²Î¿´USBÖ÷Ò³[1]µÄ¿ª·¢Õß²¿·Ö¡£
¡¡¡¡È»¶ø, Ðí¶àÉ豸µÄÐÒéÐÅÏ¢»¹Ã»Óб»¹«²¼¡£¹ØÓÚËùÓÃÐÒéµÄÐÅÏ¢ ¿ÉÄÜ¿ÉÒÔ´ÓÖÆÔìÉ豸µÄ¹«Ë¾»ñµÃ¡£Ò»Ð©¹«Ë¾»áÔÚ¸øÄã¹æ·¶Ö®Ç°ÒªÇóÄãÇ©Êð ±£ÃÜÐÒé(Non-Disclosure Agreement, NDA)¡£´ó¶àÊýÇé¿öÏ£¬Õâ»á×èÖ¹ ½«Çý¶¯³ÌÐò¿ª·ÅÔ´´úÂë¡£
¡¡¡¡ÁíÒ»¸öÐÅÏ¢µÄºÜºÃÀ´Ô´ÊÇLinuxÇý¶¯³ÌÐòÔ´´úÂ룬ÒòΪºÜ¶à¹«Ë¾ÒѾ ¿ªÊ¼ÎªËûÃǵÄÉ豸ÌṩLinuxϵÄÇý¶¯³ÌÐò¡£ÁªÏµÄÇЩÇý¶¯³ÌÐò×÷ÕßѯÎÊ ËûÃǵÄÐÅÏ¢À´Ô´×ÜÊÇÒ»¸öºÃÖ÷Òâ¡£
¡¡¡¡Àý×Ó£ºÈË»ú½çÃæÉ豸¡£ÈË»ú½çÃæÉ豸£¬Èç¼üÅÌ¡¢Êó±ê¡¢Êý×ÖÊäÈë°å¡¢ °´Å¥¡¢²¦ºÅÅ̵ȵĹ淶±»ÆäËûÉ豸Àà¹æ·¶ÒýÓ㬲¢ÔںܶàÉ豸ÖÐʹÓá£
¡¡¡¡ÀýÈ磬ÒôƵÑïÉùÆ÷Ìṩµ½Êýģת»»Æ÷µÄ¶Ëµã£¬¿ÉÄÜ»¹Ìṩ¶îÍâ¹ÜµÀ ÓÃÓÚÂó¿Ë·ç¡£ËüÃÇҲΪÉè±¸Ç°ÃæµÄ°´Å¥ºÍ²¦ºÅÅÌÔÚµ¥¶ÀµÄ½Ó¿ÚÖÐÌṩHID ¶Ëµã¡£¼àÊÓÆ÷¿ØÖÆÀàÒ²ÊÇÈç´Ë¡£Í¨¹ý¿ÉÓõÄÄں˺ÍÓû§¿Õ¼äµÄ¿â£¬ÓëHID ÀàÇý¶¯³ÌÐò»òͨÓÃÇý¶¯³ÌÐòÒ»Æð¿ÉÒÔ¼òµ¥Ö±½ÓµØ´´½¨¶ÔÕâЩ½Ó¿ÚµÄÖ§³Ö¡£ ÁíÒ»¸öÉ豸¿ÉÒÔ×÷ΪÔÚÒ»¸öÅäÖÃÖеĶà¸ö½Ó¿ÚÓɲ»Í¬µÄÉ豸Çý¶¯³ÌÐòÇý¶¯ µÄÀý×Ó£¬Õâ¸öÉ豸ÊÇÒ»ÖÖ±ãÒ˵ļüÅÌ£¬´øÓÐÀϵÄÊó±ê½Ó¿Ú¡£ÎªÁ˱ÜÃâÔÚ É豸ÖÐΪUSB¼¯ÖÐÆ÷°üÀ¨Ò»¸öÓ²¼þ¶øµ¼Öµijɱ¾ÉÏÉý£¬ÖÆÔìÉ̽«´Ó¼üÅ̱³ÃæµÄ PS/2¶Ë¿Ú½ÓÊÕµ½µÄÊó±êÊý¾ÝÓëÀ´×Ô¼üÅ̵İ´¼ü×éºÏ³ÉÔÚͬһ¸öÅäÖÃÖÐµÄ Á½¸öµ¥¶ÀµÄ½Ó¿Ú¡£Êó±êºÍ¼üÅÌÇý¶¯³ÌÐò¸÷×ÔÁ¬½Óµ½Êʵ±µÄ½Ó¿Ú£¬²¢·ÖÅäµ½ Á½¸ö¶ÀÁ¢¶ËµãµÄ¹ÜµÀ.
¡¡¡¡Àý×Ó£º¹Ì¼þÏÂÔØ¡£ÒѾ¿ª·¢³öÀ´µÄÐí¶àÉ豸ÊÇ»ùÓÚͨÓÃÄ¿µÄ´¦ÀíÆ÷£¬ ²¢½«¶îÍâµÄUSBºËÐļÓÈëÆäÖС£ÓÉÓÚÇý¶¯³ÌÐòµÄ¿ª·¢ºÍUSBÉ豸µÄ¹Ì¼þÈÔÈ» ·Ç³£Ð£¬Ðí¶àÉ豸ÐèÒªÔÚÁ¬½Ó(connect)Ö®ºóÏÂÔØ¹Ì¼þ¡£
¡¡¡¡ÏÂÃæµÄ²½Öè·Ç³£¼òÃ÷Ö±½Ó¡£É豸ͨ¹ý¹©Ó¦É̺ͲúÆ·ID±êʶ×ÔÉí¡£µÚÒ» ¸öÇý¶¯³ÌÐò̽²â²¢Á¬½Óµ½Ëü£¬²¢½«¹Ì¼þÏÂÔØµ½ÆäÖС£´ËºóÉ豸×Ô¼ºÈí¸´Î»£¬ Çý¶¯³ÌÐò·ÖÀë¡£¶ÌÔݵÄÔÝÍ£Ö®ºóÉ豸Ðû²¼ËüÔÚ×ÜÏßÉϵĴæÔÚ¡£É豸½«¸Ä±ä Æä¹©Ó¦ÉÌ/²úÆ·/°æ±¾µÄIDÒÔ·´Ó³ÆäÌṩÓй̼þµÄÊÂʵ£¬Òò´ËÁíÒ»¸öÇý¶¯³ÌÐò ½«Ì½²âËü²¢Á¬½Ó(attach)µ½Ëü¡£
¡¡¡¡ÕâЩÀàÐ͵ÄÉ豸µÄÒ»¸öÀý×ÓÊÇ»ùÓÚEZ-USBµÄActiveWire I/O°å¡£Õâ¸ö оƬÓÐÒ»¸öͨÓù̼þÏÂÔØÆ÷¡£ÏÂÔØµ½ActiveWire°å×ÓÉϵĹ̼þ¸Ä±ä°æ±¾ID¡£ È»ºóËü½«Ö´ÐÐEZ-USBоƬµÄUSB²¿·ÖµÄÈí¸´Î»£¬´ÓUSB×ÜÏßÉ϶Ͽª£¬²¢ÔÙ´Î ÖØÐÂÁ¬½Ó¡£
¡¡¡¡Àý×Ó£º´óÈÝÁ¿´æ´¢É豸¡£¶Ô´óÈÝÁ¿´æ´¢É豸µÄÖ§³ÖÖ÷ÒªÎ§ÈÆÏÖÓÐµÄ ÐÒé¹¹½¨¡£Iomega USB ZipÇý¶¯Æ÷ÊÇ»ùÓÚSCSI°æ±¾µÄÇý¶¯Æ÷¡£SCSIÃüÁîºÍ ״̬ÐÅÏ¢±»°ü×°µ½¿éÖУ¬ÔÚ´ó¿é(bulk)¹ÜµÀÉÏ´«Êäµ½/À´×ÔÉ豸£¬ÔÚUSBÏß ÉÏÄ£ÄâSCSI¿ØÖÆÆ÷¡£ATAPIºÍUFIÃüÁîÒÔÏàËÆµÄ·½Ê½±»Ö§³Ö¡£
¡¡¡¡´óÈÝÁ¿´æ´¢¹æ·¶Ö§³ÖÁ½ÖÖ²»Í¬ÀàÐ͵ĶÔÃüÁî¿éµÄ°ü×°¡£×î³õµÄ³¢ÊÔ »ùÓÚͨ¹ýĬÈϹܵÀ·¢ËÍÃüÁîºÍ״̬ÐÅÏ¢£¬Ê¹Óôó¿é´«ÊäÔÚhostºÍÉ豸֮¼ä ÒÆ¶¯Êý¾Ý¡£ÔÚ¾Ñé»ù´¡ÉÏÉè¼Æ³öÁíÒ»ÖÖ·½·¨£¬ÕâÖÖ·½·¨»ùÓÚ°ü×°ÃüÁîºÍ ״̬¿é£¬²¢ÔÚ´ó¿éoutºÍin¶ËµãÉÏ·¢ËÍËüÃÇ¡£¹æ·¶¾«È·µØÖ¸¶¨Á˺Îʱ±ØÐë ·¢Éúʲô£¬ÒÔ¼°ÔÚÅöµ½´íÎóÌõ¼þµÄÇé¿öÏÂÓ¦¸Ã×öʲô¡£ÎªÕâЩÉ豸±àд Çý¶¯³ÌÐòµÄ×î´óÌôÕ½ÊÇе÷»ùÓÚUSBµÄÐÒ飬ÈÃËüÊʺÏÒÑÓеĶԴóÈÝÁ¿´æ´¢É豸 µÄÖ§³Ö¡£CAMÌṩÁ˹³×Ó£¬ÒÔÏ൱ֱ½ÓÁ˵±µÄ·½Ê½À´Íê³ÉÕâ¸ö¡£ATAPI¾Í ûÓÐÕâô¼òµ¥ÁË£¬ÒòΪÀúÊ·ÉÏIDE½Ó¿Ú´ÓδÓйý¶àÖÖ²»Í¬µÄ±íÏÖ·½Ê½¡£
¡¡¡¡À´×ÔY-E DataµÄ¶ÔUSBÈíÅ̵ÄÖ§³ÖÒ²²»ÊÇÄÇôֱ¹Û£¬ÒòΪÉè¼ÆÁËÒ»Ì× ÐµÄÃüÁ¡£
¡¡¡¡Ìرð¸ÐлMatthew N. Dodd, Warner Losh, Bill Paul, Doug Rabson, Mike Smith, Peter Wemm and Scott Long.
¡¡¡¡±¾ÕÂÏêϸ½âÊÍÁËNewbusÉ豸¿ò¼Ü¡£
¡¡¡¡É豸Çý¶¯³ÌÐòÊÇÈí¼þ×é¼þ£¬ËüÔÚÄں˹ØÓÚÍâΧÉ豸£¨ÀýÈ磬´ÅÅÌ¡¢ÍøÂç ÊÊÅ俨£©µÄͨÓÃÊÓͼºÍÍâΧÉ豸µÄʵ¼ÊʵÏÖÖ®¼äÌṩÁ˽ӿڡ£ É豸Çý¶¯³ÌÐò½Ó¿Ú(DDI)ÊÇÄÚºËÓëÉ豸Çý¶¯³ÌÐò×é¼þ Ö®¼ä¶¨ÒåµÄ½Ó¿Ú¡£
¡¡¡¡ÔÚUNIXÄǸöʱ´ú£¬FreeBSDÒ²´ÓÖÐÑÓÐø¶øÀ´£¬¶¨ÒåÁËËÄÖÖÀàÐ굀 É豸£º
¿éÉ豸Çý¶¯³ÌÐò
×Ö·ûÉ豸Çý¶¯³ÌÐò
ÍøÂçÉ豸Çý¶¯³ÌÐò
αÉ豸Çý¶¯³ÌÐò
¡¡¡¡¿éÉ豸ÒÔʹÓù̶¨´óСµÄ[Êý¾Ý]¿éµÄ·½Ê½ÔËÐС£ ÕâÖÖÀàÐ͵ÄÇý¶¯³ÌÐòÒÀÀµËùνµÄ »º³åÇø»º´æ(buffer cache)£¬ÆäÄ¿µÄ ÊÇÔÚÄÚ´æÖеÄרÓÃÇøÓò»º´æ·ÃÎʹýµÄÊý¾Ý¿é¡£ÕâÖÖ»º³åÇø»º´æ³£³£»ùÓÚºǫ́д (write-behind)£¬ÕâÒâζ×ÅÊý¾ÝÔÚÄÚ´æÖб»Ð޸ĺ󣬵±ÏµÍ³½øÐÐÆäÖÜÆÚÐÔ ´ÅÅÌË¢ÐÂʱ²Å»á±»Í¬²½µ½´ÅÅÌ£¬´Ó¶øÓÅ»¯Ð´²Ù×÷¡£
¡¡¡¡NewbusʵÏÖÁËÒ»ÖÖ»ùÓÚ³éÏó²ãµÄÐÂÐÍ×ÜÏ߽ṹ£¬ ¿ÉÒÔÔÚFreeBSD 3.0Öп´µ½ÕâÖÖ×ÜÏ߽ṹµÄ½éÉÜ£¬µ±Ê±AlphaµÄÒÆÖ²±»µ¼Èëµ½ ´úÂëÊ÷ÖС£Ö±µ½4.0Ëü²Å³ÉΪÉ豸Çý¶¯³ÌÐòʹÓõÄĬÈÏϵͳ¡£ÆäÄ¿µÄÊÇΪÖ÷»ú ϵͳÌṩ¸ø²Ù×÷ϵͳµÄ¸÷ÖÖ×ÜÏߺÍÉ豸µÄ»¥Á¬Ìṩ¸ü¼Ó ÃæÏò¶ÔÏóµÄ·½·¨¡£
¡¡¡¡ÆäÖ÷ÒªÌØÐÔ°üÀ¨£º
¶¯Ì¬Á¬½Ó
Çý¶¯³ÌÐòÈÝÒ×Ä£¿é»¯
α×ÜÏß
¡¡¡¡×îÏÔÖøµÄ¸Ä±äÖ®Ò»ÊÇ´ÓÆ½ÃæºÍÌØÊâϵͳÑݱäΪÉ豸Ê÷²¼¾Ö¡£
¡¡¡¡¶¥²ãפÁôµÄÊÇ¡°¸ù¡±É豸£¬Ëü×÷Ϊ ¸¸É豸£¬ËùÓÐÆäËûÉ豸¹Ò½ÓÔÚËüÉÏÃæ¡£¶ÔÓÚÿ¸ö½á¹¹£¬Í¨³£¡°¸ù¡± Ö»Óе¥¸öº¢×Ó£¬ÆäÉÏÁ¬½Ó×ÅÖîÈçhost-to-PCIÇÅ µÈ¶«Î÷¡£¶ÔÓÚx86£¬ÕâÖÖ¡°¸ù¡±É豸Ϊ ¡°nexus¡±É豸£¬¶ÔÓÚAlpha£¬AlphaµÄ¸÷ÖÖ ²»Í¬ÐͺÅÓв»Í¬µÄ¶¥²ãÉ豸£¬¶ÔÓ¦²»Í¬µÄÓ²¼þоƬ×飬°üÀ¨ lca£¬apecs£¬ ciaºÍtsunami¡£
¡¡¡¡NewbusÉÏÏÂÎÄÖеÄÉ豸±íʾϵͳÖеĵ¥¸öÓ²¼þʵÌå¡£ÀýÈ磬ÿ¸öPCIÉ豸±» ±íʾΪһ¸öNewbusÉ豸¡£ÏµÍ³ÖеÄÈκÎÉ豸¿ÉÒÔÓк¢×Ó£»Óк¢×ÓµÄÉ豸ͨ³£±» ³ÆÎª¡°bus¡±¡£ÏµÍ³Öг£ÓÃ×ÜÏßµÄÀý×Ó¾ÍÊÇ ISAºÍPCI£¬ËûÃǸ÷×Ô¹ÜÀíÁ¬½Óµ½ISAºÍPCI×ÜÏßÉϵÄÉ豸ÁÐ±í¡£
¡¡¡¡Í¨³££¬²»Í¬ÀàÐ͵Ä×ÜÏßÖ®¼äµÄÁ¬½Ó±»±íʾΪ ¡°ÇÅ¡±É豸£¬ËüµÄº¢×Ó¾ÍÊÇËüËùÁ¬½ÓµÄ ×ÜÏß¡£Ò»¸öÀý×Ó¾ÍÊÇPCI-to-PCIÇÅ£¬ËüÔÚ¸¸PCI×ÜÏßÉϱ» ±íʾΪpcibN£¬¶øÓÃËüµÄº¢×Ó pciN±íʾÁ¬½ÓÔÚËüÉÏÃæµÄ ×ÜÏß¡£ÕâÖÖ²¼¾Ö¼ò»¯ÁËPCI×ÜÏßÊ÷µÄʵÏÖ£¬ÔÊÐí¹«¹²´úÂëͬʱÓÃÓÚ¶¥²ãºÍÇÅ½ÓµÄ ×ÜÏß¡£
¡¡¡¡Newbus½á¹¹ÖеÄÿ¸öÉ豸ÇëÇóËüµÄ¸¸É豸À´ÎªÆäÓ³Éä×ÊÔ´¡£¸¸É豸½Ó×ÅÇëÇó ËüµÄ¸¸É豸£¬Ö±µ½µ½´ïnexus¡£Òò´Ë£¬»ù±¾ÉÏnexusÊÇNewbusϵͳÖÐΨһ֪µÀËùÓÐ ×ÊÔ´µÄ²¿·Ö¡£
Ìáʾ: ISAÉ豸¿ÉÄÜÏëÔÚ0x230Ó³ÉäÆäIO¶Ë¿Ú£¬Òò´ËËüÏòÆä ¸¸É豸ÇëÇó£¬ÕâÖÖÇé¿öÏÂÊÇISA×ÜÏß¡£ISA×ÜÏß½«Ëü½»¸øPCI-to-ISAÇÅ£¬PCI-to-ISA ÇŽÓ×ÅÇëÇóPCI×ÜÏߣ¬PCI×ÜÏßµ½´ïhost-to-PCIÇÅ£¬×îºóµ½´ïnexus¡£ÕâÖÖÏòÉÏ ¹ý¶ÉµÄÓÅÃÀÖ®´¦ÔÚÓÚ¿ÉÒÔÓпռäÀ´±ä»»ÇëÇó¡£¶Ô0x230IO¶Ë¿Ú µÄÇëÇóÔÚMIPS»úÆ÷ÉÏ¿ÉÒÔ±»PCIÇűä³É 0xb0000230´¦µÄÄÚ´æÓ³Éä¡£
¡¡¡¡×ÊÔ´·ÖÅä¿ÉÒÔÔÚÉ豸Ê÷µÄÈκεط½¼ÓÒÔ¿ØÖÆ¡£ÀýÈ磬ÔںܶàAlphaƽ̨ÉÏ£¬ ISAÖжÏÓëPCIÖжÏÊǵ¥¶À¹ÜÀíµÄ£¬¶ÔISAÖжϵÄ×ÊÔ´·ÖÅäÊÇÓÉAlphaµÄISA×ÜÏßÉ豸 ¹ÜÀíµÄ¡£ÔÚIA-32ÉÏ£¬ISAºÍPCIÖж϶¼Óɶ¥²ãµÄnexusÉ豸¹ÜÀí¡£¶ÔÓÚÁ½ÖÖÒÆÖ²£¬ ÄÚ´æºÍ¶Ë¿ÚµØÖ·¿Õ¼äÓɵ¥¸öʵÌå¹ÜÀí - ÔÚIA-32ÉÏÊÇnexus£¬ÔÚAlpha£¨ÀýÈ磬CIA »òtsunami£©ÉÏÊÇÏà¹ØµÄоƬ×éÇý¶¯³ÌÐò¡£
¡¡¡¡ÎªÁ˹淶»¯¶ÔÄÚ´æºÍ¶Ë¿ÚÓ³Éä×ÊÔ´µÄ·ÃÎÊ£¬NewbusÕûºÏÁËNetBSDµÄ bus_space API¡£ËûÃÇÌṩÁ˵¥Ò»µÄAPIÀ´´úÌæinb/outb ºÍÖ±½ÓÄÚ´æ¶Áд¡£ÕâÑù×öµÄÓÅÊÆÔÚÓÚµ¥¸öÇý¶¯³ÌÐò¾Í¿ÉÒÔʹÓÃÄÚ´æÓ³Éä¼Ä´æÆ÷ »ò¶Ë¿ÚÓ³Éä¼Ä´æÆ÷£¨ÓÐЩӲ¼þÖ§³ÖÁ½Õߣ©¡£
¡¡¡¡ÕâÖÖÖ§³Ö±»ºÏ²¢µ½ÁË×ÊÔ´·ÖÅä»úÖÆÖС£·ÖÅä×ÊԴʱ£¬Çý¶¯³ÌÐò¿ÉÒÔ´Ó×ÊÔ´
ÖмìÈ¡¹ØÁªµÄbus_space_tag_t
ºÍ bus_space_handle_t
¡£
¡¡¡¡NewbusÒ²ÔÊÐíÔÚרÓÃÓÚ´ËÄ¿µÄµÄÎļþÖж¨Òå½Ó¿Ú·½·¨¡£ÕâЩÊÇ .mÎļþ£¬¿ÉÒÔÔÚsrc/sys Ŀ¼Ê÷ÖÐÕÒµ½¡£
¡¡¡¡NewbusϵͳµÄºËÐÄÊÇ¿ÉÀ©Õ¹µÄ¡°»ùÓÚ¶ÔÏó±à³Ì(object-based programming)¡±µÄÄ£ÐÍ¡£ÏµÍ³ÖеÄÿ¸öÉ豸¾ßÓÐËüËùÖ§³ÖµÄÒ»¸ö·½·¨±í¡£ ϵͳºÍÆäËûÉ豸ʹÓÃÕâЩ·½·¨À´¿ØÖÆÉ豸²¢ÇëÇó·þÎñ¡£É豸ËùÖ§³ÖµÄ²»Í¬·½·¨ ±»¶¨ÒåΪ¶à¸ö¡°½Ó¿Ú¡±¡£¡°½Ó¿Ú¡±Ö»ÊÇ É豸ʵÏÖµÄÒ»×éÏà¹ØµÄ·½·¨¡£
¡¡¡¡ÔÚNewbusϵͳÖУ¬É豸·½·¨ÊÇͨ¹ýϵͳÖеĸ÷ÖÖÉ豸Çý¶¯³ÌÐòÌṩµÄ¡£µ± ×Ô¶¯ÅäÖÃ(auto-configuration)ÆÚ¼äÉ豸±»Á¬½Ó(attach) µ½Çý¶¯³ÌÐò£¬ËüʹÓÃÇý¶¯³ÌÐòÉùÃ÷µÄ·½·¨±í¡£ÒÔºóÉ豸¿ÉÒÔ´ÓÆäÇý¶¯³ÌÐò ·ÖÀë(detach)£¬²¢ ÖØÐÂÁ¬½Ó(re-attach)µ½¾ßÓÐз½·¨±íµÄÐÂÇý¶¯³ÌÐò¡£Õâ¾Í ÔÊÐíÇý¶¯³ÌÐòµÄ¶¯Ì¬Ìæ»»£¬¶ø¶¯Ì¬Ìæ»»¶ÔÓÚÇý¶¯³ÌÐòµÄ¿ª·¢·Ç³£ÓÐÓá£
¡¡¡¡½Ó¿Úͨ¹ýÓëÎļþϵͳÖÐÓÃÓÚ¶¨Òåvnode²Ù×÷µÄÓïÑÔÏàËÆµÄ½Ó¿Ú¶¨ÒåÓïÑÔÀ´ ÃèÊö¡£½Ó¿Ú±»±£´æÔÚ·½·¨ÎļþÖУ¨Í¨³£ÃüÃûΪfoo_if.m£©¡£
Àý 14-1. NewbusµÄ·½·¨
# Foo ×Óϵͳ/Çý¶¯³ÌÐò£¨×¢ÊÍ...£© INTERFACE foo METHOD int doit { device_t dev; }; # Èç¹ûûÓÐͨ¹ýDEVMETHOD()Ìṩһ¸ö·½·¨£¬ÔòDEFAULTΪ½«»á±»Ê¹Óõķ½·¨ METHOD void doit_to_child { device_t dev; driver_t child; } DEFAULT doit_generic_to_child;
¡¡¡¡µ±½Ó¿Ú±»±àÒëºó£¬Ëü²úÉúÒ»¸öÍ·Îļþ ¡°foo_if.h¡±£¬ÆäÖаüº¬º¯ÊýÉùÃ÷£º
int FOO_DOIT(device_t dev); int FOO_DOIT_TO_CHILD(device_t dev, device_t child);
¡¡¡¡°éËæ×Ô¶¯²úÉúµÄÍ·Îļþ£¬Ò²»á´´½¨Ò»¸öÔ´Îļþ ¡°foo_if.c¡±£»ÆäÖаüº¬Ò»Ð©º¯ÊýµÄʵÏÖ£¬ ÕâЩº¯ÊýÓÃÓÚÔÚ¶ÔÏó·½·¨±íÖвéÕÒÏà¹Øº¯ÊýµÄλÖò¢µ÷ÓÃÄǸöº¯Êý¡£
¡¡¡¡ÏµÍ³¶¨ÒåÁËÁ½¸öÖ÷Òª½Ó¿Ú¡£µÚÒ»¸ö»ù±¾½Ó¿Ú±»³ÆÎª ¡°É豸(device)¡±£¬²¢°üÀ¨ÓëËùÓÐÉ豸Ïà¹Ø µÄ·½·¨¡£¡°É豸(device)¡±½Ó¿ÚÖеķ½·¨ °üÀ¨¡°Ì½²â(probe)¡±£¬ ¡°Á¬½Ó(attach)¡±ºÍ ¡°·ÖÀë(detach)¡±£¬ËûÃÇÓÃÀ´¿ØÖÆÓ²¼þµÄÕì²â£¬ ÒÔ¼°¡°¹Ø±Õ(shutdown)¡±£¬ ¡°¹ÒÆð(suspend)¡±ºÍ ¡°»Ö¸´(resume)¡±£¬ËûÃÇÓÃÓڹؼüʼþ֪ͨ¡£
¡¡¡¡ÁíÒ»¸ö£¬¸ü¼Ó¸´ÔÓ½Ó¿ÚÊÇ¡°bus¡±¡£ ´Ë½Ó¿Ú°üº¬µÄ·½·¨ÊÊÓÃÓÚ´øÓк¢×ÓµÄÉ豸£¬°üÀ¨·ÃÎÊ×ÜÏßÌØ¶¨µÄÿÉ豸ÐÅÏ¢ [2]£¬Ê¼þ֪ͨ £¨child_detached£¬ driver_added£©ºÍÏìÓ¦¹ÜÀí £¨alloc_resource£¬ activate_resource£¬ deactivate_resource£¬ release_resource£©¡£
¡¡¡¡¡°bus¡±½Ó¿ÚÖеĺܶ෽·¨Îª×ÜÏßÉ豸µÄijЩº¢×ÓÖ´ÐзþÎñ¡£ ÕâЩ·½·¨Í¨³£Ê¹ÓÃǰÁ½¸ö²ÎÁ¿Ö¸¶¨Ìṩ·þÎñµÄ×ÜÏߺÍÇëÇó·þÎñµÄ×ÓÉ豸¡£ÎªÁË ¼ò»¯É豸Çý¶¯³ÌÐò´úÂ룬ÕâЩ·½·¨Öеĺܶ඼ÓзÃÎÊÕß(accessor)º¯Êý£¬·ÃÎÊÕß º¯ÊýÓÃÀ´²éÕÒ¸¸É豸²¢µ÷Óø¸É豸Éϵķ½·¨¡£ÀýÈ磬·½·¨ BUS_TEARDOWN_INTR(device_t dev, device_t child, ...) ¿ÉÒÔʹÓú¯Êý bus_teardown_intr(device_t child, ...)À´µ÷Óá£
¡¡¡¡ÏµÍ³ÖеÄijЩ×ÜÏßÀàÐÍÌṩÁ˶îÍâ½Ó¿ÚÒÔÌṩ¶Ô×ÜÏßÌØ¶¨¹¦ÄܵķÃÎÊ¡£ ÀýÈ磬PCI×ÜÏßÇý¶¯³ÌÐò¶¨ÒåÁË¡°pci¡±½Ó¿Ú£¬´Ë½Ó¿ÚÓÐÁ½¸ö·½·¨ read_configºÍ write_config£¬ÓÃÓÚ·ÃÎÊPCIÉ豸 µÄÅäÖüĴæÆ÷¡£
¡¡¡¡ÓÉÓÚNewbus API·Ç³£ÅӴ󣬱¾½ÚŬÁ¦½«ËüÎĵµ»¯¡£±¾ÎĵµµÄÏÂÒ»°æ±¾»á ´øÀ´¸ü¶àÐÅÏ¢¡£
¡¡¡¡src/sys/[arch]/[arch] - ÌØ¶¨»úÆ÷½á¹¹µÄ Äں˴úÂëλÓÚÕâ¸öĿ¼¡£ÀýÈçi386½á¹¹»ò SPARC64½á¹¹¡£
¡¡¡¡src/sys/dev/[bus] - Ö§³ÖÌØ¶¨ [bus]µÄÉ豸λÓÚÕâ¸öĿ¼¡£
¡¡¡¡src/sys/dev/pci - PCI×ÜÏßÖ§³Ö´úÂëλÓÚ Õâ¸öĿ¼¡£
¡¡¡¡src/sys/[isa|pci] - PCI/ISAÉ豸Çý¶¯³ÌÐò λÓÚÕâ¸öĿ¼¡£FreeBSD4.0°æ±¾ÖУ¬PCI/ISAÖ§³Ö´úÂë ¹ýÈ¥´æÔÚÓÚÕâ¸öĿ¼ÖС£
¡¡¡¡devclass_t - ÕâÊÇÖ¸Ïò struct devclassµÄÖ¸ÕëµÄÀàÐͶ¨Òå¡£
¡¡¡¡device_method_t - Óë kobj_method_tÏàͬ£¨²Î¿´ src/sys/kobj.h£©¡£
¡¡¡¡device_t - ÕâÊÇÖ¸Ïò struct deviceµÄÖ¸ÕëµÄÀàÐͶ¨Òå¡£ device_t ±íʾϵͳÖеÄÉ豸¡£ËüÊÇÄں˶ÔÏó¡£ ÊµÏÖϸ½Ú²Î¿´src/sys/sys/bus_private.h¡£
¡¡¡¡driver_t - ÕâÊÇÒ»¸öÀàÐͶ¨Ò壬ËüÒýÓà struct driver¡£ driver½á¹¹ÊÇÒ»Àà device(É豸)Äں˶ÔÏó£»ËüÒ²±£´æ×ÅÇý¶¯³ÌÐòµÄ˽ÓÐÊý¾Ý¡£
¡¡¡¡device_state_tÊÇÒ»¸öö¾ÙÀàÐÍ£¬¼´ device_state¡£Ëü°üº¬NewbusÉ豸ÔÚ×Ô¶¯ÅäÖÃǰºó ¿ÉÄܵÄ״̬¡£
¡¡¡¡FreeBSDÉùÒô×ÓϵͳÇåÎúµØ½«Í¨ÓÃÉùÒô´¦ÀíÎÊÌâÓëÉè±¸ÌØ¶¨µÄÎÊÌâ·ÖÀë ¿ªÀ´¡£ÕâʹµÃ¸üÈÝÒ×¼ÓÈë¶ÔÐÂÉ豸µÄÖ§³Ö¡£
¡¡¡¡ pcm(4)¿ò¼ÜÊÇÉùÒô×ÓϵͳµÄÖÐÐIJ¿·Ö¡£ËüÖ÷ҪʵÏÖÏÂÃæµÄ×é¼þ£º
Ò»¸öµ½Êý×Ö»¯ÉùÒôºÍ»ìÒôÆ÷º¯ÊýµÄϵͳµ÷Óýӿڣ¨read, write, ioctls£©¡£ioctlÃüÁºÏ¼æÈÝÀϵÄOSS »òVoxware½Ó¿Ú£¬ÔÊÐíÒ»°ã¶àýÌåÓ¦ÓóÌÐò ²»¼ÓÐ޸ĵØÒÆÖ²¡£
´¦ÀíÉùÒôÊý¾ÝµÄ¹«¹²´úÂ루¸ñʽת»»£¬ÐéÄâͨµÀ£©¡£
Ò»¸öͳһµÄÈí¼þ½Ó¿Ú£¬ÓëÓ²¼þÌØ¶¨µÄÒôƵ½Ó¿ÚÄ£¿é½Ó¿Ú
¶ÔijЩͨÓÃÓ²¼þ½Ó¿Ú£¨ac97£©»ò¹²ÏíµÄÓ²¼þÌØ¶¨´úÂë £¨ÀýÈ磺ISA DMAÀý³Ì£©µÄ¶îÍâÖ§³Ö¡£
¡¡¡¡¶ÔÌØ¶¨Éù¿¨µÄÖ§³ÖÊÇͨ¹ýÓ²¼þÌØ¶¨µÄÇý¶¯³ÌÐòÀ´ÊµÏֵģ¬ÕâЩÇý¶¯³ÌÐò ÌṩͨµÀºÍ»ìÒôÆ÷½Ó¿Ú£¬²åÈ뵽ͨÓÃpcm´úÂëÖС£
¡¡¡¡±¾ÕÂÖУ¬ÊõÓïpcm½«Ö¸ÉùÒôÇý¶¯³ÌÐòµÄ ÖÐÐÄ£¬Í¨Óò¿·Ö£¬ÕâÊǶԱÈÓ²¼þÌØ¶¨µÄÄ£¿é¶øÑԵġ£
¡¡¡¡Ô¤ÆÚµÄÇý¶¯³ÌÐò±àдÕßµ±È»Ï£Íû´ÓÏÖÓÐÄ£¿é¿ªÊ¼£¬²¢Ê¹ÓÃÄÇЩ´úÂë×÷Ϊ ×îÖղο¼¡£µ«ÊÇ£¬ÓÉÓÚÉùÒô´úÂëÊ®·Ö¼ò½àƯÁÁ£¬ÕâÒ²»ù±¾ÉÏÃâ³ýÁË×¢ÊÍ¡£ ±¾ÎĵµÊÔͼ¸ø³ö¿ò¼Ü½Ó¿ÚµÄÒ»¸ö¸ÅÀÀ£¬²¢»Ø´ð¸ÄдÏÖÓдúÂëʱ¿ÉÄܳöÏÖµÄ Ò»Ð©ÎÊÌâ¡£
¡¡¡¡×÷ΪÁíÍâµÄ;¾¶£¬»òÕß˵³ýÁË´ÓÒ»¸ö¿É¹¤×÷µÄ·¶Àý¿ªÊ¼µÄ°ì·¨Ö®Í⣬ Äã¿ÉÒÔ´Ó http://people.FreeBSD.org/~cg/template.cÕÒµ½Ò»¸ö×¢Ê͹ýµÄ Çý¶¯³ÌÐòÄ£°å¡£
¡¡¡¡³ý/usr/src/sys/sys/soundcard.hÖеĹ«¹² ioctl½Ó¿Ú¶¨ÒåÍ⣬ËùÓеÄÏà¹Ø´úÂ뵱ǰ(FreeBSD 4.4)λÓÚ /usr/src/sys/dev/sound/¡£
¡¡¡¡ÔÚ/usr/src/sys/dev/sound/ÏÂÃæ£¬ pcm/Ŀ¼Öб£´æ×ÅÖÐÐÄ´úÂ룬 ¶øisa/ºÍpci/Ŀ¼ÖÐÓÐ ISAºÍPCI°åµÄÇý¶¯³ÌÐò¡£
¡¡¡¡ÉùÒôÇý¶¯³ÌÐòʹÓÃÓëÈκÎÓ²¼þÇý¶¯³ÌÐòÄ£¿éÏàͬµÄ·½·¨Ì½²âºÍÁ¬½Ó£¨É豸£©¡£ Äã¿ÉÄÜÏ£Íûä¯ÀÀÒ»ÏÂÊÖ²áÖÐISA»òPCIÕ½ڵÄÄÚÈÝÀ´»ñÈ¡¸ü¶àÐÅÏ¢¡£
¡¡¡¡È»¶ø£¬ÉùÒôÇý¶¯³ÌÐòÔÚijЩ·½ÃæÓÖÓÐЩ²»Í¬£º
ËûÃǽ«×Ô¼ºÉùÃ÷ΪpcmÀàÉ豸£¬´øÓÐÒ»¸ö
É豸˽Óнṹstruct snddev_info
£º
static driver_t xxx_driver = { "pcm", xxx_methods, sizeof(struct snddev_info) }; DRIVER_MODULE(snd_xxxpci, pci, xxx_driver, pcm_devclass, 0, 0); MODULE_DEPEND(snd_xxxpci, snd_pcm, PCM_MINVER, PCM_PREFVER,PCM_MAXVER);
´ó¶àÊýÉùÒôÇý¶¯³ÌÐòÐèÒª´æ´¢¹ØÓÚÆäÉ豸µÄ¸½¼Ó˽ÓÐÐÅÏ¢¡£Ë½ÓÐÊý¾Ý
½á¹¹Í¨³£ÔÚÁ¬½ÓÀý³ÌÖзÖÅä¡£ÆäµØÖ·Í¨¹ýµ÷Óà pcm_register()
ºÍ
mixer_init()
´«µÝ¸ø pcm¡£ºóÃæpcm
½«´ËµØÖ·×÷Ϊµ÷ÓÃÉùÒôÇý¶¯³ÌÐò½Ó¿ÚʱµÄ²ÎÊý´«µÝ»ØÀ´¡£
ÉùÒôÇý¶¯³ÌÐòµÄÁ¬½ÓÀý³ÌÓ¦µ±Í¨¹ýµ÷ÓÃmixer_init()
ÏòpcmÉùÃ÷ËüµÄMIXER»òAC97
½Ó¿Ú¡£¶ÔÓÚMIXER½Ó¿Ú£¬Õâ»á½Ó×ÅÒýÆðµ÷Óà xxxmixer_init()
¡£
ÉùÒôÇý¶¯³ÌÐòµÄÁ¬½ÓÀý³Ìͨ¹ýµ÷Óà pcm_register(dev, sc, nplay,
nrec)
ÏòpcmÉùÃ÷ÆäͨÓÃCHANNELÅäÖã¬ÆäÖÐ sc
ÊÇÉ豸Êý¾Ý½á¹¹µÄµØÖ·£¬ ÔÚpcmÒÔºóµÄµ÷ÓÃÖн«»áÓõ½Ëü£¬ nplay
ºÍnrec
ÊDz¥·ÅºÍ¼Òô ͨµÀµÄÊýÄ¿¡£
ÉùÒôÇý¶¯³ÌÐòµÄÁ¬½ÓÀý³Ìͨ¹ýµ÷Óà pcm_addchan()
ÉùÃ÷ËüµÄÿ¸öͨµÀ¶ÔÏó¡£Õâ»áÔÚ pcmÖн¨Á¢ÆðͨµÀºÏ³É£¬²¢½Ó×Å»áÒýÆðµ÷Óà xxxchannel_init()
£¨Òë×¢£ºÇë²Î¿¼ÔÎÄ£©¡£
ÉùÒôÇý¶¯³ÌÐòµÄ·ÖÀëÀý³ÌÔÚÊÍ·ÅÆä×ÊԴ֮ǰӦµ±µ÷Óà pcm_unregister()
¡£
¡¡¡¡ÓÐÁ½ÖÖ¿ÉÄܵķ½·¨À´´¦Àí·ÇPnPÉ豸£º
ʹÓÃdevice_identify()
·½·¨ £¨·¶Àý£ºsound/isa/es1888.c£©¡£ device_identify()
·½·¨ÔÚÒÑÖªµØÖ·Ì½²âÓ²¼þ£¬
Èç¹û·¢ÏÖÖ§³ÖµÄÉ豸¾Í»á´´½¨Ò»¸öеÄpcmÉ豸£¬Õâ¸öpcmÉ豸½Ó×Å »á±»´«µÝµ½probe/attach¡£
ʹÓö¨ÖÆÄÚºËÅäÖõķ½·¨£¬ÎªpcmÉ豸ÉèÖÃÊʵ±µÄhints£¨·¶Àý£º sound/isa/mss.c£©¡£
¡¡¡¡pcmÇý¶¯³ÌÐòÓ¦µ±ÊµÏÖ device_suspend
£¬ device_resume
ºÍ
device_shutdown
Àý³Ì£¬ÕâÑùµçÔ´¹ÜÀíºÍÄ£¿éÐ¶ÔØ¾ÍÄÜ
ÕýÈ·µØ·¢»Ó×÷Óá£
¡¡¡¡pcmºËÐÄÓëÉùÒôÇý¶¯³ÌÐòÖ®¼äµÄ½Ó¿ÚÒÔÊõÓï Äں˶ÔÏóµÄ½Ð·¨À´¶¨Òå¡£
¡¡¡¡ÉùÒôÇý¶¯³ÌÐòͨ³£ÌṩÁ½ÖÖÖ÷ÒªµÄ½Ó¿Ú£º CHANNELÒÔ¼° MIXER»òAC97¡£
¡¡¡¡AC97ÊÇÒ»¸öºÜСµÄÓ²¼þ·ÃÎÊ£¨¼Ä´æÆ÷¶Á/д£© ½Ó¿Ú£¬ÓÉÇý¶¯³ÌÐòΪ´øAC97±àÂë½âÂëÆ÷µÄÓ²¼þÀ´ÊµÏÖ¡£ÕâÖÖÇé¿öÏ£¬Êµ¼ÊµÄ MIXER½Ó¿ÚÓÉpcmÖй²ÏíµÄAC97´úÂëÌṩ¡£
¡¡¡¡ÉùÒôÇý¶¯³ÌÐòͨ³£ÓÃÒ»¸ö˽ÓÐÊý¾Ý½á¹¹À´ÃèÊöËûÃǵÄÉ豸£¬Çý¶¯ ³ÌÐòËùÖ§³ÖµÄ²¥·ÅºÍ¼ÒôÊý¾ÝͨµÀ¸÷ÓÐÒ»¸ö¡£
¡¡¡¡¶ÔÓÚËùÓеÄCHANNEL½Ó¿Úº¯Êý£¬µÚÒ»¸ö²ÎÊýÊÇÒ»¸ö²»Í¸Ã÷µÄÖ¸Õë¡£
¡¡¡¡µÚ¶þ¸ö²ÎÊýÊÇÖ¸Ïò˽ÓеÄͨµÀÊý¾Ý½á¹¹µÄÖ¸Õ룬 channel_init()
ÊǸöÀýÍ⣬ËüµÄÖ¸ÕëÖ¸Ïò˽ÓÐ É豸½á¹¹£¨²¢·µ»ØÓÉpcmÒÔºóʹÓõÄͨµÀÖ¸Õ룩¡£
¡¡¡¡¶ÔÓÚÉùÒôÊý¾Ý´«Ê䣬pcmºËÐÄÓëÉùÒôÇý¶¯
³ÌÐòÊÇͨ¹ýÒ»¸öÓÉstruct snd_dbuf
ÃèÊöµÄ
¹²ÏíÄÚ´æÇøÓò½øÐÐͨÐŵġ£
¡¡¡¡struct snd_dbuf
ÊÇ pcm˽Óеģ¬ÉùÒôÇý¶¯³ÌÐòͨ¹ýµ÷Ó÷ÃÎÊÕß º¯Êý£¨sndbuf_getxxx()
£©À´»ñµÃ¸ÐÐËȤµÄÖµ¡£
¡¡¡¡¹²ÏíÄÚ´æÇøÓòµÄ´óСµÈÓÚ sndbuf_getsize()
£¬²¢±»·Ö¸îΪ´óС¹Ì¶¨£¬ÇÒµÈÓÚ sndbuf_getblksz()
×ֽڵĺܶà¿é¡£
¡¡¡¡µ±²¥·Åʱ£¬³£¹æµÄ´«Êä»úÖÆÈçÏ£¨½«Òâ˼·´¹ýÀ´¾ÍÊǼÒô£©£º
pcm¿ªÊ¼Ê±Ìî³ä»º³åÇø£¬È»ºóÒÔ
²ÎÊýPCMTRIG_STARTµ÷ÓÃÉùÒôÇý¶¯³ÌÐòµÄ xxxchannel_trigger()
¡£
ÉùÒôÇý¶¯³ÌÐò½Ó×Ű²ÅÅÒÔ sndbuf_getblksz()
×Ö½Ú´óСΪ¿é£¬Öظ´½« Õû¸öÄÚ´æÇøÓò£¨sndbuf_getbuf()
£¬ sndbuf_getsize()
£©´«Êäµ½É豸¡£¶ÔÓÚÿ¸ö ´«Êä¿é»Øµ÷pcmº¯Êý chn_intr()
£¨Õâͨ³£ÔÚÖжÏʱ¼ä·¢Éú£©¡£
chn_intr()
°²ÅŽ«ÐÂÊý¾Ý¿½±´µ½ÄÇЩ
Êý¾ÝÒÑ´«Êäµ½É豸£¨ÏÖÔÚ¿ÕÏУ©µÄÇøÓò£¬²¢¶Ô snd_dbuf
½á¹¹½øÐÐÊʵ±µÄ¸üС£
¡¡¡¡µ÷ÓÃxxxchannel_init()
À´³õʼ»¯Ã¿¸ö²¥·Å
ºÍ¼ÒôͨµÀ¡£Õâ¸öµ÷ÓôÓÉùÒôÇý¶¯³ÌÐòµÄÁ¬½ÓÀý³ÌÖз¢Æð¡££¨²Î¿´ ̽²âºÍÁ¬½ÓÒ»½Ú£©¡£
static void * xxxchannel_init(kobj_t obj, void *data, struct snd_dbuf *b, struct pcm_channel *c, int dir){ struct xxx_info *sc = data; struct xxx_chinfo *ch; ... return ch;
}
b
ΪͨµÀ struct
snd_dbuf
µÄµØÖ·¡£ËüÓ¦µ±ÔÚ º¯ÊýÖÐͨ¹ýµ÷ÓÃsndbuf_alloc()
À´³õʼ»¯¡£
ËùÓõĻº³åÇø´óСͨ³£ÊÇÉ豸'µäÐÍ'´«Êä´óСµÄÒ»¸ö½ÏСµÄ±¶Êý¡£c
Ϊ pcmͨµÀ¿ØÖƽṹµÄÖ¸Õë¡£ÕâÊǸö²»Í¸Ã÷
Ö¸Õë¡£º¯ÊýÓ¦µ±½«Ëü±£´æµ½¾Ö²¿Í¨µÀ½á¹¹ÖУ¬ÔÚºóÃæµ÷Óà pcmº¯Êý£¨ÀýÈ磺 chn_intr(c)
£©Ê±»áʹÓÃËü¡£
dir
ָʾͨµÀ·½Ïò £¨PCMDIR_PLAY»ò
PCMDIR_REC£©¡£
¡¡¡¡xxxchannel_setformat()
Ó¦µ±°´Ìض¨Í¨µÀ£¬
ÌØ¶¨ÉùÒô¸ñʽÉèÖÃÓ²¼þ¡£
static int xxxchannel_setformat(kobj_t obj, void *data, u_int32_t format){ struct xxx_chinfo *ch = data; ... return 0; }
¡¡¡¡xxxchannel_setspeed()
°´Ö¸¶¨µÄÈ¡ÑùËÙ¶È
ÉèÖÃͨµÀÓ²¼þ£¬²¢·µ»Ø·µ»Ø¿ÉÄܵ÷Õû¹ýµÄËÙ¶È¡£
static int xxxchannel_setspeed(kobj_t obj, void *data, u_int32_t speed) { struct xxx_chinfo *ch = data; ... return speed; }
¡¡¡¡xxxchannel_setblocksize()
ÉèÖÿé´óС£¬
ÕâÊÇpcmÓëÉùÒôÇý¶¯³ÌÐò£¬ÒÔ¼°ÉùÒôÇý¶¯
³ÌÐòÓëÉ豸֮¼äµÄ´«Ê䵥λµÄ´óС¡£´«ÊäÆÚ¼ä£¬Ã¿´Î´«ÊäÕâÑù´óСµÄ
Êý¾Ýºó£¬ÉùÒôÇý¶¯³ÌÐò¶¼Ó¦µ±µ÷ÓÃpcmµÄ chn_intr()
¡£
¡¡¡¡´ó¶àÊýÇý¶¯³ÌÐòÖ»×¢ÒâÕâ¶ùµÄ¿é´óС£¬ÒòΪµ±Êµ¼Ê´«Ê俪ʼʱӦ¸Ã ʹÓÃÕâ¸öÖµ¡£
static int xxxchannel_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) { struct xxx_chinfo *ch = data; ... return blocksize;}
¡¡¡¡xxxchannel_trigger()
ÓÉ pcmÀ´¿ØÖÆÇý¶¯³ÌÐòÖеÄʵ¼Ê´«Êä²Ù×÷¡£
static int xxxchannel_trigger(kobj_t obj, void *data, int go){ struct xxx_chinfo *ch = data; ... return 0; }
go
¶¨Ò嵱ǰµ÷Óõ͝×÷¡£¿ÉÄܵÄֵΪ£ºPCMTRIG_START£ºÇý¶¯³ÌÐòÓ¦µ±
Æô¶¯´Ó/µ½Í¨µÀ»º³åÇøµÄÊý¾Ý´«Êä¡£Èç¹ûÐèÒª£¬Ó¦µ±Í¨¹ý sndbuf_getbuf()
ºÍ sndbuf_getsize()
¼ìÈ¡»º³åÇøµÄ »ùµØÖ·ºÍ´óС¡£
PCMTRIG_EMLDMAWR / PCMTRIG_EMLDMARD£º¸æËßÇý¶¯³ÌÐò£¬ ÊäÈë»òÊä³ö»º³åÇø¿ÉÄÜÒѱ»¸üйýÁË¡£´ó¶àÊýÇý¶¯³ÌÐòÖ»ÊÇ ºöÂÔÕâЩµ÷Óá£
PCMTRIG_STOP / PCMTRIG_ABORT£ºÇý¶¯³ÌÐòÓ¦µ±Í£Ö¹µ±Ç° µÄ´«Êä¡£
×¢Òâ: Èç¹ûÇý¶¯³ÌÐòʹÓÃISA DMA£¬ÔòÓ¦µ±ÔÚÉ豸ÉÏÖ´Ðж¯×÷ǰ µ÷ÓÃ
sndbuf_isadma()
£¬²¢´¦ÀíDMAоƬһ·½µÄ ÊÂÇé¡£
¡¡¡¡xxxchannel_getptr()
·µ»Ø´«Ê仺³åÇøÖÐ
µ±Ç°µÄ»º³å¡£Ëüͨ³£ÓÉchn_intr()
µ÷Ó㬶øÇÒ
ÕâÒ²ÊÇΪʲôpcmÖªµÀËüÓ¦µ±ÍùÄĶù´«ËÍ ÐÂÊý¾Ý¡£
¡¡¡¡µ÷ÓÃxxxchannel_free()
À´ÊÍ·ÅͨµÀ×ÊÔ´£¬
ÀýÈçµ±Çý¶¯³ÌÐòÐ¶ÔØÊ±£¬²¢ÇÒÈç¹ûͨµÀÊý¾Ý½á¹¹ÊǶ¯Ì¬·ÖÅäµÄ£¬»òÕß Èç¹û²»Ê¹ÓÃsndbuf_alloc()
½øÐлº³åÇø·ÖÅ䣬 ÔòÓ¦µ±ÊµÏÖÕâ¸öº¯Êý¡£
struct pcmchan_caps * xxxchannel_getcaps(kobj_t obj, void *data) { return &xxx_caps;}
¡¡¡¡channel_reset()
, channel_resetdone()
ºÍ channel_notify()
ÓÃÓÚÌØÊâÄ¿µÄ£¬Î´ÓëȨÍþÈËÊ¿ (Cameron Grant <cg@FreeBSD.org>
)½øÐÐ̽ÌÖ֮ǰ²»Ó¦µ±ÔÚÇý¶¯³ÌÐòÖÐʵÏÖËü¡£
¡¡¡¡²»ÔÞ³ÉʹÓÃchannel_setdir()
.
¡¡¡¡xxxmixer_init()
³õʼ»¯Ó²¼þ£¬²¢¸æËß pcmʲô»ìÒôÆ÷É豸¿ÉÓÃÀ´²¥·ÅºÍ¼Òô¡£
static int xxxmixer_init(struct snd_mixer *m) { struct xxx_info *sc = mix_getdevinfo(m); u_int32_t v; [³õʼ»¯Ó²¼þ] [Ϊ²¥·Å»ìÒôÆ÷ÉèÖÃvÖÐÊʵ±µÄλ]mix_setdevs(m, v); [Ϊ¼Òô»ìÒôÆ÷ÉèÖÃvÖÐÊʵ±µÄλ] mix_setrecdevs(m, v) return 0; }
¡¡¡¡»ìÒôÆ÷µÄ붨Òå¿ÉÒÔÔÚsoundcard.hÖÐ ÕÒµ½¡££¨SOUND_MASK_XXXÖµºÍ SOUND_MIXER_XXXÒÆÎ»£©¡£
¡¡¡¡xxxmixer_set()
Ϊ»ìÒôÆ÷É豸ÉèÖÃÒôÁ¿¼¶±ð (level)¡£
static int xxxmixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right){ struct sc_info *sc = mix_getdevinfo(m); [ÉèÖÃÒôÁ¿¼¶±ð(level)] return left | (right << 8);
}
¡¡¡¡xxxmixer_setrecsrc()
É趨¼ÒôÔ´É豸¡£
static int xxxmixer_setrecsrc(struct snd_mixer *m, u_int32_t src){ struct xxx_info *sc = mix_getdevinfo(m); [²é¿´srcÖеķÇÁãλ, ÉèÖÃÓ²¼þ] [¸üÐÂsrc·´Ó³Êµ¼Ê¶¯×÷] return src;
}
¡¡¡¡xxxmixer_uninit()
Ó¦µ±È·±£²»»á·¢³öÈκÎ
ÉùÒô£¬²¢ÇÒÈç¹û¿ÉÄÜÔòÓ¦µ±ÈûìÒôÆ÷Ó²¼þ¶Ïµç¡£
¡¡¡¡xxxmixer_reinit()
Ó¦µ±È·±£»ìÒôÆ÷Ó²¼þ
¼Óµç£¬²¢ÇÒ»Ö¸´ËùÓв»ÊÜmixer_set()
»ò mixer_setrecsrc()
¿ØÖƵÄÉèÖá£
¡¡¡¡AC97ÓÉ´øÓÐAC97±àÂë½âÂëÆ÷µÄÇý¶¯³ÌÐòʵÏÖ¡£ ËüÖ»ÓÐÈý¸ö·½·¨£º
xxxac97_init()
·µ»ØÕÒµ½µÄ ac97±àÂë½âÂëÆ÷µÄÊýÄ¿¡£
ac97_read()
Óë ac97_write()
¶Áдָ¶¨µÄ¼Ä´æÆ÷¡£
¡¡¡¡The AC97½Ó¿ÚÓÉ pcmÖеÄAC97´úÂëÀ´Ö´Ðи߲ã²Ù×÷¡£²Î¿´ sound/pci/maestro3.c»ò sound/pci/ϺܶàÆäËûÄÚÈÝ×÷Ϊ·¶Àý¡£
¡¡¡¡±¾Õ½«ÌÖÂÛFreeBSDΪ±àдPC Card»òCardBusÉ豸µÄÇý¶¯³ÌÐò¶øÌṩµÄ»úÖÆ¡£ µ«Ä¿Ç°±¾ÎÄÖ»¼Ç¼ÁËÈçºÎÏòÏÖÓеÄpccardÇý¶¯³ÌÐòÖÐÌí¼ÓÇý¶¯³ÌÐò¡£
¡¡¡¡ÏòËùÖ§³ÖµÄpccardÉ豸ÁбíÖÐÌí¼ÓÐÂÉ豸µÄ²½ÖèÒѾÓëϵͳÔÚFreeBSD 4 ÖÐʹÓõķ½·¨²»Í¬ÁË¡£ÔÚÒÔǰµÄ°æ±¾ÖУ¬ÐèÒª±à¼ /etcÖеÄÒ»¸öÎļþÀ´ÁгöÉ豸¡£´ÓFreeBSD 5.0¿ªÊ¼£¬ É豸Çý¶¯³ÌÐòÖªµÀËüÃÇÖ§³ÖʲôÉ豸¡£ÏÖÔÚÄÚºËÖÐÓÐÒ»¸öÊÜÖ§³ÖÉ豸µÄ±í£¬ Çý¶¯³ÌÐòÓÃËüÀ´Á¬½ÓÉ豸¡£
¡¡¡¡¿ÉÒÔÓÐÁ½ÖÖ·½·¨À´Ê¶±ðPC Card£¬ËûÃǶ¼»ùÓÚ¿¨É쵀 CISÐÅÏ¢¡£µÚÒ»ÖÖ·½·¨ÊÇʹÓÃÖÆÔìÉ̺ͲúÆ·µÄÊý×Ö±àºÅ¡£ µÚ¶þÖÖ·½·¨ÊÇʹÓÃÈ˿ɶÁµÄ×Ö·û´®£¬×Ö·û´®Ò²Êǰüº¬ÔÚCISÖС£PC Card×ÜÏß Ê¹Óü¯ÖÐʽÊý¾Ý¿âºÍһЩºêÀ´Ìṩһ¸öÒ×ÓõÄÉè¼ÆÄ£Ê½£¬ÈÃÇý¶¯³ÌÐòµÄ±àд ÕߺÜÈÝÒ×µØÈ·¶¨Æ¥ÅäÆäÇý¶¯³ÌÐòµÄÉ豸¡£
¡¡¡¡Ò»¸öºÜÆÕ±éµÄʵ¼ÊÇé¿öÊÇ£¬Ä³¸ö¹«Ë¾ÎªÒ»¿îPC Card²úÆ·¿ª·¢³ö²Î¿¼ Éè¼Æ£¬È»ºó°ÑÕâ¸öÉè¼ÆÂô¸øÁíÍâµÄ¹«Ë¾£¬ÒÔ±ãÔÚÊг¡ÉϳöÊÛ¡£ÄÇЩ¹«Ë¾¸Ä½ø ÔÉè¼Æ£¬°ÑÏòËûÃǵÄÄ¿±ê¿Í»§Èº»òµØÀíÇøÓò³öÊÛ²úÆ·£¬²¢½«ËûÃÇ×Ô¼ºµÄÃû×Ö ·Åµ½¿¨ÖС£È»¶øËùνµÄ¶ÔÏÖÓп¨µÄ¸Ä½ø£¬¼´Ê¹×ö¹ýÈκÎÐ޸ģ¬ÕâЩÐÞ¸Äͨ³£ Ҳ΢ºõÆä΢¡£È»¶ø£¬ÎªÁËÇ¿»¯ËûÃÇ×Ô¼º°æ±¾µÄÆ·ÅÆ£¬ÕâЩ¹©»õÉ̳£³£»á°ÑËûÃÇ ¹«Ë¾µÄÃû×Ö·ÅÈëCIS¿Õ¼äµÄ¿É¶Á×Ö·û´®ÖУ¬È´²»»á¸Ä¶¯ÖÆÔìÉ̺ͲúÆ·µÄID¡£
¡¡¡¡¼øÓÚÒÔÉÏÇé¿ö£¬¶ÔÓÚFreeBSDÀ´ËµÊ¹ÓÃÊý×ÖID¿ÉÒÔ¼õС¹¤×÷Á¿¡£Í¬Ê±Ò² »á¼õС½«ID¼ÓÈ뵽ϵͳµÄ¹ý³ÌÖÐËù´øÀ´µÄ¸´ÔÓÐÔ¡£±ØÐë×Ðϸ¼ì²éËÊÇ¿¨µÄ ÕæÕýÖÆÔìÕߣ¬ÓÈÆäµ±ÌṩԿ¨µÄ¹©»õÉÌÔÚÖÐÐÄÊý¾Ý¿âÖÐÒѾÓÐÒ»¸ö²»Í¬µÄID ʱ¡£Linksys£¬D-LinkºÍNetGearÊǾ³£³öÊÛÏàͬÉè¼ÆµÄ¼¸¸öÃÀ¹úÖÆÔìÉÌ¡£ ÏàͬµÄÉè¼Æ¿ÉÄÜÔÚÈÕ±¾ÒÔÖîÈçBuffaloºÍCoregaµÄÃû×Ö³öÊÛ¡£È»¶ø£¬ÕâЩ É豸³£³£¾ßÓÐÏàͬµÄÖÆÔìÉ̺ͲúÆ·ID¡£
¡¡¡¡PC Card×ÜÏßÔÚÆäÖÐÐÄÊý¾Ý¿â /sys/dev/pccard/pccarddevsÖб£´æÁË¿¨µÄÐÅÏ¢£¬ µ«²»°üº¬ÄĸöÇý¶¯³ÌÐòÓëËüÃǹØÁªµÄÐÅÏ¢¡£ËüÒ²ÌṩÁËÒ»Ì׺꣬ÒÔÔÊÐíÔÚ Çý¶¯³ÌÐòÓÃÀ´ÉùÃ÷É豸µÄ±íÖÐÈÝÒ׵ش´½¨¼òµ¥ÌõÄ¿¡£
¡¡¡¡×îºó£¬Ä³Ð©·Ç³£µÍ¶ËµÄÉ豸¸ù±¾²»°üº¬ÖÆÔìÉ̱êʶ¡£ÕâЩÉ豸ÐèҪʹÓà ¿É¶ÁCIS×Ö·û´®À´Æ¥ÅäËüÃÇ¡£Èç¹ûÎÒÃDz»ÐèÒªÕâÖÖÓ¦¼±°ì·¨¸ÃÓжàºÃ£¬µ«¶ÔÓÚ Ä³Ð©·Ç³£µÍ¶ËÈ´·Ç³£Á÷ÐеÄCD-ROM²¥·ÅÆ÷À´ËµÈ´ÊDZØÐèµÄ¡£Í¨³£Ó¦µ±±ÜÃâ ʹÓÃÕâÖÖ·½·¨£¬µ«±¾½ÚÖл¹ÊÇÁгöÁ˺ܶàÉ豸£¬ÒòΪËüÃÇÊÇÔÚÈÏʶµ½PC CardÉÌÒµµÄOEM±¾ÖÊ֮ǰ¼ÓÈëµÄ£¬Ó¦µ±ÓÅÏÈʹÓà Êý×Ö·½·¨¡£
¡¡¡¡pccarddevsÎļþÓÐËĽڡ£µÚÒ»½ÚΪʹÓà ËüÃǵÄÄÇЩ¹©»õÉÌÁгöÁËÖÆÔìÉ̺ÅÂë¡£±¾½Ú°´Êý×ÖÅÅÐò¡£ÏÂÒ»½Ú°üº¬ÁË ÕâЩ¹©»õÉÌʹÓõÄËùÓвúÆ·£¬°üÀ¨ËûÃǵIJúÆ·IDºÅÂëºÍÃèÊö×Ö·û´®¡£ ÃèÊö×Ö·û´®Í¨³£²»»á±»Ê¹Óã¨Ïà·´£¬¼´Ê¹ÎÒÃÇ¿ÉÒÔÆ¥ÅäÊý×Ö°æ±¾ºÅ£¬ÎÒÃÇ ÈÔÈ»»ùÓÚÈ˿ɶÁµÄCISÉèÖÃÉ豸µÄÃèÊö£©¡£È»ºóΪʹÓÃ×Ö·û´®Æ¥Åä·½·¨µÄ ÄÇЩÉè±¸ÖØ¸´ÕâÁ½½ÚµÄ¶«Î÷¡£×îºó£¬ÎļþÈκεط½¿ÉÒÔʹÓÃC·ç¸ñµÄ×¢ÊÍ¡£
¡¡¡¡ÎļþµÄµÚÒ»½Ú°üº¬¹©»õÉÌID¡£Çë±£³ÖÁÐ±í°´Êý×ÖÅÅÐò¡£´ËÍ⣬ΪÁË ÄÜÓÐÒ»¸öͨÓÃÇåÎúµÄ±£´æµØÀ´·½±ãµØ±£´æÕâЩÐÅÏ¢£¬ÎÒÃÇÓëNetBSD¹²Ïí´Ë Îļþ£¬Òò´ËÇëе÷¶Ô´ËÎļþµÄÈκθü¸Ä¡£ÀýÈ磺
vendor FUJITSU 0x0004 Fujitsu Corporation vendor NETGEAR_2 0x000b Netgear vendor PANASONIC 0x0032 Matsushita Electric Industrial Co. vendor SANDISK 0x0045 Sandisk Corporation
¡¡¡¡ÏÔʾÁ˼¸¸ö¹©»õÉÌID¡£ºÜ´ÕÇɵÄÊÇNETGEAR_2 ʵ¼ÊÉÏÊÇNETGEAR´ÓÆä¹ºÂò¿¨µÄOEM£¬¶ÔÄÇЩ¿¨Ìṩ֧³ÖµÄ×÷ÕßÄÇʱ²¢²»ÖªµÀ NETgearʹÓõÄÊDZðÈ˵ÄID¡£ÕâЩÌõÄ¿Ï൱ֱ½ÓÒ×¶®¡£Ã¿ÐÐÉ϶¼Óй©»õÉÌ ¹Ø¼ü×ÖÀ´Ö¸Ê¾±¾ÐеÄÀà±ð¡£Ò²Óй©»õÉ̵ÄÃû×Ö¡£Ãû×Ö½«»áÔÚpccarddevsÎļþ µÄºóÃæÖØ¸´³öÏÖ£¬Ãû×ÖÒ²»áÓÃÔÚÇý¶¯³ÌÐòµÄÆ¥Åä±íÖУ¬Òò´Ë±£³ÖËüµÄ¶ÌС ²¢ÇÒÊÇÓÐЧµÄC±êʶ·û¡£»¹ÓÐÒ»¸ö¸ø¹©»õÉ̵ÄÊ®Áù½øÖÆÊý×ÖID¡£²»ÒªÌí¼Ó 0xffffffff»ò0xffffÐÎʽµÄID£¬ ÒòΪËüÃÇÊDZ£ÁôID£¨Ç°ÕßÊÇ'¿ÕID¼¯ºÏ'£¬¶øºóÕßÓÐʱ»áÔÚÖÊÁ¿¼«Æä²îµÄ¿¨ÖÐ ¿´µ½£¬ÓÃÀ´Ö¸Ê¾none£©¡£×îºó»¹ÓйØÓÚÖÆ¿¨¹«Ë¾µÄÃèÊö×Ö·û´®¡£Õâ¸ö×Ö·û´® ÔÚFreeBSDÖгýÁËÓÃÓÚ×¢ÊÍÄ¿µÄÍⲢûÓб»Ê¹Óùý¡£
¡¡¡¡ÎļþµÄµÚ¶þ½Ú°üº¬²úÆ·. ÈçÄãÔÚÏÂÃæÀý×ÓÖп´µ½µÄ:
/* Allied Telesis K.K. */ product ALLIEDTELESIS LA_PCM 0x0002 Allied Telesis LA-PCM /* Archos */ product ARCHOS ARC_ATAPI 0x0043 MiniCD
¡¡¡¡¸ñʽÓ빩»õÉ̵ÄÄÇЩÐÐÏàËÆ¡£ÆäÖÐÓвúÆ·¹Ø¼ü×Ö¡£È»ºóÊǹ©»õÉÌÃû×Ö£¬ ÓÉÉÏÃæÖØ¸´¶øÀ´¡£ºóÃæ¸ú×ŲúÆ·Ãû×Ö£¬´ËÃû×ÖÔÚÇý¶¯³ÌÐòÖÐʹÓã¬ÇÒÓ¦µ± ÊÇÒ»¸öÓÐЧC±êʶ·û£¬µ«¿ÉÒÔÒÔÊý×Ö¿ªÍ·¡£È»ºóÊÇ¿¨µÄÊ®Áù½øÖƲúÆ·ID¡£ ¹©»õÉÌͨ³£¶Ô0xffffffffºÍ 0xffffÓÐÏàͬµÄÔ¼¶¨¡£×îºóÊǹØÓÚÉ豸×ÔÉíµÄ×Ö·û´® ÃèÊö¡£ÓÉÓÚFreeBSDµÄpccard×ÜÏßÇý¶¯³ÌÐò»á´ÓÈ˿ɶÁµÄCISÌõÄ¿´´½¨Ò»¸ö ×Ö·û´®£¬Òò´ËÕâ¸ö×Ö·û´®ÔÚFreeBSDÖÐͨ³£²»±»Ê¹Ó㬵«Ä³Ð©CISÌõÄ¿²»ÄÜ Âú×ãÒªÇóµÄÇé¿öÏ»¹¿ÉÄÜʹÓᣲúÆ·°´ÖÆÔìÉ̵Ä×Öĸ˳ÐòÅÅÐò£¬È»ºóÔÙ°´ ²úÆ·IDµÄÊý×ÖÅÅÐò¡£Ã¿¸öÖÆÔìÉÌÌõĿǰÓÐÒ»ÌõC×¢ÊÍ£¬ÌõĿ֮¼äÓÐÒ»¸ö¿ÕÐС£
¡¡¡¡µÚÈý½ÚºÜÏóÇ°ÃæµÄ¹©»õÉÌÒ»½Ú£¬µ«ËùÓɵÄÖÆÔìÉÌIDΪ -1¡£-1ÔÚFreeBSD pccard×ÜÏß ´úÂëÖÐÒâζ×Å¡°Æ¥Åä·¢ÏÖµÄÈκζ«Î÷¡±¡£ÓÉÓÚËüÃÇÊÇC±êʶ·û£¬ ËüÃǵÄÃû×Ö±ØÐëΨһ¡£³ý´ËÖ®Íâ¸ñʽµÈͬÓÚÎļþµÄµÚÒ»½Ú¡£
¡¡¡¡×îºóÒ»½Ú°üº¬ÄÇЩ±ØÐëÓÃ×Ö·û´®Æ¥ÅäµÄ¿¨¡£ÕâÒ»½ÚµÄ¸ñʽÓëͨÓà ½ÚµÄ¸ñʽÓе㲻ͬ£º
product ADDTRON AWP100 { "Addtron", "AWP-100&spWireless&spPCMCIA", "Version&sp01.02", NULL } product ALLIEDTELESIS WR211PCM { "Allied&spTelesis&spK.K.", "WR211PCM", NULL, NULL } Allied Telesis WR211PCM
¡¡¡¡ÎÒÃÇÒѾÊìϤÁ˲úÆ·¹Ø¼ü×Ö£¬ºó¸ú¹©»õÉÌÃû×Ö£¬È»ºóÔÙ¸ú¿¨µÄÃû×Ö£¬ ¾ÍÏóÔÚÎļþµÚ¶þ½ÚÖÐÄÇÑù¡£È»¶ø£¬ÕâÖ®ºó¾ÍÓëÄǸñʽ²»Í¬ÁË¡£ÓÐÒ»¸ö {}·Ö×飬ºó¸ú¼¸¸ö×Ö·û´®¡£ÕâЩ×Ö·û´®¶ÔÓ¦CIS_INFOÈýÔª×éÖж¨ÒåµÄ ¹©»õÉÌ£¬²úÆ·ºÍ¶îÍâÐÅÏ¢¡£ÕâЩ×Ö·û´®±»²úÉú pccarddevs.hµÄ³ÌÐò¹ýÂË£¬½« &spÌæ»»Îª ʵ¼ÊµÄ¿Õ¸ñ¡£¿ÕÌõÄ¿Òâζ×ÅÌõÄ¿µÄÕⲿ·ÖÓ¦µ±±»ºöÂÔ¡£ÔÚÎÒÑ¡ÔñµÄÀý×ÓÖÐ ÓÐÒ»¸ö´íÎóµÄÌõÄ¿¡£³ý·Ç¶Ô¿¨µÄ²Ù×÷À´ËµÖÁ¹ØÖØÒª£¬·ñÔò²»Ó¦µ±ÔÚÆäÖÐ °üº¬°æ±¾ºÅ¡£ÓÐʱ¹©»õÉÌÔÚÕâ¸ö×Ö¶ÎÖлáÓп¨µÄºÜ¶à²»Í¬°æ±¾£¬ÕâЩ°æ±¾ ¶¼Äܹ¤×÷£¬ÕâÖÖÇé¿öÏÂÄÇЩÐÅÏ¢Ö»»áÈÃÄÇЩӵÓÐÏàËÆ¿¨µÄÈËÔÚFreeBSDÖÐ ¸üÄÑÒÔʹÓá£ÓÐʱµ±¹©»õÉ̳öÓÚÊг¡¿¼ÂÇ£¨¿ÉÓÃÐÔ£¬¼Û¸ñµÈµÈ£©£¬Ï£Íû³öÊÛ Í¬Ò»Æ·ÅÆÏµĺܶ಻ͬ²¿·Öʱ£¬ÕâÒ²ÊÇÓбØÒªµÄ¡£Èç¹ûÕâÑù£¬ÔòÔÚÄÇЩ ¹©»õÉÌÈÔÈ»±£³ÖÏàͬµÄÖÆÔìÉÌ/²úÆ·¶ÔµÄÉÙ¼ûÇé¿öÏ£¬ÄÜ·ñÇø·Ö¿ª¿¨ÖÁ¹Ø ÖØÒª. ´Ëʱ²»ÄÜʹÓÃÕýÔò±í´ïʽƥÅä¡£
¡¡¡¡Òª¶®µÃÈçºÎÏòËùÖ§³ÖµÄÉ豸ÁбíÖÐÌí¼ÓÉ豸£¬¾Í±ØÐë¶®µÃºÜ¶àÇý¶¯³ÌÐò ¶¼ÓеÄ̽²âºÍ/»òÆ¥ÅäÀý³Ì¡£ÓÉÓÚҲΪÀÏ¿¨ÌṩÁËÒ»¸ö¼æÈݲ㣬ÕâÔÚ FreeBSD 5.xÖÐÓÐÒ»µã¸´ÔÓ¡£ÓÉÓÚÖ»ÊÇwindow-dressing²»Í¬£¬Õâ¶ù¸ø³öÁË Ò»¸öÀíÏ뻯µÄ°æ±¾¡£
static const struct pccard_product wi_pccard_products[] = { PCMCIA_CARD(3COM, 3CRWE737A, 0), PCMCIA_CARD(BUFFALO, WLI_PCM_S11, 0), PCMCIA_CARD(BUFFALO, WLI_CF_S11G, 0), PCMCIA_CARD(TDK, LAK_CD011WL, 0), { NULL } }; static int wi_pccard_probe(dev) device_t dev; { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, wi_pccard_products, sizeof(wi_pccard_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); return (0); } return (ENXIO); }
¡¡¡¡Õâ¶ùÎÒÃÇÓÐÒ»¸ö¿ÉÒÔÆ¥ÅäÉÙÊý¼¸¸öÉ豸µÄ¼òµ¥pccard̽²âÀý³Ì¡£ÈçÉÏÃæ
ËùÌáµ½£¬Ãû×Ö¿ÉÄܲ»Í¬£¨Èç¹û²»ÊÇ foo_pccard_probe()
Ôò¾ÍÊÇ
foo_pccard_match()
£©¡£º¯Êý pccard_product_lookup()
ÊÇÒ»¸öͨÓú¯Êý£¬Ëü±éÀú
±í²¢·µ»ØÖ¸ÏòËüËùÆ¥ÅäµÄµÚÒ»ÏîµÄÖ¸Õ롣һЩÇý¶¯³ÌÐò¿ÉÄÜʹÓÃÕâ¸ö»úÖÆÀ´
½«Ä³Ð©¿¨µÄ¸½¼ÓÐÅÏ¢´«µÝµ½Çý¶¯³ÌÐòµÄÆäËü²¿·Ö£¬Òò´Ë±íÖпÉÄÜÓÐЩ±äÌå¡£
ΨһµÄÒªÇó¾ÍÊÇÈç¹ûÄãÓÐÒ»¸ö²»Í¬µÄ±í£¬ÔòÈñíµÄ½á¹¹µÄµÚÒ»¸öÔªËØÎª ½á¹¹pccard_product¡£
¡¡¡¡¹Û²ìһϱíwi_pccard_products
¾Í»á·¢ÏÖ£¬
ËùÓÐÌõÄ¿¶¼ÊÇ PCMCIA_CARD(foo£¬
bar£¬ baz)
µÄÐÎʽ¡£ foo²¿·ÖΪÀ´×Ô pccarddevsµÄÖÆÔìÉÌID¡£
bar²¿·ÖΪ²úÆ·¡£ bazΪ´Ë¿¨ËùÆÚÍûµÄ¹¦Äܺš£Ðí¶àpccards
¿ÉÒÔÓжà¸ö¹¦ÄÜ£¬ÐèÒªÓÐ°ì·¨Çø·Ö¿ª¹¦ÄÜ1ºÍ¹¦ÄÜ0¡£Äã¿ÉÒÔ¿´Ò»Ï PCMCIA_CARD_D£¬Ëü°üÀ¨ÁËÀ´×Ô pccarddevsÎļþµÄÉ豸ÃèÊö¡£ÄãÒ²¿ÉÒÔ¿´¿´ PCMCIA_CARD2ºÍ PCMCIA_CARD2_D£¬µ±ÄãÐèÒª°´
¡°Ê¹ÓÃĬÈÏÃèÊö¡±ºÍ¡°´ÓpccarddevsÖÐÈ¡µÃ¡±
×ö·¨£¬Í¬Ê±Æ¥ÅäCIS×Ö·û´®ºÍÖÆÔìÉ̺ÅÂëʱ¾Í»áÓõ½ËüÃÇ¡£
¡¡¡¡Òò´Ë£¬ÎªÁËÒ»¸öÔö¼ÓÐÂÉ豸£¬±ØÐë½øÐÐÏÂÃæ²½Öè¡£Ê×ÏÈ£¬±ØÐë´ÓÉ豸 »ñµÃ±êʶÐÅÏ¢¡£Íê³ÉÕâ¸ö×îÈÝÒ׵ķ½·¨¾ÍÊǽ«É豸²åÈëµ½PC Card»òCF²ÛÖУ¬ ²¢·¢³ödevinfo -v¡£Äã¿ÉÄܻῴµ½Ò»Ð©ÀàËÆÏÂÃæµÄ ¶«Î÷£º
cbb1 pnpinfo vendor=0x104c device=0xac51 subvendor=0x1265 subdevice=0x0300 class=0x060700 at slot=10 function=1 cardbus1 pccard1 unknown pnpinfo manufacturer=0x026f product=0x030c cisvendor="BUFFALO" cisproduct="WLI2-CF-S11" function_type=6 at function=0
¡¡¡¡×÷ΪÊä³öµÄÒ»²¿·Ö¡£ÖÆÔìÉ̺ͲúƷΪ²úÆ·µÄÊý×ÖID¡£¶øcisvenderºÍ cisproductΪCISÖÐÌṩµÄÃèÊö±¾²úÆ·µÄ×Ö·û´®¡£
¡¡¡¡ÓÉÓÚÎÒÃÇÊ×ÏÈÏëÓÅÏÈʹÓÃÊý×ÖÑ¡ÏÒò´ËÊ×Ïȳ¢ÊÔ´´½¨»ùÓڴ˵ÄÌõÄ¿¡£ ΪÁËʾÀý£¬ÉÏÃæµÄ¿¨ÒѾ±»ÉÔÉÔÐé¹¹»¯ÁË¡£ÎÒÃÇ¿´µ½µÄ¹©»õÉÌΪBUFFALO£¬ ËüÒѾÓÐÒ»¸öÌõÄ¿ÁË£º
vendor BUFFALO 0x026f BUFFALO (Melco Corporation)
¡¡¡¡ÕâÑùÎÒÃǾͿÉÒÔÁË¡£ÎªÕâ¸ö¿¨²éÕÒÒ»¸öÌõÄ¿£¬µ«ÎÒÃÇûÓз¢ÏÖ¡£µ«ÎÒÃÇ ·¢ÏÖ£º
/* BUFFALO */ product BUFFALO WLI_PCM_S11 0x0305 BUFFALO AirStation 11Mbps WLAN product BUFFALO LPC_CF_CLT 0x0307 BUFFALO LPC-CF-CLT product BUFFALO LPC3_CLT 0x030a BUFFALO LPC3-CLT Ethernet Adapter product BUFFALO WLI_CF_S11G 0x030b BUFFALO AirStation 11Mbps CF WLAN
¡¡¡¡ÎÒÃǾͿÉÒÔÏòpccarddevsÖÐÌí¼Ó£º
product BUFFALO WLI2_CF_S11G 0x030c BUFFALO AirStation ultra 802.11b CF
¡¡¡¡Ä¿Ç°£¬ÐèÒªÒ»¸öÊÖ¶¯²½ÖèÀ´ ÖØÐ²úÉúpccarddevs.h£¬ÓÃÀ´½«ÕâЩ±êʶ·ûת»» µ½¿Í»§Çý¶¯³ÌÐò¡£ÄãÔÚÇý¶¯³ÌÐòÖÐʹÓÃËüÃÇ֮ǰ±ØÐëÍê³ÉÏÂÃæ²½Ö裺
# cd src/sys/dev/pccard # make -f Makefile.pccarddevs
¡¡¡¡Ò»µ©Íê³ÉÁËÕâЩ²½Ö裬Äã¾Í¿ÉÒÔÏòÇý¶¯³ÌÐòÖÐÌí¼Ó¿¨ÁË¡£ÕâÖ»ÊÇÒ»¸ö Ìí¼ÓÒ»Ðеļòµ¥²Ù×÷£º
static const struct pccard_product wi_pccard_products[] = { PCMCIA_CARD(3COM, 3CRWE737A, 0), PCMCIA_CARD(BUFFALO, WLI_PCM_S11, 0), PCMCIA_CARD(BUFFALO, WLI_CF_S11G, 0), + PCMCIA_CARD(BUFFALO, WLI_CF2_S11G, 0), PCMCIA_CARD(TDK, LAK_CD011WL, 0), { NULL } };
¡¡¡¡×¢Ò⣬ÎÒÔÚÎÒÌí¼ÓµÄÐÐÇ°Ãæ°üº¬ÁË'+'£¬µ«ÕâÖ»ÊÇ ÓÃÀ´Ç¿µ÷ÕâÒ»ÐС£²»Òª°ÑËüÌí¼Óµ½Êµ¼ÊÇý¶¯³ÌÐòÖС£Ò»µ©ÄãÌí¼ÓÁËÕâÐУ¬¾Í ¿ÉÒÔÖØÐ±àÒëÄں˻òÄ£¿é£¬²¢ÊÔ×Å¿´ËüÊÇ·ñÄÜʶ±ðÉ豸¡£Èç¹ûËüʶ±ð³öÉ豸 ²¢Äܹ¤×÷£¬ÇëÌá½»²¹¶¡¡£Èç¹ûËü²»¹¤×÷£¬ÇëÕÒ³öÈÃËü¹¤×÷ËùÐèÒªµÄ¶«Î÷²¢ Ìá½»Ò»¸ö²¹¶¡¡£Èç¹ûËü¸ù±¾²»Ê¶±ðÉ豸£¬ÄÇôÄã¿ÉÄÜ×ö´íÁËʲô£¬Ó¦µ±ÖØÐ ¼ì²éÿһ²½¡£
¡¡¡¡Èç¹ûÄãÊÇÒ»¸öFreeBSDÔ´´úÂëµÄcommitter£¬²¢ÇÒËùÓж«Î÷¿´ÆðÀ´¶¼ Õý³£¹¤×÷£¬ÔòÄãÓ¦µ±°ÑÕâЩ¸Ä±äÌá½»µ½Ê÷ÖС£È»¶øÓÐЩС¼¼ÇɵĶ«Î÷Äã ÐèÒª¿¼ÂÇ¡£Ê×ÏÈ£¬Äã±ØÐëÌá½»pccarddevsÎļþµ½ Ê÷ÖС£Íê³Éºó£¬Äã±ØÐëÖØÐ²úÉúpccarddevs.h ²¢½«Ëü×÷ΪÁíÒ»´ÎÌá½»À´Ìá½»£¨ÕâÊÇΪÁËÈ·±£ÕýÈ·µÄ $FreeBSD$±êÇ©»áÁôÔÚºóÃæµÄÎļþÖУ©¡£×îºó£¬ÄãÐèÒª°Ñ ÆäËü¶«Î÷Ìá½»µ½Çý¶¯³ÌÐò¡£
¡¡¡¡ºÜ¶àÈËÖ±½Ó°ÑÐÂÉ豸µÄÌõÄ¿·¢Ë͸ø×÷Õß¡£Çë²»ÒªÄÇÑù×ö¡£Ç뽫ËüÃÇ×÷Ϊ PRÀ´Ìá½»£¬²¢½«PRºÅÂë·¢Ë͸ø×÷ÕßÓÃÓڼǼ¡£ÕâÑùÈ·±£ÌõÄ¿²»»á¶ªÊ§¡£Ìá½» PRʱ£¬²¹¶¡ÖÐûÓбØÒª°üº¬pccardevs.hµÄdiff£¬ ÒòΪÄÇЩ¶«Î÷¿ÉÒÔÖØÐ²úÉú¡£°üº¬É豸µÄÃèÊöºÍ¿Í»§Çý¶¯³ÌÐòµÄ²¹¶¡ÊDZØÒª µÄ¡£Èç¹ûÄã²»ÖªµÀÃû×Ö£¬Ê¹ÓÃOEM99×÷ΪÃû×Ö£¬×÷Õß½«»áµ÷²éºóÏàÓ¦µØµ÷Õû OEM99¡£Ìá½»Õß²»Ó¦µ±Ìá½»OEM99£¬¶øÓ¦¸ÃÕÒµ½×î¸ßµÄOEMÌõÄ¿²¢Ìá½»¸ßÓÚÄǸö µÄÒ»¸ö¡£
[1] |
ÓÐЩ¹¤¾ßÈçdisklabel(8) »áʹÓÃÕâÒ»ÇøÓò´æ´¢ÐÅÏ¢£¬Ö÷ÒªÊÇÔÚµÚ¶þÉÈÇøÀï¡£ |
[2] |
±¾ÎĵµºÍÆäËüÎĵµ¿É´ÓÕâÀïÏÂÔØ£ºftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
Èç¹û¶ÔÓÚFreeBSDÓÐÎÊÌ⣬ÇëÏÈÔĶÁÎĵµ£¬Èç²»Äܽâ¾öÔÙÁªÏµ<questions@FreeBSD.org>.
¹ØÓÚ±¾ÎĵµµÄÎÊÌâÇë·¢ÐÅÁªÏµ <doc@FreeBSD.org>.