配色: 字号:
Linux+
2016-06-23 | 阅:  转:  |  分享 
  
Linux内核源代码漫游创建时间:2001-10-1121时13分

第1页共9页

Linux内核源代码漫游

AlessandroRubini著,rubini@pop.systemy.it

赵炯译,gohigh@sh163.net(www.plinux.org)



本章试图以顺序的方式来解释Linux源代码,以帮助读者对源代码的体系结构以及很多

相关的unix特性的实现有一个很好的理解。目标是帮助对Linux不甚了解的有经验的C程

序员对整个Linux的设计有所了解。这也就是为什么内核漫游的入点选择为内核本身的启始

点:系统引导(启动)。

这份材料需要对C语言以及对Unix的概念和PC机的结构有很好的了解,然而本章中并

没有出现任何的C代码,而是直接参考(g6363g2533g709实g19481的代码的。有关内核设计的g7380g1351g12699g5145是

g3324本g6175g1888的g1866g4439章g14422中,而本章g1185g17247g2533g1122是一个g19762g8503式的概g17860。

本章中所参g19417的任何g7003g1226的g17347g5464g2529g18129是g6363g1039源代码目g5417g7653,g17902g5132是g18ug86g85g18g86g85g70g18g79inux。

这g18336所g13485出的g3835多g6980g1461g5699g18129是g2474g1055g1122Linuxg2469g15904g102681g170的源代码。g15441然g3926g8504,有

时也g1262g6564g1391对g2530g7411g10268本的参考。这g12699漫游中g5332g3848有图标的任何g4579g14422g18129是g5390g168551g170g10268本

g2530对内核的g7044的g6925动。g3926g7536没有这g7691的g4579g14422g4396g3324,g2029g15932g12046直g2052g10268本1g170g17g28-1g171g17g26g25,没有g1328

g17819g6925动。

有时g1517本章中g1262有g16949这g7691的g4579g14422,这是g6363g2533g8503g11842的代码以对g2030g16764g16782g17819的g1039g20076g2474g5483

g7368多g1461g5699的g6363g12046g12538。g5415然,这g18336是g6363源代码。

引导(启动)系统

g5415PC的g11017源g6183g5332g2530,g270xg27g25结构的CPUg4570g14270动g17839入实g8181式,并g1186g3332g33480xg41g41g41g410g5332始g14270

动g6203g15904程序代码,这个g3332g3348g17902g5132是g53g50g48-g37g44g50g54中的g3332g3348。PC机的g37g44g50g54g4570g6203g15904g7588g1135系统的g7828

g8991,g3324g10301理g3332g33480g3800g5332始g2033始g2282中g7041g2533g18339。g8504g2530,g4439g4570g2499启动设g3803的g12544一个g6171g2318读入内g4396g3332

g33480xg26C00g3800,并g17351g17728g2052这个g3332方。启动设g3803g17902g5132是g17731g20549g6122是g11840g11436。这g18336的叙g17860是g19762g5132简单

的,但这已经足够理解内核g2033始g2282的工g1328g17819程了。

Linux的g7380g7380前面部分是用g270g27g25汇编语言编写的(bootg18bootg86eg70tg17g54),g4439g4570由g37g44g50g54读

入g2052内g43960xg26C00g3800,g5415g4439被g6203g15904时就g1262把g14270己移g2052绝对g3332g33480xg280000g3800,并g4570启动设g3803

(bootg18g86etupg17g54)的下2kg37字g14422的代码读入内g43960xg280200g3800,而内核的g1866g4439部分g2029被读入g2052g3332

g33480x10000g3800。g3324系统加载g7411间g4570显g12046g1461g5699"Loadingg17g17g17"。然g2530控制权g4570传递g13485

bootg18g54etupg17g54中的代码,这是另一个实g8181式汇编语言程序。

启动部分识别g1039机的g7588g1135特性以及vga卡的类型。g3926g7536需要,g4439g1262要求用户为控制台选

择显g12046g8181式。然g2530g4570整个系统g1186g3332g33480x10000移至0x1000g3800,g17839入保护g8181式并g17351g17728至系统

的余下部分(g33240x1000g3800g709。

下一步是内核的解压缩。0x1000g3800的代码来g14270g1122zg37ootg18headg17g54,g4439g2033始g2282寄g4396器并g16855

用deg70ompg85eg86g86_keg85neg79(),g4439们依次是由zg37ootg18infg79ateg17g70、zg37ootg18unzipg17g70和zg37ootg18mig86g70g17g70

组成。被解压的g6980据g4396放g2052了g3332g33480x10000g3800(1兆),这也是为什么Linux不能运g15904g1122少g1122

2兆内g4396的g1039要原因。[g33241兆内g4396中解压内核的工g1328已经完成,见g48emog85yg54aveg85g86--ED]

g4570内核封装g3324一个gzipg7003g1226中的工g1328是由zg37oot目g5417中的g48akefig79e以及工具完

成的。g4439们是值g5483一看的有趣的g7003g1226。

内核g2469g15904g102681g171g17g265g4570boot和zg37oot目g5417下移g2052了ag85g70hg18i3g27g25g18boot中了,这个g6925

动意味着对不同的体系结构允许真g8503的内核建造,不g17819我g4570g1185然只讲解有关i3g27g25的g1461g5699。

解压g17819的代码是g1186g3332g33480x10100g3800g5332始g6203g15904的[这里我可能忘记了具体的物理地址了,

Linux内核源代码漫游创建时间:2001-10-1121时13分

第2页共9页

因为我对相应的代码不是很熟],g3324那g18336,所有32比特的设置启动被完成:g44DT、GDT以及

LDT被加载,g3800理器和协g3800理器也已g11842认,分页工g1328也设置好了;g7380终g16855用g86tag85t_keg85neg79

子程序。上g17860操g1328的源代码是g3324bootg18headg17g54中的,这g2499能是整个内核中g7380有诀窍的代码了。

注意g3926g7536g3324前g17860任何一步中出了错,计算机就g1262死锁。g3324操g1328系统还没有完全运g17728g1055前

是g3800理不了出错的。

g86tag85t_keg85neg79()是位g1122initg18maing17g70中的,并g1000没有任何g17832g3250结g7536。g1186现g3324g17227的任何代

码g18129是用C语言编制的,g19512了中g7041g12661理和系统g16855用的入g18出代码(g5415然,还有g3835多g6980的g4451g18129

g4896入了汇编代码g709。

让轮子转动起来

g3324g3800理了所有错g13520g3809g7446的g19394g20076g1055g2530,g86tag85t_keg85neg79()g2033始g2282了内核的所有部分,g4600g1866是:

?设置内g4396g17805g11040和g16855用paging_init();

?g2033始g2282中g7041、g44g53g52g17902g17959和g16855g5242;

?分g7524(解g7524g709g2641g1208g15904;

?g3926g7536需要,就分g18209一个g6980据g13543g1926g2318(pg85ofig79ingbuffeg85)以及g1866g4439一g1135g4579部分;

?g7669g8503g5322g17843g5502g10627(计算g256g37ogog48ipg86g257g6980);

?g7828g7609中g70411g25是g2554能g994协g3800理器工g1328。

g7380g2530,为了g10995成g2033始g17839程,内核g1946g3803好了移至move_to_ug86eg85_mode(),g4439的代码也是g3324

同一个源代码g7003g1226中的。然g2530,所g16871的g12366g19398任g2165,g17839程g25070就g17839入g7092g19492的g12366g19398g5502g10627中运g15904。

接着g2033始g17839程(initpg85og70eg86g86g709g4593试着运g15904g18etg70g18init、g18bing18initg6122者g18g86bing18init。

g3926g7536g4439们没有一个运g15904成g2163的,就g1262g2447g6203g15904代码g256g18bing18g86hg18etg70g18g85g70g257并g1000g3324g12544一个终

g12483上g10995成一个g7693g2641g1208解释程序(g85ootg86heg79g79g709。这g8585代码g3250g9347至Linux0g1701,g5415时操g1328系

统只有一个内核,并g1000没有g11343g5417g17839程。

g3324g1186一个标g1946的g3332方(g16765我们g1563g4462我们有g709用exeg70()g6203g15904了initg2033始g2282程序g1055g2530,内

核就对程序的g6203g15904没有了直接的控制。g1186现g3324g17227g4439的g16280g2029是g6564g1391对系统g16855用的g3800理,以及为

g5334步g1119g1226g7393g2165(比g3926g11840g1226中g7041g12573g709。多任g2165的g10627g3671已经建g12447,g1186现g3324g17227是init程序g17902g17819fog85k()

g8978g10995出的系统g17839程和g11343g5417g17839程来g12661理多用户的g16787g19394了。

由g1122内核是g17139g17143g6564g1391g7393g2165的,这个漫游g7003章g4570g17902g17819g16278g4531这g1135g7393g2165(g256系统g16855用g257g709以及

g17902g17819g6564g1391g3534本g6980据结构的原理和代码的组g13467结构g13499g13505g16764g16782下g2447。

内核是如何看见一个进程的

g1186内核的g16278点来看,一个g17839程只是g17839程g15932中的一个g7477目而已。

而g17839程g15932以及g2520个内g4396g12661理g15932和g13543g1926g4396g1660器g2029是系统中g7380为g18337要的g6980据结构。g17839程g15932中

的g2520个单g20045是tag86k_g86tg85ug70t结构,是g4462g1053g3324ing70g79udeg18g79inuxg18g86g70hedg17h中的g19762g5132g3835的g6980据结构。

g3324tag86k_g86tg85ug70t中保g11053着g1186g1314g4630g2052g20652g4630的g1461g5699,g14551g3272g1186g7588g1135g11840g1226寄g4396器的g6347g17137g2052g17839程工g1328目

g5417的inodeg1461g5699。

g17839程g15932g7094是一个g6980组和g2464g19154g15932,也是一个g7653结构。g4439的g10301理实现是一个g19757g5589的g6363g19036g6980组,

g4439的g19283g5242是g4462g1053g3324ing70g79udeg18g79inuxg18tag86kg86g17h中的g5132g18339g49g53_Tg36g54g46g54,并g1000g8611个结构g18129位g1122一个

保g11053内g4396页中。这个g2027g15932结构是g17902g17819g6363g19036next_tag86k和pg85e_tag86k构成的,而g7653结构g2029是g19762

g5132g3809g7446的并g1000我们g3324g8504g4570不加以g16764g16782。g1332g2499能g5088g7407g6925动g49g53_Tg36g54g46g54的g21676认值12g27,但g1332要保

g16789所有源g7003g1226中相关的g17878g5415g7003g1226g18129要被g18337g7044编译g17819。

g3324启动引导g17819程结g7475g2530,内核g4570g5647是代g15932g7588个g17839程而工g1328,并g1000全g4628g2476g18339g70ug85g85ent---

一个g6363g2533g7588个tag86k_g86tg85ug70tg7477目的g6363g19036---被用g1122g16772g5417g8503g3324运g15904的g17839程。g70ug85g85entg1177能g17902

Linux内核源代码漫游创建时间:2001-10-1121时13分

第3页共9页

g17819g3324keg85neg79g18g86g70hedg17g70中的g16855g5242程序来g6925g2476。然而,由g1122所有的g17839程g18129g5529g20047g16787g19394g4439,所以g1363

用了g4451fog85_eag70h_tag86k。g5415系统g17139g14667很g17743时,g4439要比g6980组的顺序g6207g6563g5567g5483多。

g17839程g5647是运g15904g1122g256用户g8181式g257g6122g256内核g8181式g257。用户程序的g1039体是运g15904g1122用户g8181式而g1866

中的系统g16855用g2029运g15904g1122内核g8181式中。g3324这g1016g12193g6203g15904g8181式中g17839程所用的g3546g7644是不一g7691的--g5132

g16280的g3546g7644g8585用g1122用户g8181式,而一个g3278g4462g3835g4579的g3546g7644(一页,由g16825g17839程所有g709g2029用g1122内核g8181式。

内核g3546g7644页是g1186不g1144g6454出g2447的,因为g8611g5415一个系统g16855用g17839入时g4439就g5529g20047g4396g3324着。

内核中的系统g16855用(g86yg86temg70ag79g79g86g709是g1328为C语言g2001g6980g4396g3324的,g4439们的g254g8503g16280’g2529称是

以g254g86yg86_’g5332g3848的。例g3926一个g2529为bug85nout的系统g16855用g4570g16855用内核g2001g6980g86yg86_bug85nout()。

系统g16855用机制g3324本g6175g1888的g12544三章中g17839g15904了g16764g16782。g16278看g3324ing70g79udeg18g79inuxg18g86g70hedg17h

中的fog85_eag70h_tag86k和g54ET_Lg44g49g46g54能够帮助理解g17839程g15932中的g2027g15932和g7653结构。

创建和结束进程

unix系统是g17902g17819fog85k()系统g16855用创建一个g17839程的,而g17839程的终止是g17902g17819exit()g6122收g2052

一个g1461g2507来完成的。g4439们的Linux实现位g1122keg85neg79g18fog85kg17g70和keg85neg79g18exitg17g70中。g8978g10995出

一个g17839程是很容易的,所以fog85kg17g70程序很短并易g1122理解。g4439的g1039要任g2165是为g7044的g17839程填写

g6980据结构。g19512了填写g2520个字g8585以外,相关的步骤有:

zg2474g5483一个g12366g19398内g4396页面来保g4396tag86k_g86tg85ug70t

z找g2052一个g12366g19398的g17839程槽(find_empty_pg85og70eg86g86()g709

z为内g4396g3546g7644页keg85neg79_g86tag70k_pageg2474g5483另一个g12366g19398的内g4396页面

zg4570父辈的LDTg6347g17137g2052子g17839程

zg3809制父g17839程的mmapg1461g5699

g86yg86_fog85k()同g7691也g12661理g7003g1226g6563g17860g12538和inode。

1g170的内核也对线程g6564g1391g7588g1135不够完善的支持,所以fog85k()系统g16855用对g8504也g13485出了

g7588g1135g12046意。内核的线程是g1039流内核以外的g17819程产品。

g1186一个g17839程中退出是比较有窍门的,因为父g17839程g5529g20047被g17902告有关任何子g17839程的退出。而

g1000,一个g17839程g2499以由另外一个g17839程g1363用kig79g79()而退出(这g1135是Unix的特性g709,所以g19512了

g86yg86_exit()g1055外,g86yg86_kig79g79()以及g86yg86_wait()的g2520g12193特性也g4396g3324g1122exitg17g70g1055中了。

这g18336不对exitg17g70的代码加以g16764g16782---因为g4439一点也不g1208人感兴趣。为了以一致的状g5589退

出系统,g4439涉及g2052许多细g14422。而Pg50g54g44X标g1946对g1122g1461g2507g2029是要求相g5415严格的,所以这g18336g5529g20047对

g1866加以叙g17860。

执行程序

g3324g16855用了fog85k()g1055g2530,就有同一个程序的g1016个g6347g17137g3324运g15904了,g17902g5132一个程序g1363用exeg70()

g6203g15904另一个程序。exeg70()系统g16855用g5529g20047g4462位g16825g6203g15904g7003g1226的二g17839制映像,加载并g6203g15904g4439。词语

g254加载’并不一g4462意味着g256g4570二g17839制映像g6347g17137g17839内g4396g257,因为Linux支持按需加载。exeg70()

的Linux实现支持不同的二g17839制格式。这是g17902g17819g79inux_binfmt结构来达g2052的,g1866中内g4896了

g1016个g6363g2533g2001g6980的g6363g19036--一个是用g1122加载g2499g6203g15904g7003g1226的,另一个用g1122加载库g2001g6980,g8611g12193二g17839制

格式g18129实现有这g1016个g2001g6980。共享库的加载是g3324exeg70()同一个源程序中实现的,但我们只g16764

g16782exeg70()本身。Unix系统g6564g1391了六g12193exeg70()g2001g6980。g19512了一个以外,所有g18129是以库g2001g6980的

形式实现的,并g1000,Linux内核是单独实现g86yg86_exeg70ve()g16855用的。g4439g6203g15904一个g19762g5132简单的任

g2165:加载g2499g6203g15904g7003g1226的g3848部,并试着g2447g6203g15904g4439。g3926g7536g3848g1016个字g14422是g256#!g257,那么就g1262解g7524g16825

g2499g6203g15904g7003g1226的g12544一g15904并g16855用一个解释器来g6203g15904g4439,g2554g2029的话,就g1262顺序g3332试用g2520个注g1888g17819的

二g17839制格式。Linux本身的格式是由fg86g18exeg70g17g70直接支持的,并g1000相关的g2001g6980是

Linux内核源代码漫游创建时间:2001-10-1121时13分

第4页共9页

g79oad_aout_binag85y和g79oad_aout_g79ibg85ag85y。对g1122二g17839制,g2001g6980g4570加载一个g256ag17outg257g2499g6203g15904

g7003g1226并以g1363用mmap()加载磁g11436g7003g1226g6122g16855用g85ead_exeg70()而结g7475。前一g12193方法g1363用了Linux

的按需加载机理,g3324程序被g16787g19394时g1363用出错加载方式(faug79t-ing709加载程序页面,而g2530一g12193

方式是g3324g1039机g7003g1226系统不支持内g4396映像时(例g3926g256mg86dog86g257g7003g1226系统g709g1363用的。

g7044近的1g171内核内g4896了一个修订的mg86dog86g7003g1226系统,g4439支持mmap()。而g1000

g79inux_binfmt结构已是一个g19154g15932而不是一个g6980组了,以允许以一个内核g8181块的方式加载一

个g7044的二g17839制格式。g7380g2530,结构的本身也已经被扩展成能够g16787g19394g994格式相关的核心g17728g1660程序

了。

访问文件系统

众所周知,g7003g1226系统是Unix系统中g7380为g3534本的资源了,g4439g3926g8504的g3534本和普遍g4396g3324以至

g1122g4439需要一个g7368为便利的g2529字--我g4570忠g1122标g1946的称呼简单g3332称g1055为g256fg86g257。

我g4570g1563设读者早已知g17959g3534本的Unixg7003g1226系统的原理--g16787g19394(权g19492g709许g2499、ig14422点(inode)、

超级块、加载(mount)和卸载(umount)g7003g1226系统。这g1135概念g3324标g1946的Unixg7003献中由比我聪明

的g1328者g13485出了很好的解释,所以我就不g18337g3809他们的工g1328并g1000我g4570只专注g1122有关Linux方面的

g19394g20076。

早g7411的Unixg17902g5132只支持一个g7003g1226系统(fg86g709类型,g4439的代码散布g1122整个内核中,现今

的实现是g3324内核和fg86g1055间g1363用一个标g1946的接口,以便g1122g3324不同的体系结构中g17839g15904g6980据的g1144

g6454。Linux本身g6564g1391了一个标g1946g4630以g3324内核和g8611g12193fg86g8181块g1055间传递g6980据。这个接口g4630称为

Vg41g54,即g256虚拟g7003g1226系统g257("vig85tuag79fig79eg86yg86tem"g709。

因而g7003g1226系统的代码被分割成了g1016g4630:上g4630是关g1122内核g15932格的g12661理和g6980据结构的,而g1314

g4630是由g994g2520g7003g1226系统相关的g2001g6980集构成的,并g1000是由Vg41g54g6980据结构g17839g15904g16855用的。

所有g994g7003g1226系统独g12447的资料g18129位g1122fg86g18g17g70g7003g1226中。g4439们涉及g3926下的g19394g20076:

?g12661理g13543g1926寄g4396器(buffeg85g17g70g709;

?对fg70ntg79()和iog70tg79()系统g16855用g1328出响应(fg70ntg79g17g70和iog70tg79g17g70g709;

?g3324inode和g13543g1926g2318上映射g12661g17959和fifo(fifog17g70,pipeg17g70g709;

?g12661理g7003g1226-和inode-g15932(fig79e_tabg79eg17g70,inodeg17g70g709;

?锁g4462和解锁g7003g1226和g16772g5417(g79og70kg17g70g709;

?g4570g2529称映射g2052inode(nameig17g70,openg17g70g709;

?实现错g13520g3809g7446的g86eg79eg70t()g2001g6980(g86eg79eg70tg17g70g709;

?g6564g1391g1461g5699(g86tatg17g70g709;

?加载和卸载g7003g1226系统(g86upeg85g17g70g709;

?g1363用exeg70()g6203g15904g2499g6203g15904程序以及g17728g1660核心程序(exeg70g17g70g709;

?加载g2520g12193二g17839制格式(bin_fmtg17g70,g3926上面所g17860g709。

而Vg41g54接口g2029由一组相对比较g20652g4630次的操g1328组成,并g1186g994g7003g1226系统独g12447的代码中g16855用而

实g19481上是由g8611g12193g7003g1226系统类型g6203g15904的。g7380为相关的g6980据结构是inode_opeg85ationg86和

fig79e_opeg85ationg86,尽g12661g4439们不是独g14270g4396g3324的:同g7691g4396g3324着g1866g4439一g1135g6980据结构。g4439们g18129g4462g1053

g3324ing70g79udeg18g79inuxg18fg86g17hg7003g1226中。

g2052实g19481g7003g1226系统的内核入口点是g6980据结构fig79e_g86yg86tem_type。fig79e_g86yg86tem_typeg86的一

个g6980组包含g3324fg86g18fig79eg86yg86temg86g17g70中,并g1000g8611g5415g2469出了一个加载(mountg709g2641g1208时g18129g1262引用g4439。

然g2530,相应fg86类型的g2001g6980g85ead_g86upeg85就g17139g17143填写结构g86upeg85_bg79og70k的一个g20045,而g16825g20045又内

g4896了结构g86upeg85_g86tg85ug70t和结构type_g86b_info。前者为g5415前的fg86类型g6564g1391了g6363g2533一般fg86操

g1328的g6363g19036,而g2530者对相应fg86类型内g4896了特g4462的g1461g5699。

Linux内核源代码漫游创建时间:2001-10-1121时13分

第5页共9页

g7003g1226系统类型g6980组已经g17728g6454成了一个g19154g15932,以允许用内核g8181块的形式加载g7044的fg86

类型。g2001g6980(un-)g85egig86teg85_fig79eg86yg86tem代码包含g3324fg86g18g86upeg85g17g70中。

一个文件系统类型的快速剖析

一个g7003g1226系统类型的任g2165是g6203g15904用g1122映射相应g20652g4630Vg41g54操g1328g2052g10301理介质(磁g11436、网络g12573

g12573g709的g1314g4630任g2165。Vg41g54接口有足够的灵活性来支持传统的Unixg7003g1226系统和外来的g16949mg86dog86

和umg86dog86g7003g1226系统类型。

g8611一个fg86类型g19512了g4439g14270己的源代码目g5417以外,是由下g2027g2520g20045组成的:

?fig79e_g86yg86temg86[]g6980组中的一个g7477目(g20045g709(fg86g18fig79eg86yg86temg86g17g70g709;

?超级块(g86upeg85bg79og70kg709的ing70g79udeg7003g1226(ing70g79udeg18g79inuxg18type_fg86_g86bg17hg709;

?ig14422点(inodeg709的ing70g79udeg7003g1226(ing70g79udeg18g79inuxg18type_fg86_ig17hg709;

?普g17902g14270己专用的ing70g79udeg7003g1226(ing70g79udeg18g79inuxg18type_fg86g17hg709;

?ing70g79udeg18g79inuxg17fg86g17h中的g1016g15904#ing70g79ude,以及g3324结构g86upeg85_bg79og70k和inode中的

g7477目。

对g1122特g4462fg86类型g14270己的目g5417,包含有所有的实g19481代码、inode和g6980据的g12661理程序。

本g6175g1888中有关pg85og70fg86的章g14422,揭g12046了所有有关那g12193fg86类型的g1314g4630代码和Vg41g54接

口。g3324g19417读g17819那个章g14422g1055g2530,fg86g18pg85og70fg86中的源代码就显g5483g19762g5132容易理解了。

现g3324我们来g16278g4531Vg41g54机制的内部工g1328情况,并以minixg7003g1226系统的代码g1328为一个实g19481例

子。我选择minix类型是因为g4439比较短g4579但却是完整的;而g1000,Linux中的所有g1866g4439的fg86

类型g18129衍g10995g1122g4439。g3324g7380近Linux安装中的g1119实上的标g1946g7003g1226系统类型ext2,要比g4439g3809g7446g5483

多,对ext2这个g7003g1226系统的探索就g11053g13485聪明的读者g1328为一个练习了。

g5415一个minix-fg86被加载g2530,minix_g85ead_g86upeg85就g1262把g1186被加载的设g3803中读g2474的g6980据添

入g86upeg85_bg79og70kg6980据结构中。g8504时,g16825结构中的g86_op域g4570保g11053有一个g6363g2533minix_g86opg86的g6363

g19036,g16825g6363g19036g4570被一般g7003g1226系统代码用g1122分g8978超级块的操g1328。

g3324全g4628系统g7653结构中g19154接g7044加载的fg86依赖g1122下g2027g2520g6980据g20045(g1563设g86b是超级块g6980据结构,

而dig85_i是g6363g2533加载点的inode的g6363g19036g709:

?g86b->g86_mountedg6363g2533被加载g7003g1226系统的g7693目g5417ig14422点(g48g44g49g44X_g53g50g50T_g44g49g50g709;

?dig85_i->i_mount保g4396有g86b->g86_mounted;

?g86b->g86_g70oveg85ed保g4396有dig85_i

卸载操g1328g4570g7380终g17902g17819do_umount来g6203g15904,而g4439g1262依次g16855用minix_put_g86upeg85。

g8611g5415g16787g19394一个g7003g1226时,minix_g85ead_inode就g1262g5332始g6203g15904;g4439g1262g1363用minix_inodeg2520字

g8585中的g6980据填写系统g14551g3272的inodeg6980据结构。inode->i_op字g8585是依照inode->i_mode来填

写的,g4439g4570g17139g17143g16825g7003g1226的任何g1866g4439操g1328。上g17860minixg2001g6980的代码g2499以g1186fg86g18minixg18inodeg17g70

中找g2052。

inode_opeg85ationg86g6980据结构是用g1122把inode操g1328分g8978g13485特g4462fg86类型的内核g2001g6980;g16825g6980

据结构的g12544一g20045是一个g6363g2533fig79e_opeg85ationg86g20045的g6363g19036,g4439g12573同g1122g6980据g12661理的i_op。minix

g7003g1226系统类型允许有inode操g1328集中的三g12193方式(用g1122目g5417、g7003g1226和g12538g2507g19154接g709和g7003g1226操g1328

集中的g1016g12193(g12538g2507g19154接不需要g7003g1226操g1328g709。

目g5417操g1328(g1177minix_g85eaddig85g709位g1122fg86g18minixg18dig85g17g70中;g7003g1226操g1328(读g85ead和写wg85iteg709

位g1122fg86g18minixg18fig79eg17g70中而g12538g2507操g1328(读g2474并跟随着g19154g709位g1122fg86g18minixg18g86ymg79inkg17g70。

minix源代码目g5417中的g1866余部分用g1122实现以下任g2165:

?bitmapg17g70用g1122g12661理ig14422点g994块的分g18209和释放(而ext2g7003g1226系统却有g1016个不同的代

码g7003g1226g709;

Linux内核源代码漫游创建时间:2001-10-1121时13分

第6页共9页

?fg86ynkg17g70用g1122fg86yng70()系统g16855用--g4439g12661理直接、间接和g2464g18337间接块(我g1563g4462g1332是知

g17959这g1135术语的,因为这是Unix的普g17902知识g709;

?nameig17g70内g4896有所有g994g2529字有关的ig14422点的操g1328,比g3926g16949g14422点的创建和消g19512、g18337g2641

g2529和g19154接;

?tg85ung70ateg17g70g6203g15904g7003g1226的截g7041操g1328。

控制台驱动程序(consoledriver)

g1328为g3835多g6980Linux系统上的g1039要g44g18g50设g3803,控制台g20549动程序是应g16825受g2052g7588g1135关注的。有

关控制台和g1866g4439字g12538g20549动程序的源代码g2499以g3324dg85iveg85g86g18g70hag85中找g2052,g5415我们g6363称g7003g1226时,

我们g4570g1363用这个特g4462的目g5417。

控制台的g2033始g2282是由tty_iog17g70中的tty_init()g2001g6980来g6203g15904的。这个g2001g6980g1177g1177涉及g2474g5483

g8611个设g3803集的g1039设g3803g2507并g16855用g8611个设g3803集的initg2001g6980。而g70on_init()g2029是g994控制台相关的

g2001g6980,并g4396g3324g1122g70ong86og79eg17g70中。

g3324内核1g171的g5332g2469中,控制台的g2033始g2282已经有了很g3835的g2476g2282。g70ong86og79e_init()已

经g1186tty_init()中g14085g12175出来了,并g1000是由g17g17g18g17g17g18maing17g70直接g16855用的。现g3324虚拟控制台是动

g5589分g18209的,g1866代码也已有了很g3835的g2476g2282。所以我g4570g17351g17819g2033始g2282、分g18209g12573g12573的g16826细g16764g16782。

文件操作是如何分派给控制台的

这一g14422是相g5415g5225g4630的g16764g16782,g1332g2499以放心g3332g17351g17819本g14422。

g8639g7092g11109g19394,Unix设g3803是g17902g17819g7003g1226系统来g16787g19394的。本g14422g4570g16826细g6563g17860g1186设g3803g7003g1226g2052实g19481控

制台g2001g6980的所有步骤,而g1000,以下的g1461g5699是g1186内核的1g171g17g263源代码中g6289g2474来的,g4439g9941g170

的代码g2499能少许有点不同。

g5415g6183g5332一个设g3803ig14422点时,g3324g17g17g18g17g17g18fg86g18devig70eg86g17g70中的g70hg85dev_open()g2001g6980(g6122者是

bg79kdev_open(),但我只专注g1122字g12538设g3803g709g4570被g6203g15904。这个g2001g6980是g17902g17819g6980据结构def_g70hg85_fopg86

g2474g5483的,而g4439又是被g70hg85dev_inode_opeg85ationg86引用的,是被所有g7003g1226系统类型g1363用的(见

前面有关g7003g1226系统的部分g709。

g70hg85dev_openg17902g17819g3324g5415前操g1328中g7379g6454具体设g3803的fig79e_opeg85ationg86g15932并g1000g16855用特g4462的

open()g2001g6980来g12661理g6363g4462的设g3803操g1328的。具体设g3803的g15932结构是保g4396g3324g6980组g70hg85devg86[]中的,并

由g1039设g3803g2507g1328为索引,位g1122同一个g17g17g18g17g17g18devig70eg86g17g70中。

g3926g7536g16825设g3803是一个tty类型的(我们不是只关注控制台g2539g731g709,我们就来g16764g16782tty的设

g3803g20549动程序,g4439们的g2001g6980g3324tty_iog17g70g1055中,由tty_fopg86g1328为索引。这g7691,tty_open()就g1262

g16855用init_dev(),而init_dev()就g1262g7693据次设g3803g2507为设g3803分g18209任何所需的g6980据结构。

次设g3803g2507也用g1122g7828索已经g1363用tty_g85egig86teg85_dg85iveg85()注g1888g11343g16772g17819的设g3803的实g19481g20549动

程序。而g1000,g16825g20549动程序g1185是另一个用g1122分g8978计算的g6980据结构,g8503g3926fig79e_opg86一g7691;g4439是

g994设g3803的写操g1328和控制有关的。g7380g2530一个用g1122g12661理tty的g6980据结构是线g17347g16280程,这g4570g3324g2530面

叙g17860。控制台(以及任何g1866g4439的tty设g3803g709的线g17347g16280程是由initiag79ize_tty_g86tg85ug70t()设置

的,并由init_devg16855用的。

g3324这一g14422中我们所涉及的所有g1119情g18129是g994设g3803g7092关的,g1177有g994特g4462控制台相关的是

g70ong86og79eg17g70,g3324g70on_init()操g1328g7411间已经注g1888了g14270己的g20549动程序。相g2465,线g17347g16280程是g994设g3803

g7092关的。

Thetty_dg85iveg85g6980据结构g3324g31g79inuxg18tty_dg85iveg85g17h>中有着完整的g6563g17860。

上g17860g1461g5699是g11861g171g17g263源代码中g2474g5483的。g4439是有g2499能g994g1332的内核有所不同的(g256g3926

g1461g5699有所g2476动g4570不另g15904g17902知g257g709。

Linux内核源代码漫游创建时间:2001-10-1121时13分

第7页共9页

控制台写操作

g5415g5460一个控制台设g3803g17839g15904写操g1328时,就g1262g16855用g70on_wg85iteg2001g6980。这个g2001g6980g12661理所有控制

字g12538和g6454码字g12538序g2027,这g1135字g12538g13485应用程序g6564g1391全部的g4643g5161g12661理操g1328。所实现的g6454码序g2027是

vt102终g12483的;这意味着g5415g1332g1363用teg79netg17842接g2052一台g19762Linuxg1039机时,g1332的g10627g3671g2476g18339应g16825

有TEg53g48g32vt102;然而,对g1122本g3332操g1328g7380g1351的选择是设置TEg53g48g32g70ong86og79e,因为Linux控制台

g6564g1391了一个vt102g2163能的超集。

因而,g70on_wg85ite()g1039要是由g17728g6454语g2489组成的,用g1122g3800理g8611一次一个字g12538的有g19492g19283状g5589

g14270动g6454码序g2027的解释。g3324g8503g5132方式下,所g6183g2372的字g12538是g1363用g5415前g4658性直接写g2052显g12046内g4396中的。

g3324g70ong86og79eg17g70中,g6980据结构vg70的所有域g1363用g4451g18129是g2499g16787g19394的,所以(例g3926g709任何对attg85

的引用,只要g70ug85g85g70ong86是所g6363的控制台的g2507码,g11842实是引g16789了g6980据结构vg70_g70ong86[g70ug85g85g70ong86]

中的域。

实g19481上,g7044内核中的vg70_g70ong86已不g1889是一个g6980据结构g6980组了,现g3324g4439是g6363g19036的g6980

组,g1866内容是用kmag79g79og70()操g1328的。g4451的g1363用g3835g3835g3332简g2282了代码修g6925的工g1328,因为许多代码

g18129不需要被g18337写。

控制台内g4396g2052g4643g5161内g4396的实g19481映射和g19762映射是由g2001g6980g86et_g86g70g85mem()(g4439把控制台g13543g1926

g2318中的g6980据g6347g17137g2052显g12046内g4396中g709和get_g86g85g70mem()(g4439把g6980据g6347g17137g3250控制台g13543g1926g2318中g709g6203g15904

的。为了g1955少g6980据传g17767的次g6980,g5415前控制台的g12181有g13543g1926g2318是g10301理g3332映射g2052实g19481显g12046g53g36g48上的。

这意味着g70ong86og79eg17g70中的get-和g86et-_g86g70g85mem()是g19757g5589的,并g1000g1177g3324一个控制台g17728g6454g7411间g6177

被g16855用。

控制台读操作

控制台读操g1328是由线g17347g16280程来完成的。Linux中g21676认的(也是g2819一的g709线g17347g16280程被称为

tty_g79dig86g70_g49_TTg60。线g17347g16280程也就是g256g17902g17819一线g17347g13434g7475g17767入g257。g4439是另一个g2001g6980g15932(我们已

习g5827了这g12193方法,不是g2539g731g709,g4439是有关g1122设g3803读操g1328的。g3324teg85miog86标g5547的帮助下,线g17347

g16280程也即是g1186tty上控制g17767入的g16280程:g7422g3800理g17819的g6980据、g70bg85eak和计g2022的方式;g86eg79eg70t();

iog70tg79()g12573g12573。

线g17347g16280程中的读(g85eadg709g2001g6980称为g85ead_g70han(),g4439读g2474tty的g13543g1926g2318而不g12661g6980据是g1186

g2750g18336来的。原因是g17902g17819一个tty来g2052的字g12538是由g5334步g11840g1226中g7041g12661理的。

线g17347g16280程g49_TTg60也同g7691g3324tty_iog17g70中,尽g12661以g2530出的内核g18129g1363用一个不同的

n_ttyg17g70源程序。

控制台g17767入的g7380g5225g4630是g19202g11436g12661理的一部分,因g8504g4439是g3324keyboag85dg17g70的

keyboag85d_integ85g85upt()中g3800理的。

键盘管理

g19202g11436g12661理简直是一g3342g3133g7802。g4439g19492g1122g7003g1226keyboag85dg17g70中,g18336面g1817g9397了g15932g12046不同g2390g4490g19202g11436

的g2520个g19202码的g2325六g17839制g6980。

我g4570不对keyboag85dg17g70g17839g15904g9157入g16764g16782,因为g1866中没有g994内核g11752g12362者有关的相关g1461g5699。

对g1122那g1135对Linux的g19202g11436编程g11842实感兴趣的人,g7380好的方法是g1186keyboag85dg17g70的g7380

g2530一g15904g5460g3250看g17227。g7380g5225g4630的细g14422是g3324g16825g7003g1226的上g2334部分。

转换当前控制台

Linux内核源代码漫游创建时间:2001-10-1121时13分

第8页共9页

g5415前控制台是g17902g17819g1363用g2001g6980g70hange_g70ong86og79e()来g17728g6454的,g4439位g1122tty_iog17g70中由

keyboag85dg17g70和vtg17g70g16855用(前者响应按g19202的控制台g17728g6454,g2530者是g5415一个程序g17902g17819引用一个

iog70tg79()g16855用时g17728g6454控制台g709。

实g19481的g17728g6454g17819程是分g1016步来g6203g15904的,g2001g6980g70ompg79ete_g70hange_g70ong86og79e()g3800理g1866中的g12544二

部分。g17728g6454的分g16022意味着g3324一个g994控制着我们g8503g3324g12175g5332的tty的g17839程的g2499能的g6581g6175以g2530完成

任g2165。g3926g7536控制台不g3324g17839程控制g1055下,g70hange_g70ong86og79e()就g1262g14270己g16855用

g70ompg79ete_g70hange_g70ong86og79e()。g17839程需要足够的能g2159来成g2163g3332完成g1186图形g2052g7003本控制台g6122g1186

g7003本g2052图形控制台的g17728g6454,并g1000Xg7393g2165器(例g3926g709是g1866图形控制台的控制g17839程。

选择机制

g256选择(g86eg79eg70tiong709g257是Linuxg7003本控制台的g2110g2011(g70utg709g994g12908g17160(pag86teg709g2163能。这

个g6228g5051g1039要是由用户级的g17839程来g3800理的,g4439g2499以用g86eg79eg70tiong6122gpm的具体例子g16840明。用户

级的程序g3324控制台上g1363用iog70tg79()g17902知内核来加g1154显g12046g4643g5161的一个g2318域。然g2530,被选择的g7003

本被g6347g17137g2052一个选择g13543g1926g2318。g16825g13543g1926g2318是g70ong86og79eg17g70中的一个g19757g5589实体。g12908g17160g7003本操g1328是g17902

g17819g256g6175工g3332g257g4570字g12538放入ttyg17767入g19443g2027中完成的。整个选择机制是g17902g17819#ifdef受g2052保护的,

所以用户g3324内核g18209置g7411间g2499以g12117用g4439以g14422g11477g1972g2327字g14422的内g4396。

选择是一个g19762g5132g1314级的g2163能,因而g4439工g1328是任何g1866g4439内核活动所看不见的。这意味着许

多的#ifdef只是g4643g5161g3324以任何方式g1328修g6925g1055前简单g3332移动加g1154部分。

g7044内核特性g6925善了选择的代码,g21748标g6363g19036的加g1154g2499以g994被选择的g7003本独g12447(内核

1g171g1723g6122g7368g20652g709。而g1000,g11861g171g17g263g10268g17227,被选择的g7003本g1363用了动g5589的g13543g1926g2318而不是g19757g5589的

了,g1363g5483内核g4579了g23g46g37。

使用ioctl()操作设备

iog70tg79()系统g16855用是用户g17839程控制设g3803g7003g1226g15904为的入口点。g44og70tg79g12661理是

g1186g17g17g18g17g17g18fg86g18iog70tg79g17g70中产g10995的,实g19481上g86yg86_iog70tg79()就是g3324这个iog70tg79g17g70中的。标g1946的iog70tg79

g16843求就是g3324那g18336g6203g15904的,g1866g4439g994g7003g1226相关的g16843求是由fig79e_iog70tg79()g3800理的(g3324同一个源g7003

g1226中g709,而g1866g4439任何g16843求g18129分g8978g13485特g4462设g3803的iog70tg79()g2001g6980。

控制台设g3803的iog70tg79资料是位g1122vtg17g70中的,因为控制台g20549动程序要g4570iog70tg79g16843求分g8978

g13485vt_iog70tg79()。

上g17860g1461g5699是关g1122内核1g171g17g26x的。1g170内核是没有g256g20549动程序g257g15932的,而g1000vt_iog70tg79()

是直接由fig79e_opeg85ationg86()g15932g6363g2533的。

g44og70tg79的资料g11842实是相g5415g16765人g9163g9114的。有g1135g16843求是g994设g3803相关的,而有g1135却是g994线g17347g16280

程相关的。我g4570试图对1g170和1g171g17g26x内核g1055间g2469g10995的任何g1119概要g5647结一下。

1g171g17g26x系g2027内核有g3926下的特性:tty_iog70tg79g17g70只实现了线g17347g16280程g16843求(也就是

n_tty_iog70tg79(),这是g2819一g3324n_ttyg17g70外面的n_ttyg2001g6980g709,而fig79e_opeg85ationg86字g8585g6363g2533

tty_iog17g70中的tty_iog70tg79()。g3926g7536g16843求g2507没有被tty_iog70tg79()解g7524出来,g4439就g1262被传g2052

tty->dg85iveg85g17iog70tg79g6122者,g3926g7536g4439g3845g17145时,就g2052tty->g79dig86g70g17iog70tg79。控制台的g994g20549动程序相

关的资料g2499以g1186vtg17g70中找g2052,而线g17347g16280程方面的资料g2029g3324tty_iog70tg79g17g70中。

g33241g170内核中,tty_iog70tg79()是g3324tty_iog70tg79g17g70中的并有一般tty的fig79e_opeg85ationg86

所g6363g2533。g7422被解g7524出的g16843求g4570用g9941g171g17g26x相g1296的方法被传g17877g2052特g4462的iog70tg79g2001g6980g6122g2052线g17347

g16280程代码g2447。

注意,g3324这g1016g12193情况中,Tg44g50CLg44g49UXg16843求是g3324g994设g3803g7092关的代码中的,这g7275g12046着控制台

选择操g1328g2499以g17902g17819iog70tg79对任何ttyg17839g15904操g1328来设置(g86et_g86eg79eg70tion()g5647是g3324控制台前台

Linux内核源代码漫游创建时间:2001-10-1121时13分

第9页共9页

上操g1328的g709,而这是一个安全上的g9443g8946。这也是g17728移g2052一个g7368g7044的内核的很好理由,g3324g7044内

核中,g17902g17819g1177允许超级用户来g3800理选择g5369g15929了这个g9443g8946。

有很多g16843求g2499以被g2469g13485控制台设g3803,而知g17959g4439们的g7380好方法是g8995g16284源程序g7003g1226vtg17g70。



g10268权所有(g70)1g28g28g23g36g79eg86g86andg85og53ubinig15g85ubinig35popg17g86yg86temyg17it



献花(0)
+1
(本文系七克白菜首藏)