Linux0.11源代码


( ৰ 1 ) ͝ 160 Ȍ Version 1.0 ۅLinux0.11 ļ x++÷À÷ƄxŅ÷ax++÷À÷ƄxŅ÷ax++÷À÷ƄxŅ÷ax++÷À÷ƄxŅ÷a "  % "!""#$$  % "!""#$$  % "!""#$$  % !""#$$         ȄÏ▻ȄÏ▻ȄÏ▻ȄÏ▻ ě̓ƚě̓ƚě̓ƚě̓ƚ Ǎʻƚ┦Ǎʻƚ┦Ǎʻƚ┦Ǎʻƚ┦ ᩥਜ਼ƶᩥਜ਼ƶᩥਜ਼ƶᩥਜ਼ƶ     Ȍ ۅȌļ ۅȌļ ۅȌļ ۅ ļ ৰ 2 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ό„ϬՈିƧʐ͔ɴǜₓ .................................................................................................64 !ϧẟ࣏Ո TSS.............................................................................................................63 ......................................................................................................61 ç¥źɍɉTSS ɴᾬȳẴ৪ᜬՈ᪂ǎ.....................................................................................................61 !ϧẟ࣏ .................................................................................................................................59 ৰ€ত ẟ࣏ிඣՈ!ϧĚ ...........................................................................................................59 58.............................................................................................................کᩥਜ਼ƶȭẟ࣏Ոͫ ç¥źɍɉ .........................................................................................................................58 ɴᾬȳẴ৪ᜬ.....................................................................................................................58 ^࣏Ûâƅ͟ .................................................................................................................57 ^rⒸƅ͟ .........................................................................................................................57 ^ᵯéɀ᪅ƅ͟ .................................................................................................................57 ẟ࣏ՈPჰȳẴǍʻ .........................................................................................................56 ᪸Š.............................................................................................................................56 ^ẟ࣏ाⒸՈƽǶƅ͟.....................................................................................................56 ^Ǎǻ̠ˊƅ͟ .................................................................................................................56 ^ẟ࣏᫇òּ͟ .................................................................................................................55 ৰ÷ত ẟ࣏ՈȳẴ.......................................................................................................................55 1 ǻẟ࣏ ..................................................................................................................................52 ƅிඣµśḰȕϬ›µś.............................................................................................51 0 ǻẟ࣏ ..................................................................................................................................50 ৰYত ிඣՈ!ϧĚ ...................................................................................................................50 ljĈµś[ͱƌՈȯŜʇ඗ .................................................................................................48 ˛ේ᪱ᣄ^ C ᪱ᣄՈ£Ȍේ࣏............................................................................................45 .........................................................................................43 ljĈµś)ś੥ˊ ᪸Š .................................................................................................................36ۅÏ Ո੄ᡅϕ࣏Ě .................................................................................................36ۅÏ Head.s Ո᪸Š.................................................................................................................35 A20 ŌŜඃ⒲L....................................................................................................34 .................................................................................31 ljĈµśɉś੥ˊᾬ ᪸Š .................................................................................................................24ۅÏ Ո੄ᡅϕ࣏Ě .................................................................................................24ۅÏ Setup.s Ո᪸Š................................................................................................................22 Ȓᩴ.........................................................................................................................22 ᪸Š .................................................................................................................14ۅÏ Ո੄ᡅϕ࣏Ě .................................................................................................14ۅÏ Bootsec.s âՈ᪸Š ....................................................................................................13 වẴ .................................................................................................................................12ۅÏ šȰՈවẴ.............................................................................................................................11 ৰxত ிඣՈšȰ.......................................................................................................................11 ৰPত Ẵ .....................................................................................................................................9 Ûᣄ ..................................................................................................................................................7 ֲơֲơֲơֲơ ৰ 3 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ǍǻՈ᪂า...........................................................................................................................106 ǍǻିƧ................................ .......................................................................................106 ǍǻՈȳẴ...........................................................................................................................105 ৰŅত Ǎǻ̠ˊ .........................................................................................................................105 ϔ do_timer: ..............................................................................................................103 ͟z EOI Ո᪸Š......................................................................................................103 ˑàǎr) .......................................................................................................................102 ᪸Š...........................................................................................................................102 ǎr„Ո!ϧĚ...................................................................................................................102 ৰIত ǎr„.............................................................................................................................102 ΞŁūϬிඣ᫇Ϭ .................................................................................................97 ிඣ᫇Ϭ .................................................................................................................91 Ŏ„ .........................................................................................................90ۅrϦ⏝ Ŏ„.....................................................................................................88ۅ]rϦ⏝ ẟ͑⓺ɉʐỄϦ⓺ɉ.....................................................................................................87 Ŏ„̠ˊ .................................................................................................................................87 ᪂าிඣϬՈ)ȕₓ................................ .................................................................85 ʌɶǃǎ5.............................................................................................................85 áɶǃǎ5.............................................................................................................84 ⒬ȳẴ৪Ո᪂ǎ.............................................................................................................84 )ȕₓᜬՈ᪂ǎ .................................................................................................................84 ᩨƉ¥࣏Û ignore_int .......................................................................................83ڌ !ϧĚ)ȕₓᜬ................................ .........................................................................82 ϔǒ඗Ȁ................................ .........................................................................................81 )ȕₓᜬ.............................................................................................................................81 ৰ͗ত )ிඣ ...........................................................................................................................80 ϔ interruptible_sleep_on....................................................................................................78 4̨⁖ .................................................................................................................77פẟ࣏ºý ϔ wake_up.........................................................................................................................76 ϔ sleep_on .........................................................................................................................75 ʐ̨⁖ ...........................................................................................................75פৰSত ẟ࣏Ոý 73.............................................................................................................ۅdžՈÏ ẟ࣏ -Ϭç¥⒬ǒɴɉⒸᲷḰ.....................................................................................72 ிඣɉȳẴ৪ .........................................................................................................71 ljĈµś[ՈɉⒸḰࢿ................................ .................................................................71 dž.............................................................................................................................71 ẟ࣏Ո ẟ࣏Ոọō.............................................................................................................................70 ǍǻՈ̠ˊ.............................................................................................................................69 ৰ͙ত ẟ࣏Ո᫇ò.......................................................................................................................69 ᪸Š.............................................................................................................................66 ẟ࣏Ո!ϧĚ .........................................................................................................................65 current .............................................................................................................................64 init_task ...........................................................................................................................64 ȳẴ৪ିƧ.....................................................................................................................64 ৰ 4 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ϔ get_free_page .......................................................................................................146 )Ոቻǚ^₎΢...................................................................................................................146 ͱƌ)œȸᜬ................................ ...............................................................................145 !ϧĚ ...............................................................................................................................144 ৰŅ÷ত ͱƌ੥ˊ.....................................................................................................................144 ிඣ᫇Ϭ sys _kill .................................................................................................................142 ிඣ᫇Ϭ sys_waitpid ...........................................................................................................140 tell_father ..............................................................................................................140 kill_session............................................................................................................139 ּ͟ϔ................................ .......................................................................................139 do_exit ...........................................................................................................................138 ிඣ᫇Ϭ sys_exit .................................................................................................................138 ৰŅYত ẟ࣏ՈඌǶ................................ .................................................................................138 ϔ change_ldt ....................................................................................................136 ϔ create_tables .................................................................................................135 ϔ copy_strings .................................................................................................133 ϔ do_execve .............................................................................................................128 ிඣ᫇Ϭ execve ...................................................................................................................127 ৪ǻᜬ...........................................................................................................................126 ₑǎĹᩴơ...................................................................................................................124 â͐ʸś...................................................................................................................123 dzËᜐâՈʸś ...............................................................................................................123 ৰŅxত ẟ࣏ՈËᜐ................................ .................................................................................123 ᪙ɀ ͟zϔՈẘúȨ⒲L.................................................................................121 ϣtẟ࣏ȒՈẘúȨ⒲L...................................................................................................118 ͢Ʒ.......................................................................................................................118 â᪂ǎ ...............................................................................................................118 ‑ͱƌ ...............................................................................................................116 TSS Ո᪂า ...........................................................................................................115 ẟ࣏„ᢈǜₓՈ᪂ǎ...........................................................................................114 ϔ int copy_process(…..)..........................................................................................114 ϔ int find_empty_process(void) ..............................................................................113 ிඣ᫇Ϭ fork .......................................................................................................................113 ņ................................ .................................................................................113ৰŅPত ẟ࣏Ո ǍǻՈËᜐ...................................................................................................................111 8̠ˊ⓺ɉ...................................................................................................................110 ǍǻՈËᜐ...........................................................................................................................110 ǍǻՈČỖ...........................................................................................................................109 ிඣ᫇Ϭ sys_sgetmask ................................................................................................109 ிඣ᫇Ϭ sys_ssetmask ................................................................................................109 ṉ­ϔ᪸Š .......................................................................................................108 ிඣ᫇Ϭ sys_sigaction ................................................................................................107 ிඣ᫇Ϭ sys_signal .....................................................................................................107 ǍǻՈ!ϧĚ ...............................................................................................................106 ৰ 5 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ dž໇Dz .......................................................................................................................................160 ࣏ÛՈPϣ...........................................................................................................................159 ͱʴՈ1ň...........................................................................................................................158 β̣1ň ...............................................................................................................................158 ৰŅ€ত ̱ňிඣՈẔᜐ................................ .........................................................................158 ϔ do_wp_page .................................................................................................156 ͝—ͱƌ ...............................................................................................................154 ϔ do_no_page..................................................................................................153 ̠ˊ⓺ɉ................................ .......................................................................................153 Ŏ„Ոẟ͑^ỄϦ⓺ɉ................................ ...............................................................152 Ŏ„̠ˊ ...............................................................................................................................152 ϔ get_empty_page ...................................................................................................152 ϔ put_page...............................................................................................................150 ᔞŃŌŜ4ĭˊŌŜՈœȸ̱ň.......................................................................................150 ϔ free_page_tables ...........................................................................................149 ϔ copy_page_tables .................................................................................................147 ȭֲơᜬՈ̱ň...................................................................................................................147 ϔ free_page..............................................................................................................147 ৰ 6 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ΞȘrⒸ ̭᩼ ⓉᪿʌČƨՈ Linux ႮϢ«☢„ΙՈ4IJ« uᩨ&uǡ᪸ẝɳãɨ ŌĆ᪸8uඌz͑⒬r9 ۅºጛՈȴʌ4׏ǀr Linux0.11 ՈÏ Ո᪡ ¬¯࿁Ÿ Pǎ ĆۅՈⓉᪿ ÏףՈ¦«] ĆƅՈ4udzÑlj᪅ ǮƅŌ࿁̻ɨṇ ᩨۅļ uǒ ń«\ͩϬ᪱ᣄǡȳẴ ẝ«P࢑ͫᢍ ̵ƅᪿẋ ᢍႮ=Ιʻˊᢧr C ᪱ᣄ4ẝP Ȍ̱ňிඣūuȭ C ᪱ᣄʐ˛ේ᪱ᣄKƅrP͔,Ոᩨ᪊ ͫ ̿ଡ଼r͍Ոർ4Ȑr ῁Ιʻǜǣƅ‡ồ Šr ɥ ɴń uՈͫ ᢍ« ᩥਜ਼ƶՈА ]͹ὧ4Ոࠢ࢜r P ǒń«̶͆r4 ἗໅TńȺ¬44ü&] &Ո ک[ₐ׏ᅵ u◂»ףƅ ƟrńȰ΀ ͑śிඣՈ᪂ᩥՈrȅ ǣǔΙ ᩶ᢧ ΞŁ ń Win32 Ոɳʟ [ūϬ˛ේ᪱ᣄ4Ɵrᩨ& ǒń«͆ʌ̵ϟr4ẜ ᩥਜ਼ƶՈ ȋ:࿁Ÿ ǀ͔ ƉȺṉ́ňிඣՈ Ɍₐ 4ƅPƨR9 win32 ˛ේ᪱ᣄ࣏Û᪂ᩥ:΅ Windows ՈàϬ࣏Û^ÑnjՈ࣏Ûේ΅ 5ͩǀ͔]Ȑ Ιʻń Windows Ⴎ=ɥ͍ƿ rȭ ࢑ń}◂ ᜐ ᰴՈͫ ᢍ ʇ«ᩨ& Ⴎ= ΅Ո࣏Û ΙʻΙʻΙʻΙʻ «Ƿܲ Ո4ƟrՈͫ ᢍɥ « ේ΅ 4Ñ Q uϬ MFC ΅ẋP‡ Windows ՈɃɃ ࣏Û ƅP ܄࿁&ÑȒՈƚL· [☢„ΙՈȖ ƅϬՈ Ʒ„☢„☢»ۅuᩨ& ȭzƚᩥਜ਼ƶ c ՈȐƚ ǡ᪸ ׏Pἑ̱ňிඣՈ ļ ἗&¬4ᡅẝ4Ëᜐ ˊᢧ᰻ǡǔ«Č▂4ک[»ẝ4΅ĆËᜐ¬4̱ň IJ ۅ἗Ïک±± Ոr ȅĆǕ ɴۅ᪊ Ⓣᪿ Ï کˊ᩾᫂ՈƚL «͆ₑᡅr4 ̵ƅƣˊ᫂Z᩶Ո žᢅ4Ɵu׏ǀrẟ࣏Ո੥ˊ7Ȓ uᩨ&uà ᪩ਜ਼«ˊᢧr4] ࿁᪸ˊ ᩾᫂ ]ₑᡅ ּ Ǒ Ո«ẝ4ɆՈ uּǍIJ«u]ˊᢧ ü&Ȱ᪸໐> ƦźףՈȨƣˊ᫂Z᪸ ̱ňிඣ ϞႷPϔẜdz࿁ẘú] Ȑᩭ P࣏Û Ŧ᰻ ᩭǪ P࣏ÛẔᜐdz࿁ǒɴՈɦ rՈ3 ᜐՈ Ʒ«ΞŁ ῁ ᪸ɴ ńՈ̱ňிඣ«ਜ਼ƶ̱ňிඣ«ΞŁᩭƷȳ¬᰻ǡՈɦ u]ˊᢧƷ ]ŠՁὧ 4̶]dzɩᩲՈ£࿁ «ΞŁǒɴՈ4̿̿׏ u ØϬrẝ4̶ÀՈᩥ Ȍ̱ňிඣ«ü& ₓǒ ń«ᩭ¦ȏȆ ᪿǀƅْƄ˜ᬥՈͫᢍ4u 7¤Ñ̿ۅʌČƨՈÏ ਘ˄«੄ř4Ȍ Linux0.11 ẝ ᱉൫ĺ ՈČ ƨɦ Linux ிඣՈČƨὧ4̶ & ¬4ᡅ L4r☢„☢„̶Ոᡃ4 ȌՈẋ࣏u ƚ ȌՈ ¤Zᅆȳa ̓൪Ϭr 200 Ƀr4 ń u«-Ϭ ÖZ rⒸǡ 2004 À 4 Ƅ 24 a 9 r ȄÏ▻ ࠡŌϣaȷ< ᪞Ոࠀĭễඝ¤ƅńẝPͅẋϣaՈ¦ףՈPͅ üǸu΋ȺƷɆ&Pé ʜ̳ 4IJ«\᩾ΞŁ ৰPČඌz ń¶ͅ 4 Ƅ 24 aǀtr4ẝ«Ʒ ᪢ϣ ɴǒͫ4P ͫ4▂ẋ4ü& u«r؄࢑࢑ՈÇ̿ǡ΅ƷՈ4Ɵˊ̿^ɴǒ :ᲡǔẠ Ոr ȅ ႮϢĆ ȭ ra࣏4¶ͅ« 4 Ƅ 24 a ৰPČ>ඓ΅ǀr4u&ƷՈǀtͫ4ȷ< uK&ƷՈǀt u«º 2 Ƅ 25 aŌϧ΅Ո Ōϧ±±«ƅ̿ͩ &rệὃɴǒՈüެz«ȺƷ͑ ΅rẝ41 ඌzdzÑẴᆪr ÛᣄÛᣄÛᣄÛᣄ ৰ 7 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ x++÷À÷ƄŅIa ȄÏ▻ phone: 83670837 e-mail: pan_xiaolei@sina.com uՈ ftp ŌŜftp://202.118.13.14 ( 'Ć IP ɴᬥɨṇₑ ü Ǹ IP ƅr ĆǜĚ ᪻ƣ᫉) 8ࠡ̓Ǫƅ4̓ՈΚቻKXƗ࿁̻^̓Ǫ͝Ȑϕ4☺      ☺9     8 Ιr ẜ«ᡅễ̓ǪPǩ᪡ ἗«Ȫβܲ4Ǫ̲ uņ ᩲ̓Ǫ ūϬ Adobe Reader 6.0 ǡⓉᪿẝƨR ü&άȘɨṇΙ4ک[ ₓȺႮ= Ո̿ͩ΅ẟǡ ᕁϢKƅ /¦Ոᡃ IJɩণ«Ʌϔ ¤ÑϬr8ጛ9ẝƋ4K )r ໐͔«/¦Ոᡃ żȒẜᡅÑේ ጛ඗ɲ4ęͱ̶͆ՈR῁ «ේ ጛr ǑǷ u« ɱ rǔ̶৘˄4uŌϧՈrȅ̴Ⱥ¤ƅudž໇ẋՈᰈ῁┈rZ IJ«ὧʳẝƨRɥĆ ƅẕŇ IJ«¬¯࿁Ÿ ּȭ ŽrP‡4ü Ǹ ńƅ‡ǒɴՈ ඊᅆ˔w Z᯽ ܄ƅ؄☢„ΙՈˊ᩾Ȗ uՈ̿ͩ«ᩭᪿẝƨR Ո¦࿁̻ǔΙՈˊᢧƷ ü ǸuÑuՈPȐƚ&Ȗβ້ᪿ4Ε Ոň ¤Ñuɥ̴ǕᜬPČƨȫ4ۅȌļ ໅TНr Ȍǀr4 Ȑr Ȍ4ϵzu ɨṇⒶ ɥ̴ልልՈ ẟ࣏ிඣ ϵuᯣᯧ âிඣϵz͞ 4 t ̓ųẟ࣏ிඣʐâிඣͱƌ੥ˊ̠ńẟ࣏ிඣ uᩨ& Linux0.11 dzÑ ἗Ո u΅[ruՈᢆͥ4کǪ̲ ń Linux0.11 Ոܲ«ƅP‡ bug Ո4ȭzu ̶ᰈ4᰹Ş̇«PĹ☢„☢„ΙȏՈ¦ ńՂȥ7ẜඓǔ᪪ඊ r4 XƗ̓Ǫń׏ uՈẝ ƨR Ոrȅ K ̶׏׏ Ո4u ńȭÏ Ո ẝۅȌ: ẝƨRՈȳ፝ [±ŌϧⓉᪿ Linux0.11 ՈÏ u«ń9 Linux0.11 Čƨǀ͔ Ȍ: 4ü Ǹu̿ ńǸͫ᫦ &u Ø!ƚ້ɆϦՈ ᯥDz4 «Ո ǯɆ9 Linux0.11 Čƨǀ͔ ἗PƨکȌdzÑ᪸«#ₓՈ IJ«͟z Li nux0.11 Ոu ɥ ńตZ͟zʌČƨ Linux Ո rZ☦4—͝ۅƉ¥„ Ⱥudž໇ẋՈDzᰈÑǎP‡1ͣʐ᪙ɀՈÏ ൪Ō ՈrⒸ uȺⓉᪿՈrȅἋ4ẋՈ Č▂΅r[ǡ4 Ȑr u&ẝƨRņএrP FTP ᪊4uƟr& Ǹ໐ńตZͰᡃᲕ ᰴrǔ̶ŻᲳ ĖϢ᯽rǔ̶ rⒸ4&r ᅆ کƾ]Ո ẝ ƨR̵ƅçŁՈǒ┉͛54ϵz ̱ňிඣՈǒɴ 5ǎ 4rǔ̶ǔ̶ ۅΞȘ]ƿⓉᪿ Ï Ո άɋ̓̓ Ոȴʌ4ۅ໐«ᩭŌᪿÏ ۅ΅ẝƨR ՈֲՈඡȭඡȭ]«ᩭŌ ]ƿᪿļ Ï ͫᢍ« ΞȘඝu 2 ƄՈrⒸ uKdzÑ΅P࿁̻ẔᜐՈ̱ňிඣՈ4 ἗ǒ┉̑Ρ ΞŁ IJuɴńՈک[἗r¬4«̱ňிඣ4کඣՈ඗Ȁ4 ໐ Linux0.11 Ÿᩭ u ʂŠՁƷՈȳ¬ẋ࣏ʐிK ᩼ ۅȌ Linux2.*.* ՈÏ ͆ĺr4Ξ ȘuńẝɉrⒸ ₐƿ ৰ 8 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ϭ›àϬ࣏Û ிඣƉ¥࣏Û ிඣͱʴ 4µųⒸՈ~͟ிΞ[ ÷ᾬ ĉŐẟ࣏੥ˊ3ͱƌ੥ˊ3᪂̣੥ˊ 3â੥ˊ ǡ᪸ ŭ+£࿁ǡۅȭzͱʴÏ ᜬ߾ŷȺỄϦẔᜐʐþɈẔᜐՈẟ࣏4 tr࢑dz)਍Ǒʐ☢dz) ਍Ǒ4Ȑr̶rźɍ zombie ʐstop ਍ǑՈr ȅK ՈḰࢿ4֜ޅLinux0.11 Ոẟ࣏µƧ^ƣˊՈ]͆Pʳ ]ƌńẟ࣏ͱ ǭºͱƌȕ Fs âிඣՈǒɴ4 Lib ⏂ȉՈrȅĆϬ4Ոß4 mm: ȭzͱƌՈ੥ˊՈâĹzẝₐ4 kernel ^ẟ࣏ிඣƅ͟ՈȈ࢑ǒɴό:῁ń ẝₐ Ǫ̲ P‡áɶ᪂̣Ո̱ňKńẝₐ4 include: ȭzȈ࢑ϔՈ̌Š ȈିՈǃǎ5῁ńẝₐ4 init: ẝₐɥPâ main.c4̱ňிඣՈ!ϧĚ1ň῁«ńẝₐǀtՈ4 ΢4rẝₐ4Bootsec.s, setup.s, head.s῁ۅ boot: ᩥਜ਼ƶՈȳ¬Ï Šuȭ Linux0.11 Ոόâ͕ɆP੄ᡅՈ᪸ ۅȌÏ &r5ƫ̓Ǫ ඣՈȖƨ̱ň ŷΞȳ¬P࣏Û਍4 ඣ֜4 ɥΙʻ Windows ிඣՈ ᰈļ ੥ˊ„P ʳ Ϭ›dzÑ-ϬƷǡǀtP ‡ȭ̱ňி ȌƷØȭrᢧ̱ňிඣňϬ]«ǔ̓4◄ᡅͼ͛ՈPிඣƉ¥࣏Û« sh ƷĹzâி Ȗzͱʴ ȴƇՈ᫇ϬǡǀtP‡Ȗƨ£࿁Ո4໐ẝ‡࣏ÛՈ࢑ି njŇǜWĚ ż'ᡅՈ« ü&\᩾«ிඣƉ¥࣏Ûẜ«Ϭ›àϬ࣏Û ῁« ۅȌՈ±±«ிඣͱʴՈÏ ẝₐ ňிඣՈ඗Ȁ« ̱ňிඣ«☢„Ո ̩ƾՈ IJ«ń Linux0.11 njºǣὧ4Ո੄ř4ȭzϬ›ǡ᪸ ̱ ᔞŃâிඣՈΓť4IJ« ẝ‡]ᱷ]ĆƽˑŌȭ̱ňிඣՈ͑⒬Ո4 ɴẟ࣏Ȑǹʐ~! Ո PV ̱ň਍4Ȑr Ʒ±±Γť Minix1.0 Ոâிඣ K ̵ƅȭ ตචʐ ƫ4IJ« ϵzẝČƨǔĺ ü ǸKƅ̶᩼äƫƷ̵ƅūϬ4 ŷΞඃ࣏ 3džͱƌ3ǒ ʸśՈdzËᜐâ ϞႷẔᜐÝ̠ˊâ Γť ̶ẟ࣏4Ʒ-Ϭr ǔ̶ńƣˊ᫂Zȴ 4Ո ä 2Ƿ4Ʒ ĉŐrẟ࣏Ո੥ˊ3ͱƌ੥ˊ 3᪂̣੥ˊʐâ੥ˊ4 ńẝ̱ňிඣ ZdzÑẔᜐ .out ₓń 1 WᜐۅLinux ̱ňிඣՈČ ƨǔ̶ 0.11 Č« Linus ৰPǷśǕOՈČ ƨ Ï ৰPতৰPতৰPতৰPত ẴẴẴẴ ৰ 9 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ dzᢅ àϬ࣏Ûżඌ«-Ϭிඣ᫇Ϭǡǀt^̱ňிඣՈϕՈ4 ǀ͔ͼ₎:ۅ ļ Ě P.1 µųⒸՈ~͟ிϦႮz9 ৰ 10 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ [ĚƮᬥՈ᪸Šrẝϕ࣏ 9̱ňிඣšȰȆऺ:PR4 ׏ǀrẝPত 7Ȓ ŌKdzÑϬ˛ේɆP੄řՈšȰ࣏Û4ͣĿՈǒɴ 5ͩdzÑdž ᢅ 4 ̩ƾՈᾬ wjKjLw~rjKu âՈ ~rjK€ϔ ẝϔ«Ϭ I ᪱ᣄේ΅Ո4ẝ̓« Ϙͱʴ ż& Ո ŊŌŜ ញ͑4ּàՈ Ǹƌ„ !ϧĚ̠ˊ„ ᪂า Ιͱƌ) ☦ żඌ᫇Ϭ ᜬ ʐ i{|ɴᾬɉȳẴ 3}{|͔ɴɉȳẴ৪ᜬ ĆȺ J{|)ȕₓᜬ zMrsun ẝᾬ ȭàՈâ«wxqqLwyMrsun4 ۅ᪱ᣄේ΅ՈÏ ͱʴâՈ͐ᾬ«Ϭ˛ේ 4ۅ̠4ẝrிඣḰ͑ljĈµś Ōϧ ËᜐĹz STSSSSS ̠ՈÏ Ŋ̴᪂าP‡ிඣՈܰâ᪂̣ ϢȒȺͱʴâºSTaSSSS ̠ࢿ ႷST SSSSS QMLkoun ᾬ wxqqLwQMLkouQ4ۅḰȕǪPǒµś[ẔᜐՈ˛ේ᪱ᣄÏ Ɵ4ƟšȰ࣏ÛȺிඣ ញ͑ͱƌr Ćº߾8iqrsjKtuuu 9ẝǝǍʻ4ញ͑ǀtȒ ȋ: ࣏ÛǀtՈ ẝ࣏Û«Ϭ˛ේ᪱ᣄේ΅Ո ΢ ńȳ¬֜ՈৰP «ľ ϵ \JYQ ¤ṁ4ͱƌ ញ͑4ŌŜ STlSbSS ̠ żȒȺ ͱʴâ ញ͑4 STaSSSS4ẝẋ࣏«ϵிඣՈšȰ â Ɵ ijKkT ிඣ ŌϧẔᜐr Ⱥ Ⴎ=ញ͑4ඡȭŌŜ STlSSSS ͹Ⱥ͢ȒՈ bm ƋᅆnMLko 4 ẝɥ«ȭᩥਜ਼ƶȳ¬ẋ࣏ՈPż੄řՈȳẴ4 ]& 4ẝ ₐ᪸Ոȳ¬֜^dzÑ«ܰ֜KdzÑ«ḳ֜͢ÂՈᡃ uۅḰ4ẝₐŌϧËᜐ Ǹ̠ՈÏ ញ͑4 ඡȭͱƌŌŜ STSdISS ÂᲷ ȕₓᜬ4 żȒ \JYQ Ⱥȳ¬֜ՈৰP«ľ`ab Ƌᅆ JYQ ̴ẟᜐPிՈிඣ Ⴎ̼ ϢȒ!ϧĚĹzŌŜ S Ո)\ 4ۅXYZ[\JYQ ᰻ϧĹาՈÏ K ɥ« ۅƌ„ՈȨ« STSSSS4ü Ǹ IHO Ōϧ Ոr ȅ«ËᜐĹzŌŜ STWWWWS ̠ՈÏ Ɵ HI ȳ¬r JKLMN ிՈ IHO Ŋ̴ẟ͑Ո«ǒµś IQ Ǹƌ„ՈȨ& STUUUUVJH Ǹ šȰՈවẴšȰՈවẴšȰՈවẴšȰՈවẴ ৰxতৰxতৰxতৰxত ிඣՈšȰிඣՈšȰிඣՈšȰிඣՈšȰ ৰ 11 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ                                               ̴ņএP˛ේâLMnLurn~ ṗ͑ &rƫzˊᢧ&¬4ᡅȺǜₓՈǎ5΢ń࣏ÛՈɲᾬ uØǡ׏PɃ࣏Û4 ȘȺ͢ǜ&uMTMâʸśɥ]ĆǕϣ⏝᪳r ü&Ʒ«ϵּàՈ̱ňிඣǡᢧ₎ËᜐՈ4 ՈQ☦ɥĆūǣᩥਜ਼ƶËᜐǕϣ⏝ ᪳4IJ« ΞۅâՈŌ͐ .ÛËᜐ Ξ ȘȺǜₓ΢4rÏ ÑËᜐՈrȅɥ «º¤4ۅȰՈ ɥ«ń̵ƅçŁՈ̱ňிඣՈ̑Ρ[ᩭᩥਜ਼ƶËᜐՈÏ Ϭzš»῁ۅՈȒ ṽ ẝ^ Ở„Ո˛ේνnj ඝϦՈ ŷƄ ]͆Pʳ4ẝ«ü&ẝₐՈÏۅÏ ՈrȅdzÑǕɴ ẝό˛ේâ¤ƅՈǜₓǎ5 ῁«΢ ńËᜐۅń׏ijKkT˛ේÏ rņᩲ̶׏׏ ˛ේՈR4udž໇Ո«ě̓ƚʌࡓࠩ ໅TՈ9˛ේ᪱ᣄ࣏Û᪂ᩥ:ẝƨR 4 ۅ੄ᡅՈ·එP‡˛ේ᪱ᣄՈ᪱ͩ4 ń׏Ïۅu ńĆńÏ ۅ&rƫzˊᢧ[☦ՈÏ ᪕Vẝ«P࢑||h᪱ͩՈ˛ේ᪱ᣄ࣏Û4 ūϬ }ŽOhՈ˛ේ࣏Ûʸś ◄ᡅϬ }ŽOh Ոrnhẟᜐේේ᪕„rn‰ŠʐẢȉ „Ns‰Š ໐yMrsunh \qqLnMLunh ʐnMLkounh₋ϬẕĨzJKLMNhՈ˛ේ᪱ᣄ᪱ͩ ◄ᡅūϬJKLMNh‰S‰Šh˛ේ වẴۅවẴÏۅවẴÏۅවẴÏۅÏ ǀ͔ͼ₎:ۅ ļ Ě x.1 â¤ṁẋ࣏ϦႮz9 ৰ 12 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ɥdzѧ¤ńẝâՈɲᾬ4ۅ᪙4ẝÏ ͱƌ4Ξ ȘϬৰxŬḳ֜ Ɇâிඣ ֜ Ɵ Ⱥͱʴâ¤ṁǀtȒ ɥ◄ᡅȭḳȥ ẟᜐ ϟ ẝâේ᪕Ȓ΢4šȰ֜ՈৰPĭˊ«ľ ϬzȺ setup.s ʐ head.c â ¤ṁ4 ŠBootsec.s âՈ᪸ŠâՈ᪸ŠâՈ᪸ŠâՈ᪸ Ȓᾬ4ۅǜₓՈǎ5῁«΢ńrÏۅü&ẝƣü ijKkTՈšȰÏ ǷՈ᰻ϧͥɥdzÑr4ףᡅ¤͑PᲷḰūÐū͢ Ჷ4࣏Û ᾬ.ÛËᜐ4 SW̵ƅּàՈƶ„ūÐüǸ ẝ࣏Û ɥ⏝᪳r4̿ ᩭ͢ǷܲËᜐ੄ř Ǯ◄ ΞȘẝ࣏Û«ºžžžžŸSaSbŌϧËᜐՈ Ʒɥ«ǷܲՈ4 IJ« Ʒ« Ǯdz࿁º࣏Û͐ žžžžŸSaSb SS SS ZY¡ iV ¢SSSS£ ŸžžžžŸSaSa b IQ žžžžŸSaSS SW {\ SW Ȑ|Q|uQZâPʳ Ⱥ͢:ňt|Q|buIYZ4Ǒ˛ේȒǣ4                                                       uØ͹ņএPâ|Q|buQZ ṗ͑ «ּȐՈ4 |Q|uIYZՈϔǒ« bSS SSSW ϔǒ SW΢ńâՈ żȒṽ4dz ᢅ^uØ̿ᡅՈ4Ո࣏Û žžžžŸSaS  SW žžžžŸSaSa SS SS ZY¡ iV ¢SSS £ ŸžžžžŸSaSS b IQ ΢4rȒṽ4ේ᪕t|Q|uIYZâȒ Ϭ{\O}Ǒ˛ේǣ4 ẝ࣏Û ̵ƅǒ┉͛5 ±±«Ⱥ {|ՈȨSW΢͑ iǸƌ„4ẝ ₐ«ȺǜₓՈǎ5         ৰ 13 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ! versions of linux ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current ! SYS_SIZE is the number of clicks (16 bytes) to be loaded. ! Š᪸ۅ᪸ŠÏۅ᪸ŠÏۅ᪸ŠÏۅÏ Ě x.2bootsec.s ϕ࣏Ě Ո੄ᡅϕ࣏ĚۅՈ੄ᡅϕ࣏ĚÏۅՈ੄ᡅϕ࣏ĚÏۅՈ੄ᡅϕ࣏ĚÏۅÏ ৰ 14 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ! 0x301 - first partition on first drive etc ! ROOT_DEV: 0x000 - same type of floppy as boot. ENDSEG = SYSSEG + SYSSIZE ! where to stop loading SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). // ͱʴâūϬՈɉŌŜ SETUPSEG = 0x9020 ! setup starts here // Setup âȺᡅūϬՈɉŌŜ INITSEG = 0x9000 ! we move boot here - out of the way // šȰ࣏ÛႮᵯɥĆࢿ4 0x9000 ɉ̠ BOOTSEG = 0x07c0 ! original address of boot-sector // ȳ¬֜ՈৰP«ľ¤ṁ4ՈɉŌŜ SETUPLEN = 4 ! nr of setup -sectors // setup.s ේ᪕ȒՈâńȳ¬֜ŤϬՈ«ľϔ« 4 .text begbss: .bss begdata: .data begtext: .text .globl begtext, begdata, begbss, endtext, enddata, endbss ! loads pre tty fast by getting whole sectors at a time whenever possible. ! read errors will result in a unbreakable loop. Reboot by hand. It ! The loader has been made as simple as possible, and continuos ! ! buffer cache as in minix ! kernel size should be enough, especially as this doesn't contain the ! problem, even in the future. I want to keep it simple. This 512 kB ! NOTE! currently system is at most 8*65536 bytes long. This should be no ! ! at 0x10000, using BIOS interrupts. ! It then loads 'setup' directly after itself (0x90200), and the system ! ! iself out of the way to address 0x90000, and jumps there. ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves ! ! bootsect.s (C) 1991 Linus Torvalds ! SYSSIZE = 0x3000 0x30000 ȭàՈ« 192k Ƌᅆ ẝ̓ɃȭzƟQՈͱʴǡ᪸>ඓᱷ̻r ĖūÐǔʻ« C ᪱ᣄՈ#define ᪱ǩ ϬzǃŻdž4 ! ৰ 15 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ :load_setup // Ǫ̲ńϔȨQ☦¤ZUń ?)0 ේ᪕„ᜬ߾ẝ«এŷϔ HI ʃȣ&าĹ4 ūȕϔǒ෗Ξľ ΞȘϦ⏝ // >?@A  ᡅาĹ 1 ȥ¬„ǻΞȘ«ܰ֜ǻ2͐ޅ // 2   Ĺ$0 -1' ἗ǻʌޅ ' -. Ĺ  Ōϧ«ľ$἗$ɭ☦'ǻՈĺ ) Ĺ"ޅ " //  ◄ᡅᪿϦՈ«ľϔₓ // ľ4ͱƌ»֜ޅ ᜬ߾ᪿ  –  ΢Ո«£࿁ǻ  // // ᪿ«ľ // int 13 ՈūϬ5ͩ // ɴń«Ⱥ setup â¤ṁ4ͱƌƟՈr?r ẝ ₐūϬr BIOS Ո 13 ǻ)(int 13) ! Note that 'es' is already set up. ! load the setup -sectors directly after the bootblock. mov sp,#0xFF00 ! arbitrary value >>512 mov ss,ax // ̓ɃɥdzÑr Ȣʄ 0x200 4 // ᪂าȢʄǸƌ„ ẝŌŜɨṇ ╓͛ ǮᡅƷՈȨ ẠẠ̓ z 0x200 ! put stack at 0x9ff00. mov es,ax mov ds,ax go: mov ax,cs  // ɉۅɉּȐ ü&ẝrȅ¤ƅՈϔǒ῁ƌ΢ńÏۅ// ᪂าȈǸƌ„ՈȨū͢^Ï jmpi go,INITSEG // ẝₐ«ᲷḰ4 0x9000go ̠ º,ՈͱƌɉŌϧËᜐ // ɉⒸᲷḰ ūÐ ʸś«: jmpi ȻࢿŌŜ ɉŌŜ4ňϬɉŌŜCS, ȻࢿŌŜ IP 4 movw rep sub di,di sub si,si mov cx,#256 mov es,ax mov ax,#INITSEG mov ds,ax mov ax,#BOOTSEG // ňūÐ dzÑń9˛ේ᪱ᣄ࣏Û᪂ᩥ:ẝƨRՈ 7.4 ᅆɡ44 ̱// ȺšȰ࣏ÛႮᵯº 0x7C00:0x0000 ̠ࢿ ¬4 0x9000:0x0000 ̠4ẝ ₐūϬrϔǒ start: entry st art // Ćńϵේ᪕„Ⴎ¬ՈŻdž ‑ाⒸ ÂØ // ẝₐ±«࣏ÛՈ͑ǧ ÑZÂ]«ǜₓՈǎ5 ේ᪕„̵ƅ&ÂØ ROOT_DEV = 0x306 ‑᪂̣ǻ // ẝₐ&ʵâிඣ ৰ 16 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ // DX,DL= ᜐ Ȩ CH,CL= ƟQ̵ʃµś // ẘúȨ º߾Ո)ǻĚƮ5śr« 0 03 bh // ah // ̵ᪿʃĹา // system …..”ńʃ¡ZṗϦ◄ᡅūϬ BIOS Ո 10 ǻ)4ʸśΞ[ // ȠZɥᡅ¤ṁͱʴâr ń¤ṁẝâՈrȅĆńʃ¡ZṗϦ8Loading ! Print some inane message mov es,ax mov ax,#INITSEG mov sectors ,cx seg cs // ɥ«᪸ sectors «΢ń CS ɉՈ // seg SEGMEN ūÐᜬ߾[Pǝ˛ේ᪱ǩūϬ̱ňϔ΢ń SEGMEN ɉ ẝₐ« CS mov ch,#0x00 int 0x13 mov ax,#0x0800 ! AH=8 is get drive parameters mov dl,#0x00 džϔᜬ4֜ޅ// es:di ūȕḳȥ ϔ dl = ȥ¬„ϔₓ͐ޅ// dh = ż̓ // 6-7) ἗ǻʌ 2 Ĺ(Ĺޅ἗ż̓«ľϔ(Ĺ 0-5) ż̓ޅ἗ǻՈĺ 8 Ĺ cl = ɣޅ// ch = ż̓ ah = 0 al = 0 bl = ȥ¬„ିƧAT/PS2 // 4ۅ CF าĹ Â ah = źɍ// ΞȘϦ⏝ // ẘúǍʻ 4 ᡅาĹ 7 & 1// ah = 0x08 dl = ȥ¬„ǻΞȘ«ܰ֜ ȥ¬„džϔ INT 0x13 ᫇ϬʸśʐẘúǍʻΞ[֜ޅ// ǚ ȥ¬„Ոdžϔ Ľ/«ɣ἗Ո«ľϔₓ4֜ޅ// ǚ ! Get dis k drive parameters, specifically nr of sectors/track ok_load_setup: j load_setup int 0x13 mov ax,#0x0000 ! reset the diskette mov dx,#0x0000 // ah = 0 Ϧǧdžϔ\ Ո̩Ĺ ūϬ BIOS Ո 13 ǻ)Ոৰ 0 ǻ)֜ޅ // jnc ok_load_setup ! ok - continue int 0x13 ! read it mo v ax,#0x0200+SETUPLEN ! service 2, nr of sectors mov bx,#0x0200 ! address = 512, in INITSEG mov cx,#0x0002 ! sector 2, track 0 mov dx,#0x0000 ! drive 0, head 0 ৰ 17 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ mov ax,#0x0208 ! /dev/ps0 - 1.2Mb mov bx,sectors seg cs jne root_defined cmp ax,#0 mov ax,root_dev seg cs // Ȑˊ /dev/at0 (2,8)ūՈ« 1.2M A ȥ¬„ ͢᪂̣ǻ« 0x0208 // ü& 7*4 + 0 = 28 ¤Ñ /dev/PS0 (2,28)ūՈ« 1.44M A ȥ¬„,͢᪂̣ǻ« 0x021c 4 // ਍ /ȭàḳȥ A3B3C z Dtype «ḳȥՈିƧ 21.2M z 71.44M // nr & 0-3 // ń Linux ḳȥՈ'᪂̣ǻ« 2 Ƶ᪂̣ǻ = type*4 + nr ͢ // Z☦Pᜐ᪂̣âՈȯ5 // ܲǎ4áūϬ/dev/PS0 (2,28) ẜ« /dev/at0 (2,8)4 ἗«ľϔǡޅɥ◄ᡅʵǒ BIOS ĉɎՈɣ// ɥָȉūϬඝǎՈ᪂̣4Ȫ 4Ξ Ș>ඓūǎr᪂̣ (!=0) // ǸȒ u Ø̼ɡᡅūϬ ˮʵâிඣ᪂̣੄ࢴʵ᪂̣ ! on the number of sectors that the BIOS reports currently. ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending ! defined (!= 0), nothing is done and the given device is used. ! After that we check which root-device to use. If the device is call kill_motor ἗ȥ¬„Ոźɍrک// ͟⒱ȥ¬„ȠẂ ẝʳɥdzÑ call read_it // ᪿǚͱʴâ4ͱƌ mov es,ax ! segment of 0x010000 mov ax,#SYSSEG // ᪂าͱʴâȺᡅƌ΢4ՈɉŌŜ ! we want to load the system (at 0x10000) ! ok, we've wr itten the message, now int 0x10 mov ax,#0x1301 ! write string, move cursor mov bp,#msg1 mov bx,#0x0007 ! page 0, attribute 7 (normal) mov cx,#24 int 0x10 xor bh,bh mov ah,#0x03 ! read cursor pos // BH= ƟQՈº߾)ǻ BL= ʒɳ ±>ඓǣ4r̵ʃՈ᰻ϧĹา ẝȨ ⑃ò DXƋ৪ //CX ՈŊŌŜ// ES:BP =dž΅͑ՈƋ৪ // º߾Ƌ৪ ৰ 18 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ mov ax,sectors seg cs ok1_read: ret jb ok1_read cmp ax,#ENDSEG ! have we loaded all yet? mov ax,es rp_read: xor bx,bx ! bx is starting address within segment die: jne die ! es must be at 64kB boundary test ax,#0x0fff mov ax,es read_it: track: .word 0 ! current track head: .word 0 ! current head sread: .word 1+SETUPLEN ! sectors read of current track // ̭᩼uɣ6PƵȫ☺,ΞȘŌĽƅΙͣȏ njǔ6 ɥָ᪻ȉ༘ிuȫ4 Ո]̿‡࿁ūŌˊᢧƷՈͼ₎r ໐ƷՈǒɴȭˊᢧͱʴ̵ƅ¬4ƽˑ ¤Ñɥ // ףǒń«̩ƾuۅ἗4ẝɉÏޅṁͱʴâϬՈ ɣƵ῁«¤ṁP¤»ۅ// ẝɉÏ ! ! in: es - starting address segment (normally 0x1000) ! ! possible, loading whole tracks whenever we can. ! no 64kB boundaries are crossed. We try to load it as fast as ! This routine loads the sys tem at address 0x10000, making sure jmpi 0,SETUPSEG // ɴń¤ṁ඗ǛrdzÑËᜐ setup ࣏Ûr ! the bootblock: ! the setup -routine loaded directly after ! after that (everyting loaded), we jump to mov root_dev,ax // ljƌ᪂̣ǻ seg cs root_defined: jmp undef_root undef_root: je root_defined cmp bx,#18 mov ax,#0x021c ! /dev/PS0 - 1.44Mb je root_defined cmp bx,#15 ৰ 19 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ mov dx,head mov ch,dl inc cx mov cx,sread mov dx,track push dx push cx push bx push ax read_track: jmp rp_read xor bx,bx mov es,ax add ax,#0x1000 mov ax,es jnc rp_read add bx,cx shl cx,#9 mov sread,ax ok3_read: xor ax,ax mov head,ax ok4_read: inc track jne ok4_read sub ax,head mov ax,#1 jne ok3_read cmp ax,sectors seg cs add ax,sread mov cx,ax call read_track ok2_read: shr ax,#9 sub ax,bx xor ax,ax je ok2_read jnc ok2_read add cx,bx shl cx,#9 mov cx,ax sub ax,sread ৰ 20 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ .word ROOT_DEV root_dev: .org 508 .byte 13,10,13,10 .ascii "Loading system ..." .byte 13,10 msg1: .word 0 sectors: ret pop dx outb mov al,#0 mov dx,#0x3f2 push dx kill_motor: */ * don't have to worry about it later. * that we enter the kernel in a known state, and * This procedure turns off the floppy drive motor, so /* jmp read_track pop ax pop bx pop cx pop dx int 0x13 mov dx,#0 bad_rt: mov ax,#0 ret pop ax pop bx pop cx pop dx jc bad_rt int 0x13 mov ah,#2 and dx,#0x0100 mov dl,#0 mov dh,dl ৰ 21 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ĺาᢅ[Ě ¤ǚǣՈdžϔʐljНՈͱƌ STlSSSShŌϧՈĹาᡊ֚ǭrxqqLnMLh࣏Û¤ńՈŌ5 nMLkoh࣏ÛՈňϬ'ᡅ«-ϬXYZh\JYQh)ᪿǚƶ„ிඣϔǒ ÂȺẝ‡ϔǒljƌ4 ŠSetup.s Ո᪸ŠՈ᪸ŠՈ᪸ŠՈ᪸ dzѤŌȭšȰ࣏ÛՈˊᢧ4 ẟᜐĭˊɡ׏ ϬƷǡ ׏Ō:ňՈৰP«ľ֜ޅƅPǔΙՈḳâ WinHex ƷdzÑȭ «ָȉ«ľᪿ΅ϔ ẝϔ>ඓ]ń VC6.0 r4 4 ¤Ñ ◄ᡅń Windows98 [ūϬ Turbo C ǡǀt4᫇ϬՈ ἗੄řՈ5ͩک[ႷɅuẜ šȰ࣏Û ȑ/ ΅ńৰP «ľ  IJ«ń Windows2000 [«\ͩ੄řՈǀtẝ -1࣏Ո 4 ᆪ ҟ âḰdž&.com ʸśՈâńâ4ẝǑᯡ7QuPָ«ָȉǚΝ .exe âՈ Ņ ʸśՈâ ẝâƟϢ]࿁ň&šȰ࣏Ûr4¤Ñ◄ᡅūϬ exe2bin.exe ẝ࣏ÛȺ.exe uK᪙ɀ؄΅rPšȰ࣏Û ẝ࣏Û«ń MASM 6.0 [ේ΅Ո4ේ ᪕ϦǡՈ«.exe ͠ᱧՈ᪡ dzѺตZâ4Pઋǯ9̱ňிඣšȰȆऺ:Ոত ΅Ո]⏝4 ẝšȰ࣏Û ☢„Ոඓ ͤ ǔ̶šȰ࣏ÛȐƷɩ̿ǔ«ּʻ4Ξ ȘȭšȰ࣏ÛՈ᪂ᩥͫ ȒᩴȒᩴȒᩴȒᩴ endbss: .bss enddata: .data endtext: .text .word 0xAA55 boot_flag: // Û«ǷܲՈ4ẝʃȣᡅ˖΢ń 511 ʐ 512 Ƌᅆ̠ // ẝʃȣ ǔₑᡅ ü&BIOS ǮƅǕɴr 0xAA55 ẝʃᩴ7Ȓ±࿁ ᩨǎẝšȰ࣏ ৰ 22 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ՈyMrsunh࣏ÛණනẔᜐ4 ໐ẟ͑æbhĹljĈµśẔᜐ ÂᲷḰ4ĹzͱʴâżQ☦ᾬ :ᅳċ‰b`l Ⱥܰâ)ǻₑ,᪂า&STbSh[hSTbU4żȒ᪂าIHOhՈȋ:Ǹƌ„IXS º Ẵ৪ᜬǸƌ„ €jsLãʐ͔ɴȳẴ৪ᜬǸƌ„ €tsLだŌ ȳbShŌŜඃ ₑ ,᪂า )ȋ Ϙųȕ[ࢿ¬4ͱƌඡȭŌŜSTSSSSSh̠4ȉ[ǡ¤ṁ)ȳ ⑃ò]Ć᱉ẋǸȨ`abâ\ ϢȒnMLkoh࣏ÛȺnánLM~hµųºSTaSSSS[ST‰UUUUƟrᩨ&ͱʴிඣµųnánLM~hՈ Ո4 ẝdžϔᜬȭzÑȒՈ࣏Û«ǔƅϬՈ ̶᩼ϔ῁«Ởẋẝᜬǡǣ4ிඣՈǍʻ ǀ͔ͼ₎:ۅ_`` ļ Ě x.3 džϔńͱƌՈƌ΢ĹาϦႮz9[\]^ ৰ 23 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ! Š᪸ۅ᪸ŠÏۅ᪸ŠÏۅ᪸ŠÏۅÏ Ě x.4setup.s ϕ࣏Ě Ո੄ᡅϕ࣏ĚۅՈ੄ᡅϕ࣏ĚÏۅՈ੄ᡅϕ࣏ĚÏۅՈ੄ᡅϕ࣏ĚÏۅÏ ৰ 24 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ // «᫇Ϭ) 0x15 £࿁ǻ ah = 0x88 4 // ǚÍʉͱƌՈ̓ɃȨKB ! Get memory size (extended mem, kB) mov [0],dx ! it from 0x90000. int 0x10 ! save it in known place, con_init fetches xor bh,bh mov ah,#0x03 ! read cursor pos mov ds,ax mov ax,#INITSEG ! this is done in bootsect already, but... // ɴńȺ̵ʃĹาljƌṆ̃¶ȒūϬ ! posterity. ! ok, the read went well so we get current cursor position and save it for start: entry start .text begbss: .bss begdata: .data begtext: .text .globl begtext, begdata, begbss, endtext, enddata, endbss SETUPSEG = 0x9020 ! this is the current segment SYSSEG = 0x1000 ! system loaded at 0x10000 (65536). INITSEG = 0x9000 ! we move boot here - out of the way Š// ᢅ bootsec.s ᪸ ! NOTE! These had better be the same as in bootsect.s! ! ! for buffer -blocks. ! system to read them from there before the area is overwritten ! boot-block used to be. It is then up to the protected mode ! puts them in a "safe" place: 0x90000-0x901FF, ie where the ! This code ask s the bios for memory/disk/other parameters, and ! ! both setup.s and system has been loaded by the bootblock. ! and putting them into the appropriate places in system memory. ! setup.s is responsible for getting the system data from the BIOS, ! ! setup.s (C) 1991 Linus Torvalds ৰ 25 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ mov ds,ax mov ax,#0x0000 // ֜Ոᜬ4 // ܰ֜ Ոdžϔᜬ 0x90080 ̠ƌ΢ৰ 1  ܰ֜ Ոᜬ 0x90090 ̠ƌ΢ৰ 2 ܰ /̩: BIOS ƅ͟ // Ոdžϔᜬ ŊŜ4ᜬՈ⑃ò« 16 Ƌᅆ(0x10)4 [☦ɉ࣏Û // džϔᜬ௫ȉৰ 1 ᜬՈȒ☦ )ȕₓ 0x46 ՈȕₓȨKūȕẝৰ 2 ܰ֜ // ৰ 1 ܰ֜džϔᜬՈŊŌŜণϢ«)ȕₓ 0x41 ՈȕₓȨ໐ৰ 2 ܰ֜ 4 // ǚৰPܰ֜ՈǍʻ̩:ܰ֜džϔᜬ ! Get hd0 data mov [12],cx mov [10],bx mov [8],ax int 0x10 mov bl,#0x10 mov ah,#0x12 // ẝȨĆńඌ঳Ո!ϧĚūϬ // cx = º߾ťĽɳdžϔ // (0x00 - 64k, 0x01 - 128k, 0x02 - 192k, 0x03 = 256k) // bl = ƽញՈº߾ͱƌ // (0x01 - řᄶµś I/O ঳ǧ=0x3bX) // (0x00 - Ƶᄶµś I/O ঳ǧ=0x3dX) // ẘúbh = º߾źɍ // £࿁ǻah = 0x12 bl = 0x10 // ᫇Ϭ BIOS ) 0x10 Âǚdžϔ4 // ̼ɡº߾5śEGA/VGA ! check for EGA/VGA and some config parameters mov [6],ax ! al = video mode, ah = window width mov [4],bx ! bh = display page int 0x10 mov ah,#0x0f // 0x90004(1 Ƌ)ƌ΢ƟQ) 0x90006 º߾µś 0x90007 Ƌ৪ϔ // ẘúah = Ƌ৪ϔ al = º߾µś bh = ƟQº߾)4 // ᫇Ϭ BIOS ) 0x10 £࿁ǻ ah = 0x0f // ǚº߾ťƟQº߾µś4 ! Get video -card data: mov [2],ax int 0x15 mov ah,#0x88 ẝȨȺĆńͱƌՈ!ϧĚūϬ // 4ۅ CF าĹ ax = Ϧ⏝// ᆩϦ⏝ ̠ŌϧՈÍʉͱƌ̓Ƀ(KB) 4 // ẘúax = º 0x1000001M ৰ 26 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ... ! now we want to move to protected mode is_disk1: stosb rep mov ax,#0x00 mov cx,#0x10 mov di,#0x0090 mov es,ax mov ax,#INITSEG no_disk1: je is_disk1 cmp ah,#3 jc no_disk1 int 0x13 mov dl,#0x81 mov ax,#0x01500 // 02 --«ḳȥ(z͢Ʒdzࢿ¬᪂̣) ƅ change-line Γť 03 --«ܰ֜4 ƅẝ֜ CF าĹ01 --«ḳȥ ̵ƅ change -line Γť̵ -- 00; ۅ// ṗϦah = ିƧ // ṗ͑dl = ȥ¬„ǻ0x8X «ܰ֜0x80 ūৰ 1 ܰ֜ 0x81 ৰ 2 ܰ֜ // £࿁ǻ ah = 0x15 // -Ϭ BIOS )᫇Ϭ 0x13 Ոǚ֜ିƧ£࿁4 ৰ 2 ᜬ±►4 // ̼ɡிඣ«Ȫƌńৰ 2 ܰ֜ ΞȘ]ƌń ! Check that there IS a hd1 :-) movsb rep mov cx,#0x10 mov di,#0x0090 mov es,ax mov ax,#INITSEG lds si,[4*0x46] mov ds,ax mov ax,#0x0000 ! Get hd1 data movsb rep mov cx,#0x10 mov di,#0x0080 mov es,ax mov ax,#INITSEG lds si,[4*0x41] ৰ 27 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ call empty_8042 out #0x64,al mov al,#0xD1 ! command write call empty_8042 // Ōȳ A20 ŌŜඃ ! that was painless, now we enable A20 lgdt gdt_48 ! load gdt with whatever appropriate // ɉ«Ȫńͱƌ3ᪿ΅᩼dzÑǎ ͢ƷP‡ljĈµśẔᜐՈʃȣ4 3ɉՈĽƿ൫3 // ʻ4͢ĉŐɉՈ ż̓⑃ò└:(16 Ĺ)3ɉՈඃɳȖŜ32 Ĺ ՈǍ ɉųۅ// ɴȳẴ৪ ᜬՈɣȳẴ৪-(8 Ƌᅆ)ȳẴrljĈµś[ϔǒʐÏ // lgdt ūÐϬz ¤ṁ͔ɴȳẴ৪ᜬ (gdt) Ǹƌ„ ̱͢ňϔʸś^ lidt ūÐ Ոּ Ȑ4͔ lidt idt_48 ! load idt with 0,0 \2a ūÐϬz¤ṁ)ȳẴ৪ᜬ$\2a' Ǹƌ„ ƷՈ̱ňϔ« 0 Ƌᅆ // // ẝₐɥ«ẟᜐljĈµśՈ᪂าr Ȓ☦ƅ͟zƷՈ᪪ඊȳẴ4 mov ds,ax mov ax,#SETUPSEG ! rig ht, forgot this at first. didn't work :-) end_move: ! then we load the segment descriptors jmp do_move movsw rep mov cx,#0x8000 sub si,si sub di,di mov ds,ax ! source segment jz end_move cmp ax,#0x9000 add ax,#0x1000 mov es,ax ! destination segment do_move: cld ! 'direction'=0, movs moves forward mov ax,#0x0000 8 Ƶࢿ¬r4 // 0x80000 ŤϬr 20 Ĺ ໐ cx Ǹƌ„« 16 ĹՈüǸǮ࿁ ü&// Ƶ PƵࢿ¬ 0x10000 Ƌᅆ4&¬4]PƵɥî 0x80000 ƋᅆՈͱǭࢿ¬ǀɦ // ੥ˊr &ிඣͱʴН[PųĖ ǎՈ ľǻ 4m[Ո ɥdzÑ ╓ƫϬr4ẝ ₐ«P͝ࢿ ¬r 8 ՈĹา4ẝʳɥdzÑ5ƫÑȒՈͱƌ // (512k) ϘųŌȕͱƌĺ঳ࢿ¬r 0x1000064k // îϘ system µųࢿ¬4 0x00000 Ĺา ŷîº 0x10000 4 0x8ffff Ոͱƌϔǒų ! first we move the system to it's rightful place cli ! no interrupts allowed ! ৰ 28 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ .word 0x00eb,0x00eb out #0x21,al mov al,#0x01 ! 8086 mode for both // ᪂า&☢ĽȞǀ͔΀ͳ ☢෗Ξ ☢Ⴎ¬ EOI 86/88 5ś // !ϧĚ'ȋϹᲳՈ ICW4 .word 0x00eb,0x00eb out #0xA1,al mov al,#0x02 ! 8259-2 is slave // ᜬ߾ºȋϹᲳẢȉ4'ȋϹᲳՈ IR2 ̠ // !ϧĚºȋϹᲳՈ ICW3 .word 0x00eb,0x00eb out #0x21,al mov al,#0x04 ! 8259-1 is master // ᜬ߾'ȋϹᲳՈ IR2 ǧẢȉºȋϹᲳ // !ϧĚ'ȋϹᲳՈ ICW3 .word 0x00eb,0x00eb out #0xA1,al // ᪂าºȋϹᲳՈ)ǻº 0x28 Ōϧ // !ϧĚºȋϹᲳՈ ICW2 mov al,#0x28 ! start of hardware int's 2 (0x28) .word 0x00eb,0x00eb out #0x21,al // ᪂า'ȋϹᲳՈ)ǻº 0x20 Ōϧ ẝɥ«r⍣)ȭàՈ int 0x20 Ոƣü // !ϧĚ'ȋϹᲳՈ ICW2 mov al,#0x20 ! start of hardware int's (0x20) .word 0x00eb,0x00eb out #0xA0,al ! and to 8259A-2 // !ϧĚºȋϹᲳՈ ICW1 ᪂า&Ϲ¿ᢪǕ ൫༘ ūϬ ICW4 .word 0x00eb,0x00eb ! jmp $+2, jmp $+2 out #0x20,al ! send it to 8259A-1 // !ϧĚ'ȋϹᲳՈ ICW1 ᪂า&Ϲ¿ᢪǕ ൫༘ ūϬ ICW4 mov al,#0x11 ! initialization sequence // ȭ 8259A ȋ:„ẟᜐ!ϧĚ dž׏9ȉǧäƫ:Ո P122 ! have to reprogram the 8259's, and it isn't fun. ! which is used for the internal hardware interrupts as well. We just ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f, ! messed this up with the original PC, and they haven't been able to ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really ! we put them right after the intel -reserved hardware interrupts, at ! well, that went ok, I hope. Now we have to reprogram the interrupts :-( call empty_8042 out #0x60,al mov al,#0xDF ! A20 on ৰ 29 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ .word 0x00C0 ! granularity=4096, 386 .wo rd 0x9A00 ! code read/exec .word 0x0000 ! base address=0 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) .word 0,0,0,0 ! dummy gdt: // .word ĖūÐᜬ߾͢Ȓɣϔǒ-ŤϬ 2 Ƌᅆ4 Ո᪸Š4 // ǒɉȳẴ৪4Ȓṽƅ͟z͔ɴȳẴ৪ᜬGDT ɉȳẴ৪ ৰ 3 -«ிඣϔۅ// ȳẴ৪-4ৰ 1 -\Ϭ IJ/ƌń4ৰ 2 -«ிඣÏ  // ͔ɴȳẴ৪ᜬŌϧ̠4ȳẴ৪ᜬ ϵ̶  8 Ƌᅆ⑃ՈȳẴ৪ -ඈt4ẝ ₐඝ Ϧr 3 ret jnz empty_8042 ! yes - loop test al,#2 ! is input buffer full? in al,#0x64 ! 8042 status port .word 0x00eb,0x00eb empty_8042: ! the machine, and we probably couldn't proceed anyway. ! No timeout is used - if this hangs there is something wrong with ! This routin e checks that the keyboard command queue is empty jmpi 0,8 ! jmp offset 0 of segment 8 (cs) lmsw ax ! This is it! mov ax,#0x0001 ! protected mode (PE) bit // Word) 4Ǹƌ„ CR0 ͢ɨĽĹ 0 า 1 ȺȰႸ CPU 1ňńljĈµś4 // ẝₐ᪂าẟ͑ 32 ĹljĈµśẔᜐ4 Ŋ̴¤ ṁƶ„źɍƋ(lmsw - Load Machine Status ! absolute address 0x00000, in 32-bit protected mode. ! we let the gnu -compiled 32-bit programs do that. We just jump to ! things as simple as possible, we do no register set -up or anything, ! Well, now's the time to actually move into protected mode. To make ! ! "interesting" anyway. This is how REAL programmers do it. ! The BIOS -routine wants lots of unnecessary data, and it's less ! need no steenking BIOS anyway (except for the initial loading :-). ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't out #0xA1,al .word 0x00eb,0x00eb out #0x21,al // ȭ'ºȋ:„ǕϦ OCW1 ʁÐ ʃᐁP‡) mov al,#0xFF ! mask off all interrupts for now .word 0x00eb,0x00eb out #0xA1,al // !ϧĚºȋϹᲳՈ ICW4 ৰ 30 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ └)ȳẴ৪ᜬǸƌ„ J{|X ȖŌŜ А ͔ɴȳẴ৪ᜬǸƌ„ }{|X ȖŌŜ А└ \J| d4\J|aŠ \J|a`4\J|S ἗rẝŌŜɥdzÑ ̼௦ᜬՈͱǭr ک ȳẴ৪ᜬՈŊŌŜ ȖŌŜ͔ɴ) ǒՈʸśΞ[ ńᩥਜ਼ƶ,᪂า Ǹƌ„ }{|X ʐ i{|X ǡƌ ʔP඗ȀᜬՈ ȖŌŜ4 }{|X ϔ JKLMN «ẝʳɆ4Ո ʵǒɉǸƌ„Ոͱǭâ48ŌŜɉȳẴ඗Ȁ94ʵǒɉǸƌ„Ոͱǭâ48ŌŜɉȳẴ඗Ȁ94ʵǒɉǸƌ„Ոͱǭâ48ŌŜɉȳẴ඗Ȁ94ʵǒɉǸƌ„Ոͱǭâ48ŌŜɉȳẴ඗Ȁ94  „hrT b «ūϬ {Q ɉǸƌ Ǹƌ„ ໐ ~q ~ohSlS Sy ūÐ ɥ«ūϬ IQ ɉ ʵǒūÐՈିƧǡΟǎūϬ¬4ʳՈǸƌ„ʵǒūÐՈିƧǡΟǎūϬ¬4ʳՈǸƌ„ʵǒūÐՈିƧǡΟǎūϬ¬4ʳՈǸƌ„ʵǒūÐՈିƧǡΟǎūϬ¬4ʳՈǸƌ„ ŷΞ a rP‡ିƧՈ᪸Šʐƿ└4üǸPūÐȯâŌŜՈẋ࣏dzÑŐΞ[ ńljĈµśɉǸƌ„Ո͛5>ඓǜr ƷՈͱǭ«PȭȖŌŜՈP௦šÂ¤Z Ĉ5ś[Ո 80386 ǎ͢ේ࣏:4 ΞȘ̿r ᢧŰ̶ՈǍʻdzÑ ɡ׏9 jKLMN ிǺ̠ˊ„඗Ȁ 3ේ࣏ʐ ȉǧäƫ ͔̓:ʐ9lj ՈËᜐ ẝ ₐ̴ȭljĈµśẟᜐPƵ੄řՈ᪸Š4ۅǒµśΝ&ljĈµś4&r ƫzˊ ᢧÏ ijKkT «Ẕᜐ ńljĈµś[Ո ¤ÑńŌϧËᜐ ijKkT Ոͱʴ7Q◄ ᡅȺͱƌՈµśϵ ljĈµśɉś੥ˊᾬ ljĈµśɉś੥ˊᾬ ljĈµśɉś੥ˊᾬ ljĈµśɉś੥ˊᾬ endbss: .bss enddata: .data endtext: .text .word 512+gdt,0x9 ! gdt base = 0X9xxxx .word 0x800 ! gdt limit=2048, 256 GDT entries gdt_48: .word 0,0 ! idt base=0L .word 0 ! idt limit=0 idt_48: .word 0x00C0 ! granularity=4096, 386 .word 0x9200 ! data read/write .word 0x0000 ! base address=0 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) ৰ 31 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ɉ ϢȒȭǸϔǒɉẟᜐۅ/ȑäƫ ŷϬPdz΅ՈϔǒɉȳẴ৪ǡȳẴ ᪩Ï ȑ/ūϬ ɉẟᜐ΅̱͑ňۅɉʇ«]dz΅Ո ᆩ◄ᡅȭÏۅɉȳẴ৪4Ïۅ ɉ ּàՈȳẴ৪ ɥ«ÏۅᜐՈ IJʇ«dz ᪿՈ4 a ᜬ߾ɉ«dzËᜐɉ ŷÏ ɉ&ϔǒɉ ּàՈȳẴ৪Kɥ«ϔǒɉ€ĉŐȢʄ ɉȳẴ৪4ϔǒɉ«]dzË ɉẜ«ϔǒɉ Ϭ৪ǻ ʃᩴ4S ᜬ߾ۅ͢ՈĹ æ ū߾¤ȳẴՈɉ«Ï Ẵ৪«Ȫᝯ᪃⒲ẋ4 ‰S扊 î᪩Ĺา& a ᜬŠȳẴ৪> ᝯ᪃ ⒲4̱ňிඣdzϟ᪙᪃⒲Ĺ >ܲǎȳ ᝯ᪃ ⒲ ahᜬ߾ɉ> ᝯ᪃ ⒲4Ɵ îȳẴ৪Ոּàọō Ƅញ͑4ɉ Ǹƌ„r ͢ՈĹ S ū߾ȳẴ৪«Ȫᝯ᪃⒲ẋ Ϭ৪ǻ €MnnMs ʃᩴ4S ᜬ߾ɎƦ €  |H ᪸ŠƌʔɉȳẴ৪¤ȳẴՈƌʔɉՈͣĿʒɳ4 ৪ʐ⒬ȳẴ৪€{|S4 €æ {| Ĺ᪸ŠȳẴ৪ՈିƧ4ȭzƌʔɉȳẴ৪໐ᣄ {| a Ñľ/ ^ிඣɉȳẴ Οǎȭ᪩ɉ࿁Ȫ᪃⒲4 €b {Hi ᜬ߾ȳẴ৪Ľƿ൫͝ b Ĺ4Ʒᢈǎr ¤ȳẴɉՈĽƿ൫ ϬzĽƿ̼ ɡ Ñ ᪩ȳẴ৪ẟᜐͱƌ᪃⒲rĆš᰻Ŏ„4 Ոɉƌń ŷńͱƌHS ᜬ߾ȳẴ৪ȭŌŜḰdž \ά ŷ᪩ɉ]ƌń4ūϬ €a H Ĺࢴ&ƌńĹ4Ha ᜬ߾ȳẴ৪ȭŌŜḰdž«ƅάՈ z້᪸᪩ȳẴ৪ ¤ȳẴ Š᪸ ʒ ɳ } { S ¡i ij~jL€aluuuaŠ H {Hi {|a |H ȳẴ৪ ƌʔɉ \J|d \J|Š \J|` \J|  \J|æ \J|b \J|a\J|S\J|d\J|Š\J|`\J| \J|æ\J|b\J|a\J|S \áLMh~Š \áLMh~` ij~jLM€a`uuuS ȳẴ৪ \rnM€æauuub  LLãjxkLMn QMt~MKLh\rnM€bæuuuS QMt~MKLh Zd ZŠ Z` Z  Zæ Zb Za ZSƌʔɉ ŌŜɉȳẴ৪ŤϬ ‰ Ƌᅆ͢ʸśΞ[ º8ŌŜɉȳẴ඗Ȁ9ǣ4ȖŌŜ4º8ŌŜɉȳẴ඗Ȁ9ǣ4ȖŌŜ4º8ŌŜɉȳẴ඗Ȁ9ǣ4ȖŌŜ4º8ŌŜɉȳẴ඗Ȁ9ǣ4ȖŌŜ4 %%%% ¤᪃⒲ɉՈĽƿ൫ẟᜐɨṇ Ñܲǎ«Ȫ̭࣏᩼Ûȭ᪩ɉՈ᪃⒲4 zĽƿ̼ɡ4hXHi ƋɉՈϬͩ«ɣƟ࣏Û᪙Ě᪃⒲Pɉr ᡅîƟQĽƿ൫^ ū߾ºɴᾬȳẴ৪ᜬ i{| ᪿǚȳẴ৪ 4ọōƄՈżĺĹ«᪻˖Ľƿ൫ XHi Ϭ ϬȳẴ৪ᜬū߾Ĺ ʃᩴ& |J |J S ū߾º͔ɴȳẴ৪ᜬ }{| ᪿǚȳẴ৪|Ja dzÑ׏4ż̶̭᩼ b`Š 4 ɉọōƄՈৰ b Ĺ«šۅȳẴ৪4 IJ«ńẝₐ ºÏ ϵz«ūϬ aæ xẟ :ĹǡljƌȳẴ৪ ௦š¤Ñˊ᩾Zż̶̭᩼ ௦š ‰alb  }{| ඗ Ȁ ȳẴ৪௦š |J XHi \J|a`\J|a \J|aæ\J|ab\J|aa\J|aS\J|l\J|‰\J|d\J|Š\J|`\J| \J|æ\J|b\J|a\J|SọōƄ Ո඗ȀΞ[ „ႷzūϬ ᪩඗ȀՈˮPȳẴ৪«ϵɉǸƌ„Ո ʃǻǡ ΟǎՈ4 ,Ոɉ Ǹƌ  ‰ Ű,r }{|X4ẝr ȅỞẋ }{|X ɥdzÑâ4ŌŜɉȳẴ඗Ȁ4 ūϬ i}{|htsL uqãs `abtsLVSTl tsL ՈȖŌŜ hSTSSSlSSSS`abtsL ¤Ñẝₐ ż̶̭᩼ b`Š  }{| ȳẴ৪4 uqãs ST‰SS tsLhА└bS ‰ ƋᅆVh ü&PȳẴ৪ ◄ᡅ ‰ Ƌᅆ Ÿ‰  tsL Ոǎ5Ξ[ۅijKkTSuaa Ï ȳẴ৪ᜬՈ⑃ò└:4 А└͔ɴ) ৰ 32 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ŸtsL Ո }{| ǎ5Ξ[ۅń ijKkTSuaa Ï Ǹ̲ ȳẴ৪ͱৰ ŠƋᅆՈĹ ` ȑ/า& S dzÑˊᢧt«&ÑȒՈ̠ˊ„ljНՈ4 ŌǕϣ“Ո̠ˊ„ Ǯᡅ^ ‰S扊 ͨǭ ɥ]Ćȭ᪩ĹՈūϬ ɆçŁǎ5zᢈǎ4 €d ¡i Ĺ« ḳâdz-ϬĹ4‰S扊 ȭ᪩ĹՈūϬƦ2ᢈǎ JKLMN ͘ǼKlj᪅¶Ȓ {S ᜬ߾ūϬ aŠ ĹȢʄū⍌Ǹƌ„ QH ẝ^ ‰Sb‰Š ͨǭ4 ʐ HYH ūЁūϬŁ࢑ Ȣʄū ⍌Ǹƌ„4 {a ᜬ߾ūϬ æb ĹȢʄū ⍌Ǹƌ„ QH ńȳẴϵ QQ Ǹƌ„ȯŜՈɉȳẴ৪ { ĹΟǎ╔śՈȢʄ᪃⒲ūÐ€Ξ HOQz &  }{S ᜬ߾ɉՈZᾬА└& Š â ẝ«&r^ ‰Sb‰Š ͨǭ4 ńȕ[ÍʉϔǒɉՈȳẴ৪ { ĹΟǎɉՈZᾬṽА4{a ᜬ߾ɉՈZᾬА└ ᩨՈŌŜẕňϔՈ̓Ƀ4ڌ/Νǜ ɉ Ʒ^ ‰Sb‰Š ͨǭ4dzÑūϬŌŜ̓ɃQහʐ̱ňϔ̓ɃQ හۅ& aŠ ĹÏ ɉK ࢴۅᩨ ̑Ρ [ ūϬ aŠ ĹŌŜ ǎ aŠ Ĺz‰Ḻ́ňϔ ẝ ʳՈÏڌ{Shᜬ߾  ɉۅɉK ࢴ& æb ĹÏۅūÐūϬ æb ĹŌŜǎ æb Ĺz‰Ḻ́ňϔ ẝʳՈÏ ᩨ ̑Ρ [ڌᩨՈ ̓Ƀ4{a ᜬ߾ڌ¤ ৪ { ĹΟǎr ūÐ ūϬՈŌŜ ǎ̱ňϔ Ոɉ€Ở„«ȢʄɉՈY࢑ȳẴ৪Ո ͛5Ȉ]ּȐ4 ńȳẴdzËᜐɉՈȳẴ €Š { Ĺ«PǔĽȞ ՈĹ ńȳẴdzËᜐɉ3ȕ[ Íʉ ϔǒɉ zϵ QQ Ǹƌ„ȯŜ ʇ«ÑƋᅆ&řĹ4 ୖò&  âhƋᅆ4ͼ͛ А└ୖòǮȭɉ А└ƅά ȭɉȖŌŜ\ά ɉ ȖŌŜ €` } &ɥ«ɉА└ୖò€}ãrKkNrãjLáĹ4 }S ᜬ߾А└ୖò&Ƌᅆ}a ᜬ߾А└ ɉ3>᪃⒲ۅW Ëᜐwᪿ3PႸ ି Ƨ ɉۅÏ ɉۅ Ëᜐwᪿ3PႸ ɉ3>᪃⒲ۅ{ ǮËᜐ3PႸ ɉۅI ǮËᜐ3PႸ \ Ëᜐwᪿ3>᪃⒲  Ëᜐwᪿ l ǮËᜐ3>᪃⒲ ‰ ǮËᜐ Š ିƧȨ ᪸ d ᪿw΅3ȕ[Íʉ3>᪃⒲ ି Ƨ ϔǒɉ Š ᪿw΅3ȕ[Íʉ ` Ǯᪿ3ȕ[Íʉ3>᪃⒲   Ǯᪿ3ȕ[Íʉ æ ᪿw΅3>᪃⒲ b ᪿw΅ a Ǯᪿ3>᪃⒲ S Ǯᪿ Š ିƧȨ ᪸ ƌʔɉȳẴ৪Ո |H Ƌɉ¤᪸ŠՈʒɳdzƞ൷&[ᜬ ɉ4ۅɉ«PႸÏۅIa ᜬ߾ȭàՈÏ ɉۅɉ€êỞÏۅɉ]«P ႸÏۅɉ Ϭ Iʃᩴ4IS ᜬ߾ȭàՈÏۅPႸÏ ɉ« Ȫ«ۅɉ |H ՈĹ b ū߾¤ȳẴՈÏۅȑ/ūϬ/ȑäƫ4ńÏ ɉẟᜐ΅̱͑ňۅɉʇ«]dz΅Ո ᆩ◄ᡅȭÏۅɉdz ᪿdzËᜐ4ͼ͛ÏۅÏ ɉ]dz ᪿ Ǯ࿁Ëᜐ4 Xa ᜬ߾ȭàՈۅᪿ Ϭ৪ǻ Xʃᩴ4XS ᜬ߾ȭàՈÏ ɉ« ȪdzۅɉȳẴ৪ €a Ո̑с |H ՈĹ a ū߾ ¤ȳẴՈÏۅńÏ ᜬ߾ϔǒɉȕĺÍʉ ɉͱȻࢿȑ/̓zɉА└4 5ȕ4{ S ᜬ߾ϔǒɉȕʌ ঳Íʉ KŷɉͱȻࢿȑ/Ƀz਍zɉА└4{a ͼ͛ ϔǒɉʇ«dzᪿՈ4 |H ՈĹ b « { Ĺ ū߾¤ȳẴՈϔǒɉՈ Íʉ ΅ Ϭ ʃᩴ4  S ᜬ߾ȭàՈϔǒɉ]dz΅4 Ǒ7 a ᜬ߾ϔǒɉ«dz΅Ո4 ńϔǒɉȳẴ৪ €S Ո̑с |H ՈĹ a ū߾ ¤ȳẴՈϔǒɉ« Ȫdz ΅4 ৰ 33 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ȍ:ʼơ[ǡՈ Čƨǀ͔1 ẝɉ᪸Š«ǀ͔º᰹͛Ş̇Ո9 ŷūϬrẝ࢑ ͤƧՈȋ:5 ś4ȭz͢ƷP‡ͨǭǺƶẜdzÑūϬ͢Ʒ 5śǡɆ4ȭbShඃ ȭbShǍǻඃẟᜐ ȋ: Ո„Ϭ5ͩ«Ởẋ᪂า⏲֜ȋ:„Ո ঳ǧ Ȩ4ẝₐՈnMLkounh ࣏Û Β4üǸỞ„ᡅńό࢑ȋ:5ͩọō4ٯẝPͥŸ«☢„Ո ̱ňிඣ ȑ/ ūϬ ỆƟՈ5ͩǡŌ ȳƷ4IJ«ϵzȈ࢑ͨǭƶ¤ūϬՈᅳċ▊]Ȑ ᡅ Ɇ4 ᩨǝâ[ bShŌŜඃ« ࡅǶՈ ¤Ñڌ ᝯ±┨4º ໐ǒɴrͨǭɳ4ϵzńƶ„ȳ¬r ɨĽbShǎÑZŌŜ῁ ň&^⒬ ȋ: ẝŌŜ ɨĽĹ4 ᪩Ǎǻŷᝯࢴ&bS 4Ξ ȘƷ& ► z«ƫūϬr᪩š࿞ǡ ⏲֜ȋ:„ZʼΙƅाⒶՈ঳ǧš࿞ṗϦ঳ǧHb š࿞Hba ɳ J\Zh͘ǼǕŠrūϬPŌ͟ǡŌȳzࡅǶSTaSSSSShŌŜɨĽĹ4ϵzńƟrՈ‰S bh ɳ඙4IJ«Ɵr>ඓƅP‡࣏Û«-Ϭẝ࢑ŌŜ ɳ඙ƶ:ẟᜐ1ňՈ4&rǒɴǀ͔Ոͨǭ ͔ͨǭՈǒµśẔᜐ5ś4 Ϣ໐ ńȯŜȨ᱉ẋaZ\rƷŸ]࿁ᬥ ‰S‰‰hὧʳǒɴŌŜȯŜՈ ƶr ūϬՈ«JKLMNh‰Sb‰Š hIHO ͣƅb ʵŌŜඃ żʌdzȯŜaŠZ\ ÂƅP^‰S‰‰h ǀ ᩨŌɳ඙4STSUUMU4ƟJ\Zh͘Ǽzal‰`hÀš͑|hڌȭz᱉ϦSTaSSSSS€aZ\ՈȯŜŌŜȺ Ŝඃ>ᱷ̻ϬǡȯŜẝ‡ͱƌ4͢¤࿁ȯŜՈżʌŌŜ«STUUUUŸSTUUUU K ŷSTaSUUMU 4 ǺƶŌŜඃ ǮƅbSh ʵ€Shhal4ńƟrͱƌ XZhǮƅό Ղâ\hz]4 aZ\h r bShʵŌ al‰ahÀ‰hƄ J\Zh͘Ǽż!ȌϦՈ¦ᩥਜ਼ƶJ\ZhHIhūϬՈ IHOh«JKLMNh‰S‰‰ 4ń᪩  A20 ŌŜඃ⒲LŌŜඃ⒲LŌŜඃ⒲LŌŜඃ⒲L ͼ͛ͼ͛ͼ͛ͼ͛ ẝₐ·එՈ±±«ɉśՈƌʔ4 ;<;<;<;< ȺūÐǕϦՈȻࢿŌŜȐȖŌŜּ¤ƮtĭˊŌŜ4ȺūÐǕϦՈȻࢿŌŜȐȖŌŜּ¤ƮtĭˊŌŜ4ȺūÐǕϦՈȻࢿŌŜȐȖŌŜּ¤ƮtĭˊŌŜ4ȺūÐǕϦՈȻࢿŌŜȐȖŌŜּ¤ƮtĭˊŌŜ4 ☢ͩ᪃⒲ͱƌ4   ȺūÐǕϦՈȻࢿŌŜȐᢈǎՈɉ⑃òּɨ̼ɡ«ȪǕϣᱎАȺūÐǕϦՈȻࢿŌŜȐᢈǎՈɉ⑃òּɨ̼ɡ«ȪǕϣᱎАȺūÐǕϦՈȻࢿŌŜȐᢈǎՈɉ⑃òּɨ̼ɡ«ȪǕϣᱎАȺūÐǕϦՈȻࢿŌŜȐᢈǎՈɉ⑃òּɨ̼ɡ«ȪǕϣᱎА ẝʳɥdzÑὃ̹ & SS Ո࣏ÛdzÑ᪃⒲ ȭ᪩ɉȭàՈͱƌdzÑᪿw΅4 $ẝȳẴ৪᪸Š ȖŌŜ« S ɉ └:Ոୖò&  m Ƌᅆ ɉ ̓Ƀ└: ‰Z Ǯƅ൫/ Š‰uqãs STSSIS #htãrKkNrãjLá SlŠVhæ uqãs STlbSS #hsrLrhãMrswãjLM uqãs STSSSS #hxrnMhrssãMnnS uqãs STSdWW #h‰Zxh[hNj~jLbS dh€bS ‰ž SlŠ‰Zx Ǯƅ൫/& SS Ո࣏ÛdzÑ ᪃⒲ ȭ ᪩ɉȭàՈͱƌdzÑËᜐwᪿ4 ̓dzẂ4  } $ẝȳẴ৪᪸Š ȖŌŜ« S ɉ └:Ոୖò&  m Ƌᅆ ɉ ̓Ƀ└: ‰Z ˊ ᩾Zż €ʒ ɳ}€a {€a S ¡i€Sij~jL€aluuuaŠ€S H€a {Hi€SS {|€a |H ȳẴ৪ ƌʔɉ \J|d \J|Š \J|` \J|  \J|æ\J|b \J|a \J|S\J|d\J|Š\J|` \J|  \J|æ\J|b\J|a\J|S \áLMh~Š \áLMh~` Ẵ৪ \rnM€æauuub €SS ʒɳ€IShl \rnM€bæuuuS€SShSShSS ij~jLM€a`uuuS€SdhWW Zd ZŠ Z` Z  Zæ Zb Za ZSƌʔɉȳ Š‰uqãs STSSIS #htãrKkNrãjLá SlŠVhæ uqãs STlSS #hqsMhãMrswMTM uqãs STSSSS #hxrnMhrssãMnnS uqãs STSdWW #h‰Zxh[hNj~jLbS dh€bS ‰ž SlŠ‰Zx uqãs SVSVSVS }{| ᜬՈৰ S ǻȳẴ৪ȑ/« S Â]ĆᝯūϬ ৰ 34 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ŌŜƅϦ ƿẔᜐ~rjK€࣏Û4 /᪂าƷØՈᜬ-4żȒ-ϬẘúūÐȺ8̴΢าńȢʄՈwjKjLw~rjKuh࣏ÛՈ͑ ǧ ௫╓Ȓ☦΢า͝dzȯŜaŠZ\hͱƌՈ h)ᜬ  ͱƌĹา üǸẝɉ࣏ÛȺᝯᡊ֚ǭ )̠ˊƶ : Ⱥ)ֲơᜬ΢ńඡȭĭˊŌŜShŌϧ̠K« ƨ࣏Û¤̠Ոĭˊ ੥ˊͱƌՈ Âńȋ:Ǹƌ„IXSh᪂าּàՈʃȣĹ4ȉ؄᪂า ċ‰Sb‰d3‰Sæ‰dhzͨ͢ǭᅳċ ẟ͑ȏǶɳ4ϢȒ࣏Ûϟ᪙HIhƶ«Ȫȯƅϔƚœ̠ˊ„ ᅳ ΞȘ̼ϟ[ǡǕɴ̵ƅŌȳ ŌŜ̠Ոͱ ǭ ń᪃⒲ʌz aZxh ĭˊͱƌŌŜrIHOhǒ┉ǮĆ᪃⒲ JHhZY{haZx ƅŌȳ ՈŌȳΞȘ̵ף<ϬĭˊŌŜSh^aZhŌϧ̠ՈͱǭּɨṇՈ5ͩ ̼ϟbShŌŜඃ«Ȫ ÂūȈᜬ-ţūȕPǮĉ⏝᪳Ո)Ɖ¥Ƅ࣏Û4ϢȒₑ,᪂า͔ɴȳẴ৪ᜬ4 ȉ؄ū Ո4ƷՈ £࿁ɨṇřP Ŋ̴«¤ṁȈϔǒɉǸƌ„ ₑ ,᪂า)ȳẴ৪ᜬ ͝ b`Šh- ẝɉ࣏Û>ඓϵnMLko࣏Ûʐ4STSSSS̠ ¤Ñǒ┉Z«ºͱƌඡȭŌŜSh̠ŌϧËᜐ 5ȕ«º24Ƿ4 ᰏȨՈ ۅՈ˛ේ᪱ᣄʸś Â◄ᡅūϬ}ŽOhՈtrnhʐtNsẟᜐේ᪕Ảȉ 4ü Ǹ᪻ͼ͛ Ï ǀ͔῁«ńljĈµś[Ẕᜐr4yMrsnunh˛ේ࣏Û^ Q☦Ո᪱ͩʸś]Ȑ Ʒ ₋ϬՈ«||h 4ºẝₐŌϧ ͱʴ yMrsunh࣏Ûńᝯේ᪕Ȓ ĆᝯẢȉtͱʴâՈżQ☦Ōϧᾬ ŠHead.s Ո᪸ŠՈ᪸ŠՈ᪸ŠՈ᪸ ǶbShǍǻඃ4 Ćࡅtிඣ⏝᪳Ո̱ň4ẜƅP࢑5ś«ỞẋᪿSTMMh঳ǧǡŌȳbShǍǻඃ ΅᪩঳ǧ ¤ūϬ º ໐Ụ ঳ǧǡȋ: IJ«᪩঳ǧKƅdz࿁ᝯ͢ƷͨǭǺƶZՈ᪂̣Ξ º߾ᅳċ ǻඃ ὃ ̹rūϬ ήợ Ո⏲֜ȋ: „̱ň5ś4ȭz]ȯ⏲֜ȋ:„ՈிඣɥǮ࿁ūϬSTlbh ̱ň4& ǸšẟrP bSȷợ⒬ọ -€WrnLh}rLMhbS ƷūϬ JwYh঳ǧ STlbhǡ̠ˊbShǍ 4 ϵz⏲֜Ոȋ: „ợòǔή ü Ǹɥ]࿁ūϬ ⏲֜ȋ: „ȭ bShඃǡẟᜐ ẋ࣏ՈPᾬ Ոȋ:4ƅ ‡̱ňிඣȺ bShՈŌȳʐࡅǶň&ǒµś^ljĈẔᜐµś 7ⒸẟᜐḰdžՈ ʃβ ৰ 35 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ .text Š᪸ۅ᪸ŠÏۅ᪸ŠÏۅ᪸ŠÏۅÏ Ě x.5head.s Ո੄ᡅϕ࣏Ě Ո੄ᡅϕ࣏ĚۅՈ੄ᡅϕ࣏ĚÏۅՈ੄ᡅϕ࣏ĚÏۅՈ੄ᡅϕ࣏ĚÏۅÏ ৰ 36 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ orl $2,%eax # set MP /* "orl $0x10020,%eax" here for 486 might be good */ andl $0x80000011,%eax # Save PG,PE,ET movl %cr0,%eax # check math chip ἗4ک[// ̼ɡ CPU ՈିƧ &¬4 u */ * int 16 for math errors. * 486 users probably want to set the NE (#5) bit also, so as to use * mode. Then it would be unnecessary with the "verify_area()" -calls. * NOTE! 486 should set bit 16, to check for write -protect in supervisor /* je 1b cmpl %eax,0x100000 movl %eax,0x000000 # loop forever if it isn't 1: incl %eax # check that A20 really IS enabled xorl %eax,%eax // Οǎ«Ȫ࿁᪃⒲ 1M ÑZͱƌ4 Ƕɳ਍Ǒ4ŌŜඃ A20 « x86 ՈƊǶἛН⒲L// ȓ׏ϔǒඃ A20 «Ȫƅά Ȫ lss _stack_start,%esp mov %ax,%gs mov %ax,%fs mov %ax,%es # reloaded in 'setup_gdt' mov %ax,%ds # after changing gdt. CS was already movl $0x10,%eax # reload all the segment registers // ₑ,᪂าȈɉǸƌ„4 call setup_gdt // ₑ,᪂า GDT ͟z GDT Ո᪂า5ͩᢅ Setup Ո᪸Š4 call setup_idt // setup_idt Ո᪸Š4 // ᜐ8Unknown interrupt9ᜬ߾)ɎƦ᪂า4͟zẝϔՈͣĿՈǒɴ5ͩdž໇ // ᪂า)ȕₓᜬ ᩭ¤ƅՈ)῁ūȕPƄ࣏Û ẝƄ࣏ÛՈňϬ«º߾P lss _stack_start,%esp // ʻŌ5 // ᜬ߾_stack_start ss:esp 4_stack_start « C ේ᪕࣏Û&࣏ÛႮ¬ϣtՈƌƅȢʄǍ mov %ax,%gs mov %ax,%fs mov %ax,%es mov %ax,%ds // ּƟz MOVDS,AX movl $0x10,%eax // ּƟz MOV EAX, 10H, ẝₐՈMOVL ᜬ߾ẟᜐ 32Ĺࢿ¬ startup_32: // ɉ Ȑr!ϧĚrȢʄɉ4 ᪂าϬzȺ¤ƅՈɉǸƌ„(ds,es,fs,gs) Ոʃᩴ᪂า&ūȕ GDT ՈŌŜۅ// Ñ[Ï _pg_dir: .globl _idt,_gdt,_pg_dir,_tmp_floppy_area ৰ 37 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ :rp_sidt mov $256,%ecx lea _idt,%edi movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ movw %dx,%ax /* selector = 0x0008 = cs */ movl $0x00080000,%eax lea ignore_int,%edx setup_idt: // ʸś^ GDTR Ǹƌ„ό:Pʳ ẝₐ]͹௳Ẵ4 ᪂าՈ IDT ᜬ4IDTR Ǹƌ„Ո// ͑͢47Ȓ ᪂า IDTR Ǹƌ„ ū͢ūȕ // ẝ1ňńේ᪕Ոrȅ>ඓǀtr4ϢȒ Ƕɳ 256 ƵȺ ignore_int Ո͑ǧŌŜ΢ ƋᅆՈाⒸ // ᪂า IDT Ŋ̴ń_idt ՈĹา±ाr 2568)ȕₓ« 8 Ƌᅆ */ * written by the page tables. * sure everything is ok. This routine will be over - * are enabled elsew here, when we can be relatively * in the idt -table may do so themselves. Interrupts * idt. Everything that wants to install itself * ignore_int, interrupt gates. It then loads * sets up a idt with 256 entries pointing to * * setup_idt /* ret 1: .byte 0xDB,0xE4 /* fsetpm for 287, ignore d by 387 */ .align 2 ret movl %eax,%cr0 xorl $6,%eax /* reset MP, set EM */ movl %cr0,%eax je 1f /* no coprocessor: have to set bits */ cmpb $0,%al fstsw %ax fninit check_x87: */ * We depend on ET to be co rrect. This checks for 287/387. /* jmp after_page_tables call check_x87 movl %eax,%cr0 ৰ 38 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ * reach to a buffer -block. It needs to be aligned, so that it isn't * tmp_floppy_area is used by the floppy-driver when DMA cannot /* .org 0x5000 pg3: .org 0x4000 pg2: .org 0x3000 pg1: .org 0x2000 pg0: .org 0x1000 // ń)ֲơᜬƌ΢Ոɥ«ẝ‡)ᜬ-ᜬՈŌŜ ɣᜬŌŜ7ⒸՈᲡࡿ« 4k4 */ * more than 16MB will have to expand this. * using 4 of them to span 16 Mb of physical memory. People with * I put the kernel page tables right after the page directory, /* ret lgdt gdt_descr setup_gdt: */ * This routine will beoverwritten by the page tables. * rather long comment is certainly needed :-). * is VERY complicated at two whole lines, so this * ones that were built in init.s. The routine * Only two entries are currently built, the same * This routines sets up a new gdt and loads it. * * setup_gdt /* ret lidt idt_descr jne rp_sidt dec %ecx addl $8,%edi movl %edx,4(%edi) movl %eax,(%edi) ৰ 39 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ popl %ecx popl %edx pop %ds pop %es pop %fs popl %eax call _printk pushl $int_msg mov %ax,%fs mov %ax,%es mov %ax,%ds movl $0x10,%eax push %fs push %es push %ds pushl %edx pushl %ecx pushl %eax 4// ẝ«P C ᪱ᣄՈϔ ¤ÑūϬՈrȅᡅἹƼPǎՈᢈ ignore_int: .align 2 .asciz "Unknown interrupt\n\r" int_msg: /* This is the default interrupt "handler" :-) */ # just in case, we know what happens. jmp L6 # main should never retu rn here, but L6: jmp setup_paging pushl $_main pushl $L6 # return address for main, if it decides to. pushl $0 pushl $0 pushl $0 # These are the parameters to main :-) // ᪱ǩɥdzÑŌϧr C ᪱ᣄՈϣϏ ̿4ẝₐ ÄࡓՈͫᢍ͍Ϣ໐ϣ☺4 // Ʒ΢ń init/main.c ƟƟȺ mai n Ո͑ǧŌŜ΢͑Ȣʄ7Ȓ żȒËᜐP ret // ᪂าȢʄ ɉ ĹżȒËᜐ main ϔňβ̣ main ϔūϬ C ᪱ᣄ΅ՈৰPϔ after_page_tables: .fill 1024,1,0 _tmp_floppy_area: ἗ẝ«ᡅňϞ44ک˰ // /* . * on a 64kB border ৰ 40 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ movl $pg3+4092,%edi movl $pg3+7,_pg_dir+12 /* --------- " " --------- */ movl $pg2+7,_pg_dir+8 /* --------- " " --------- */ movl $pg1+7,_pg_dir+4 /* --------- " " --------- */ movl $pg0+7,_pg_dir /* set present bit/user r/w */ cld;rep;stosl xorl %edi,%edi /* pg_dir is at 0x000 */ xorl %eax,%eax movl $1024*5,%ecx /* 5 pages - pg_dir+4 page tables */ setup_paging: .align 2 )µś4 // «º 0x000000000x00ffffff ͝ 16M4żȒ᪂า CR0 Ǹƌ„ Ōϧr // r 44k Ƌᅆ ǷΙȺ pg0—pg3 Ո 4 Ŭᜬ§ǀ4ẝrȅϬ›࿁̻ūϬՈŌŜ // ᜬ ϢȒúʇ)☦ȳẴ-ᜬ45ͩ«Ƕɳ 4k Ƶ ɣƵʇ͑ 4 Ƌᅆ4P͝úʇ // ाⒸ ĉŐrֲơᜬʐ 4 )☦ȳẴ-ᜬ4Ⱥ 4 )☦ȳẴ-ᜬՈŌŜ΢4ֲơ )µś4Ŋ̴º 0x0000 ŌŜŌϧ±ा 54k ̓ɃՈ // żₑᡅՈ1ňŌϧr ᪂า */ * won't guarantee that's all :-( ) * some kind of marker at them (search for "16Mb"), but I * I've tried to show which constants to change by having * even cannot be extended past that (ok, but it was cheap :-) * change some constants etc. I left it at 16Mb, as my machine * it. (Seriously - it shouldn't be too difficult. Mostly * not got it, why should you :-) The source is here. Change * For those with more memory than 16 Mb - tough luck. I've * * that. * will be mapped to some other place - mm keeps track of * use just the lower 1Mb, or the local data space, which * use the >1Mb addresses directly. All "normal" functions * mapped by this routine, only the kernel page functions * NOTE! Although all physical memory should be identity * * addresses are produced (ie >4Mb on a 4Mb machine). * the first 16MB. The pager assumes that no illegal * in cr0. The page tables are set up, identity -mapping * This routine sets up paging by setting the page bit * * Setup_paging /* iret popl %eax ৰ 41 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ OĚ ඓẋ)Ո!ϧĚ7ȒͱƌाⒸ .fill 252,8,0 /* space for LDT's and TSS's etc */ .quad 0x0000000000000000 /* TEMPORARY - don't use */ .quad 0x00c0920000000fff /* 16Mb */ // ͱƌ└: 16M ȖŌŜ 00200000 ǮËᜐ>᪃⒲4 .quad 0x00c09a0000000fff /* 16Mb */ // ͱƌ└: 16M ȖŌŜ 00a00000 ǮËᜐ>᪃⒲4 _gdt: .quad 0x0000000000000000 /* NULL descriptor */ _idt: .fill 256,8,0 # idt is uninitialized // 1ň«ńϬ C ᪱ᣄǒɴՈ trap_init() ǀtՈ ƷĹz/kernel /traps.c 4 // ẝₐ±±«&)ȕₓᜬŌṣrाⒸ ÂȺPĉ⏝࣏Û΢͑͢4ͣĿՈʇ̱ .align 3 .long _gdt # magic number, but it works for me :^) .word 256*8-1 # so does gdt (n ot that that's any gdt_descr: .word 0 .align 2 .long _idt .word 256*8-1 # idt contains 256 entries idt_descr: .word 0 .align 2 ret /* this also flushes prefetch -queue */ movl %eax,%cr0 /* set paging (PG) bit */ orl $0x80000000,%eax movl %cr0,%eax movl %eax,%cr3 /* cr3 - page directory start */ xorl %eax,%eax /* pg_dir is at 0x0000 */ jge 1b subl $0x1000,%eax 1: stosl /* fill pages backwards - more efficient :-) */ std movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */ ৰ 42 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ )µś᪂ǎr 7Ȓ ĭˊŌŜՈȯ âɥ◄ᡅ̴ඓẋɉՈǜdž ZẟᜐՈ4Ɵ܄ɉ੥ˊՈ Ȗ Q☦>ඓ ȴ4r ń setup.s >ඓȺͱƌՈµśḰǜ&ɉ੥ˊ ẝₐՈ)੥ˊ ɥ«ń ੥ˊ ੥ˊ ੥ˊ ljĈµś)śljĈµś)śljĈµś)śljĈµś)ś ੥ˊ OĚ Ě x.6 ͱƌाⒸ ৰ 43 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ⒲4[ᜬϦrZẴʒɳĹ Xw ʐ OwQ ¤ܲ ǎՈ)൫ljĈ[ Ϭ›൫࣏Û OwQS ᜬ -¤ūǎՈ)«ிඣ൫) Ǯ࿁ϵிඣ Ľƿ ൫[ËᜐՈ࣏Û᪃ ᜬ-¤ūǎՈ)«Ϭ› ൫) dz ϵçŁ Ľƿ ൫[ËᜐՈ࣏Û ᪃⒲ΞȘ OwQ€b «Ϭ›wிඣ ʒɳĹVū߾᪩ᜬ-¤ūǎՈ)«Ȫ«Ϭ›൫)4ᆩ OwQa Ñᪿ3΅zËᜐu Ϭ›Ľƿ ൫rǕƉňϬ Ɵ̠ˊ„̠zிඣ Ľƿ ൫r Xw  ĹᝯɉЩ ŷʇdz Ëᜐ IJ]࿁ȭ᪩ūǎՈ)΅͑4 IJ« Xw Ĺȭ)Ո΅ljĈ Ǯń ̠ˊ„̠z ȭᜬ-¤ūǎՈ)dzẟᜐᪿ3΅zËᜐᆩ XwS ȭᜬ-¤ūǎՈ)dzᪿz Xw€a«ᪿ΅ʒɳĹ ū߾ ᪩ᜬ-¤ūǎՈ)« Ȫdzᪿ3 ΅zËᜐ4 ᆩ Xwa Ո͢ŅȈĹţdzƇḳ âūϬ ‰S扊 ]ᢧ₎ HS Ոᜬ-ՈçŁ͢ƷՈĹ4 H€S «ƌńʒɳĹVᜬ߾᪩ᜬ-«Ȫƅά4Ha ᜬ-ƅάH S ᜬ-\ά Ǹrᜬ- ¡i€aa4l ƋɉƇḳâūϬ4 i S S {  S S OwQ Xw H¡ ۅ(ˊᜬՈᜬ-ʸś ĭ \J|æa4\J|abh\J|aa4\J|lh\J|‰h\J|dh\J|Šh\J|`h\J| h\J|æh\J|bh\J|ah\J|Sh)ֲơᜬz) uØ͹ǡ׏׏ֲơᜬ-ʐ)☦ᜬ-Ոʸś ẝʸśό:ǀ͔Pʳ Ȍ: ë̑ۅĚ x.8 ඃɳŌŜ4ĭˊŌŜՈœȸẋ࣏ϦႮz9 ͱʴļÏ dzÑỞẋPĚǡᜬ߾Ϧǡ Ĺɉּ¤ǣ4ĭˊŌŜ4œȸẋ࣏ - żȒȺ) ☦ȳẴ-Ո ȖŌŜ^ offset )ͱ Ȼࢿ Ĺɉ&[ʃǚǣ)☦ȳẴ &[ʃ ºֲơᜬâ4) ☦ᜬՈȖŌŜ4͹Ñ page)☦ᜬ Ĺɉ 4 ϢȒÑඝϦՈͱƌඃɳŌŜՈ dir ) ☦ֲơ ƌʔr͔ɴȳẴ৪ᜬՈ ŊŌŜPʳ Ŋ̴ Intel ᪂าrPɉ Ǹƌ„ CR3 ẝ Ǹƌ„ƌ ʔr)☦ֲơՈ ŊŌŜ ɥȐ GDTR Ȍ: ë̑ۅĚ x.7 ͱƌඃɳŌŜՈʸśϦႮz9 ͱʴļÏ ƌŌŜƅrP,Ոʸśᢧ₎ )੥ˊ ȭ ඝϦՈ 32 ĹՈͱ ń)੥ˊɦ ϢȒ͹Ởẋ)ǡâ4ǒ ┉ŌŜ4ΞŁǒɴ ৰ 44 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ȒϬ˛ේ᪱ᣄ΅P᫇ϬՈ࣏Û4Ⱥẝâ ༘Ȍේ᪕tP .com â ūϬ debug.exe Ϣ ẝ᪙ɀ«̴Ϭ C ᪱ᣄ΅PńỞ„Ո ͛5[« ǔͣɶՈ࣏Û ̵ƅ main ϔ ǎ debug.exe4 nasmw.exe turbo c 2.0 Ոේ ᪕„ tcc.exe .exe â4 .co m âՈḰdž1ͣ exe2com.exe Ñ „ń᩶ᢧ7Q uØɆ P᪙ɀ ᪙ɀՈ1 ͣ« masm ՈẢȉ „ link.exe nasm ේ᪕ ΅Ո࣏ÛP᰻ේ᪕4PâƿՈ4ƅ̵ƅ̿ẋẝ«ΞŁǒɴՈɦ ‑ՈाⒸdzÑᝯ C ᪱ᣄ΅ՈϔūϬ4Ǫ̲ẝ˛ේ࣏Û żȒū◄ᡅȐ C ᪱ᣄ ˛ේ᪱ᣄ ń head.s âƅ ̠᫇ϬrūϬ C ᪱ᣄ R΅Ոϔ _printk() ʐ_main() ȐrūϬ ˛ේ᪱ᣄ^˛ේ᪱ᣄ^˛ේ᪱ᣄ^˛ේ᪱ᣄ^ C ᪱ᣄՈ£Ȍේ࣏᪱ᣄՈ£Ȍේ࣏᪱ᣄՈ£Ȍේ࣏᪱ᣄՈ£Ȍේ࣏ SSSSSSSSSSSS ۅ(ˊIXæ )ֲơᜬĭ „ȋ:Ǹƌ IXb )Ω╠ඃɳŌŜ IXa ljН IXS H} SSSSSSSSSSSSSSSS | |Q Z ZH H IXN \J|æa \J|æS4\J|ab \J|aa4\J|` \J|  \J|æ \J|b \J|a \J|S Š,š͑Ոȋ:Ǹƌ„ʸś᪸ )੥ˊ4 żȒ ƟȺ IXS Ǹƌ„Ո H} Ĺ᪂าĹ a ɥŌϧr a a a a a a ɳ ඈȌ)ՈljĈʒ a S S a S S S a S S a S S S S S S S ֲơᜬ- OwQ)ᜬ- OwQ ඈȌ OwQ ֲơᜬ- Xw)ᜬ- Xw ඈȌ Xw Ȩ ඈȌᩥਜ਼«8^9̱ň4 ơᜬ -ʐ)ᜬ-ՈljĈ ʒɳĹՈȨ ¤ǣ4[ᜬϦr ඈȌᩥਜ਼QȒՈljĈ ʒɳĹՈ ᰻4ljĈňϬ4¤Ñ ȭ)᪃⒲ršϬՈljĈʒɳĹ Xw  ʐ OwQ ՈȨ« ඈȌᩥਜ਼)ֲ Xw ʐ OwQ )ֲơᜬ-ՈljĈʒɳĹȭϵ᪩ᜬ-ūǎ)ᜬ¤ūǎՈ͔ᾬ aâ Ȉ ) ᪃⒲ƿ4 ƿ ŷūᢈǎ&Ǯ̭ᪿ᩼ wËᜐՈϬ›) ͱɶிඣ ൫࣏ÛKȭ ᪩)ƅ΅ ƶ:]ȐՈ« ńͱɶிඣ ൫ËᜐՈ࣏Û ȭçŁ) ῁ƅᪿw΅wËᜐ ᪃⒲ ɉ ͱɶிඣ ൫ËᜐՈ࣏Û ^dz᪃⒲ிඣ ൫) Kdz᪃⒲Ϭ› ൫)4^ ɉƶ :Pʳ ̲ɶϬ› ൫ËᜐՈ࣏Û Ǯ࿁ ᪃⒲Ϭ›൫Ո) ໐ ⒲Ո4 ^ ிඣ൫)ȭzிඣ ൫࣏Ûʇ«dzᪿw΅wËᜐ ໐ȭϬ› ൫࣏Ûʇ«]dz ᪃ ϵZᜬdzᢅ Ϭ› ൫)dzÑᢈǎ&Ǯ̭ᪿ᩼ wËᜐ zᢈǎ&ᪿw΅wËᜐ4 a a ᪿw΅wËᜐ ᪿw΅wËᜐ ʒɳ ljĈ )൫ a S ᪿwËᜐ ᪿw΅wËᜐ S a \ ᪿw΅wËᜐ S S \ ᪿw΅wËᜐ OwQ Xw Ϭ›൫᪃⒲ƿ└ ிඣ൫᪃⒲ƿ└ /ͣƅՈȭϬ›൫)ʐிඣ൫)ẟᜐ̱ňՈƿ└4 ʐிඣ൫࣏Û ৰ 45 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ xxxx:0 10B C3 RET xxxx:010A 59 POP CX xxxx:0107 E80200 CALL 010C xxxx:0106 50 PUSHAX ; assigne(6) xxxx:0103 B80600 MOV AX,0006 ; ẝ« e_main() xxxx:0 100 E80000 CALL 0003 ;call _e_main ඗ȘΞ[ Ιr ɴ ńᩭ uØǡ׏׏ẝ ɶྒ«¬4ȫ4Ϭ debug –u ǡ׏׏Ǒ ˛ේẝ e.exe â4 4ۅȌ ǜt.com âɥǔΙr Ʒɥ«ƶ„ ūϬ exe2com Ⱥẝ e.exe Ḱdžt e.com4ü&.exe âϵႮ=ՈPͳʸś ] ǭ ṗ͑Ոrȅᡅͼ͛ẝâՈ.Û PĆ̫uĆ᩶&¬44 link start.obj e.obj, e.exe,,, Ȓ ◄ᡅȺÂØẢȉtdzËᜐ࣏Û e.exe4 ේ᪕trֲʃâe.obj ʐ start.obj ᜬ߾ÑֲʃâՈʸśේ᪕t start.obj â4 Nasmw –f obj –o start.obj –start.asm ᜬ߾ÑǺƧµśǮẟᜐේ᪕ ϣt e.obj â4 tcc –mf –oe.obj –c –e.c ±±ේ᪕t.obj â4ʁÐʸś& ɴńẟᜐේ᪕r ŇW]ᡅ ń▊tɳʟ ේ ᪕ \ͩỞẋՈ4ේ ᪕ՈūϬȺẝ â ᪱ᣄේ᪕ՈūϬĆńϔQႮ¬¤Z ‘ _’4 ẝ࣏Û ɥPǝūÐ ɥ«᫇Ϭ C ᪱ᣄՈ e_main() ϔ4ẝ ₐ΅t_e_main «ü& C call _e_main start: [extern _e_main] [global start] [BITS 16] ɴń u̿ń˛ේ᪱ᣄ᫇Ϭẝϔ4ņএP˛ේâ start.asm 4 ʻ«.dll ͢ǒּ:ǔ̶Ո îƷ±± ׏ň«Ϭ C ΅Ո ϔ4 ǔ ۅdžPᢖòǡ׏ẝɉÏ ἗ǔ੄řک4£࿁ Ǯ ἗«¬ک[4ü&ẝ࣏Û̵ƅ͑ǧͥ4ẝ࣏Û«u╓͛ϖՈP uK Ⴎ=΅Ո]ਜ਼ Û«]dz ࿁ËᜐՈ4̵⏝ ūϬçŁP ▊tɳʟ ǡේ ᪕ẝɉ C ࣏Û ῁«]dz ࿁t£Ո Ō ẝ C ᪱ᣄՈ࣏Û̵ƅ main ϔ ẝ ńỞ„Ո͛5[«ǽ͢]Ƿ„Ո dzÑ᪸ẝ࣏ } c = 5; { void assigne(in t c) } assigne(6); { void e_main() extern void assigne(int); ̴ņএP C ᪱ᣄâ e.c4ͱǭ« ȭẝ.com âẟᜐǑ˛ේ ǡ ɡ׏ẝϵ8 ÷]ᬥ9Ոේ ᪕„4ádžϣrP¬4ɶྒ 4 ৰ 46 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ‑Ոǜₓr4Ξ_gdt, _idt4 ՈͱʴâKdzÑūϬń˛ේ᪱ᣄ ʳń head.s ūϬͱʴâǎ5Ո C ᪱ᣄϔ ɥ«PâǔǷ„Ոw̑r4Ȑr C ᪱ᣄ΅ ɥẢȉ4rͱʴՈ żQ☦ 4ẝ ۅֲʃâ ͢ȒᲣՈ῁«ּàՈͱʴâ z« head.s ՈÏ LD Ïᜬ gld Ảȉ„ LDFLAGS«Ảȉdžϔ4 Boot/head.o ɥ«ẝ˛ේ΅Ո head.s Ո $(LIBS) \ $(MATH) \ $(DRIVERS) \ $(ARCHIVES) \ $(LD) $(LDFLAGS) boot/head.o init/main.o \ ƅPǩ᪡ ἗ේ᪕ẋ࣏Ո4͢ ک๨ƅP makefile â ẝâūϬzۅń Linux0.11 ՈÏ ϔȑQ¤Z ‘ _’ âẢȉ4P᰻4ẝ ʳ C ᪱ᣄʐ˛ේ᪱ᣄɥdzÑ£ȌūϬr4 /Ȥr C Ոේ ᪕„Ćń Ոrȅ◄ᡅ4 ̴Ⱥ˛ේ࣏Ûʐ C ࣏Ûේ᪕t.obj ʸśՈâ ϢȒūϬẢȉ „Ⱥֲ ʃ ᩾ Ởẋẝ ŷƄ dzÑ ׏4 ˛ේ^ C ᪱ᣄ£Ȍේ࣏C ᪱ᣄ ΀͑˛ේ ūÐ ]ńẝₐᩬ ȑϢ«ᡅϦ⏝Ո4Ûϕ࣏ẟᜐƽǶ4Ȫ ǔŠºẝƵේ᪕⏝r4]« Ảȉ„]ö࿁ « ŌᜬẂՈ]Ƿܲ4ẢȉՈr ȅ◄ ᡅŭ+ ࣏ ۅxxxx:011 5 E9FF ; ̵ƅּàՈƶ„ ;4 /⒲u4 ἗ẝ«¬ک[xxxx:011 3 00E8 ADD AL, CH ; u xxxx:011 2 C3 RET xxxx:0111 5D POP BP xxxx:010C C746040500 MOV WORD PTR [BP+04], 0005 xxxx:010A 8BEC MOV BP, SP ;c = 5 xxxx:0109 55 PUSH BP ; ẝ« assigne(int c) xxxx:0 108 C3 RET xxxx:0107 59 POP CX xxxx:0104 E80200 CALL 010C xxxx:0103 50 PUSHAX ; assigne(6) xxxx:0100 B80600 MOV AX,0006 ; ẝ« e_main() ẜ«Ⱥ͢Ḱǜt e. com 7Ȓ Ϭ debug Ǒ˛ේ4 link e.obj start.obj, e.exe,,, ṗ͑.Û4ɴńuØ׏׏ ΞȘẝʳẢȉĆɚ4ʳ “ϣՈẝdzËᜐâ ẜ«ƞǷܲ Ոȫ4Q☦᪸἗ń ẢȉՈrȅᡅͼ͛ .obj âՈ xxxx:011 5 C3 RET xxxx:0114 5D POP BP xxxx:010F C746040500 MOV WORD PTR [BP+04], 0005 xxxx:010D 8BEC MOV BP, SP ;c = 5 xxxx:010C 55 PUSH BP ; ẝ« assigne(int c) ৰ 47 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ˖7Z Ո4ü Ǹ Linux0.11 ]ǣ>ẜ«ᡅ ŭ+ Intel Ոᡅ܄੥ˊPǎᡅņ এń ɉś੥ˊՈȖ )śՈ )śǡ੥ˊͱƌՈ IJ«ϵz Intel Ո඗ȀՈ᪂ᩥū ǣ ń Linux0.11 «ūϬ Ĺ& 1 ǒɴՈ4 Ո PG 31 )Ո ȳ¬ «᪂า CR0 Ĺ& 1 ǒɴ ljĈµś ȳ¬ «Ởẋ᪂า CR0 Ǹƌ„Ո PE 0 ńḰdžՈẋ࣏ĆඓẋPிՈĽƿ൫̼ɀ4 ᜬՈŊŌŜϵ CR3 ඝϦ )ᜬ-ՈŌŜϵ)ֲơ-ǣ44 ͢ɉȳẴ৪ᜬՈ ŊŌŜϵ GDTR ඝϦ ɉȳẴ৪ՈọōńɉǸƌ„ǣ4 )ֲơ ǀ͔ͼ₎:ۅĚ x.10 )ǜdž߾͛ĚϦႮz9 ļ ǀ͔ͼ₎:ۅĚ x.9 ɉǜdž߾͛ĚϦႮz9 ļ ߾͛ĚΞ[ &ẝ‡1ňȴƇǝâ4 ƾՈǜdžʐȈ࢑̼ɀ῁«ϵܰâǡǒɴՈ ẕňிඣ\͟4ிඣ±±«ẟᜐּàՈ‑า 4 .ƫ᪸P[ ẝ‡̩ ඡȭŌŜඓẋ)ǜdž tỿṕŌŜ ඃɳŌŜඓẋɉǜdž ńljĈµś[ Linux0.11 ̴ẟᜐɉǜdž ϢȒ«)ǜdž Ⱥ ඡȭŌŜ â44dzÑᜬ߾ χ ¤ÑuńẝₐẟᜐPƵʇ඗4 Ŝ ϵzɨṇ /·එr Linux0.11 ΞŁ ńljĈµś[ẟᜐͱƌՈȯ  Q☦>ඓ ń setup.s ʐ head.s ljĈµś[ͱƌՈȯŜʇ඗ljĈµś[ͱƌՈȯŜʇ඗ljĈµś[ͱƌՈȯŜʇ඗ljĈµś[ͱƌՈȯŜʇ඗ ৰ 48 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ˊŌŜՈǜdžՈ祐ඝr)ś੥ˊǡǀt4 0x0000000 ¤ÑḰdžՈඃ ɳŌŜ^ỿṕŌŜՈȨ«ּ ȐՈ4ẝ ʳɥūǣϘỿṕŌŜ4ĭ ńºỿṕ ŌŜ4ඃ ɳŌŜՈḰdžՈrȅ ȭzūϬẝ ʳՈɉȳẴ৪ǡ᪸ ϵzȖŌŜ« 1 32 ĹՈȻࢿŌŜD 0 ிඣ൫ՈɉȳẴ৪ DPL 2 dzᪿdz΅Type 1 ɉȳẴ৪ DT G=1 KୖǺò 4k 16M 0x00FFF 4k4kɉ└: 0x00000000ȖŌŜ ʒ ɳ}€a {€a S ¡i€Sij~jL€aluuuaŠ€S H€a {Hi€SS {|€a |H€b ȳẴ৪ ƌʔɉ \J|d \J|Š \J|` \J|  \J|æ\J|b \J|a \J|S\J|d\J|Š\J|` \J|  \J|æ\J|b\J|a\J|S \áLMh~Š \áLMh~` Ẵ৪ \rnM€æauuub €SS ʒɳ€IShlb \rnM€bæuuuS€SShSShSS ij~jLM€a`uuuS€SWhWW ~d ~Š ~` ~  ~æ ~b ~a ~Sƌʔɉȳ <0000 0000><1100 0000><1001 0010><0000 0000><0000 0000><0000 0000><0000 1111><1111 1111> ϔǒɉ 1 32 ĹՈȻࢿŌŜD 0 ிඣ൫ՈɉȳẴ৪ DPL A dzᪿdzẔᜐType 1 ɉȳẴ৪ DT G=1 KୖǺò 4k 16M 0x00FFF 4k4kɉ└: 0x00000000ȖŌŜ €ʒ ɳ}€a {€a S ¡i€Sij~jL€aluuuaŠ€S H€a {Hi€SS {|€a |H ȳẴ৪ ƌʔɉ \J|d \J|Š \J|` \J|  \J|æ\J|b \J|a \J|S\J|d\J|Š\J|` \J|  \J|æ\J|b\J|a\J|S \áLMh~Š \áLMh~` Ẵ৪ \rnM€æauuub €SS ʒɳ€IShl \rnM€bæuuuS€SShSShSS ij~jLM€a`uuuS€SWhWW Zd ZŠ Z` Z  Zæ Zb Za ZSƌʔɉȳ <0000 0000><1100 0000><1001 1010><0000 0000><0000 0000><0000 0000><0000 1111><1111 1111> ɉۅÏ &r±ϖ׏4ƷՈʸśuȺƷḰǜtxẟ: .fill 252,8,0 /* space for LDT's and TSS's etc */ .quad 0x0000000000000000 /* TEMPORARY - don't use */ .quad 0x00c0920000000fff /* 16Mb */ .quad 0x00c09a0000000fff /* 16Mb */ _gdt: .quad 0x0000000000000000 /* NULL descriptor */   uØ׏׏ ிඣՈ«ΞŁ᪂ǎ GDT Ո ń head.s)ś੥ˊǡǀtՈ4& ¬4ẝ4᪸ ɦ ƿɆɉՈ੥ˊ IJ«ǒ ┉Z ẝɉś੥ˊ« ̵ƅǒ┉͛5Ո4ȭzƽ͔Ո໇ᔕǒ┉Zẜ«ϵ ৰ 49 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;()chr_dev_init // Ƌ৪᪂̣!ϧĚẝₐ±±«Нrȉǧ ̵ƅǒɴ blk_dev_init(); // ų᪂̣!ϧĚ trap_init(); // )ȕₓ!ϧĚ mem_init(main_memory_start,memory_end); #endif main_memory_start += rd_init(main_memory_start, RAMDISK*1024); #ifdef RAMDISK main_memory_start = buffer_memory_end; buffer_memory_end = 1*1024*1024; else buffer_memory_end = 2*1024*1024; else if (memory_end > 6*1024*1024) buffer_memory_end = 4*1024*1024; if (memory_end > 12*1024*1024) memory_end = 16*1024*1024; if (memory_end > 16*1024*1024) mem ory_end &= 0xfffff000; memory_end = (1<<20) + (EXT_MEM_K<<10); // ŌϧͱƌՈ!ϧĚ drive_info = DRIVE_INFO; ROOT_DEV = ORIG_ROOT_DEV; */ * enable them * Interrupts are still disabled. Do necessary setups, then /* { /* The startup routine assumes (well, ...) this */ void main(void) /* This really IS void, no error he re. */ ňɥϵ 1 ǻẟ࣏ǡǀtr4 0 ǻẟ࣏ ɥ«!ϧẟ࣏ ϬzËᜐ main ϔՈ4 ÂĆ “ϣ 1 ǻẟ࣏Ẕᜐ init ÑȒՈ1 0 ǻẟ࣏ǻẟ࣏ǻẟ࣏ǻẟ࣏ r main() ϔ̠ŌϧËᜐ4 £࿁µųՈ!ϧĚ1ň ϢȒ᫇Ϭ sh ǀt ȳ¬ 4head.s Ո iret ūÐūǣ CPU ՈËᜐḰ4 r4ẝâdzÑ]Ϭ ඊ׏ ਍4ẟ࣏ிඣ׏ǀrú͐͹׏ 4ẝâ'ᡅ« ɆிඣՈȈ ிඣ! ϧĚ࣏Ûƌ΢ ń/init/main.c â ிඣՈ ȳ¬ ẋ࣏͔ᾬ ▊4ẝPâ ৰYতৰYতৰYতৰYত ிඣՈ!ϧĚிඣՈ!ϧĚிඣՈ!ϧĚிඣՈ!ϧĚ ৰ 50 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ẋ࣏ϬĚᜬ߾rẝʳՈ üǸuØdzÑ-Ϭ ƏʄǡµŃ)4 ϢȒ ϬPẘúūÐ ǡǀtɴ Ŗʮ ̩Ո1ň4Ξ Șẝ 4)7QՈźɍ ẝ ɥĉŐrȺẔᜐµśḰdž&Ϭ›µś4)Ո̠ˊ]ẋ«Əʄ໐> Û4)Ɖ¥࣏Û«Ẕᜐńிඣµś[Ո ü ǸĆǕ ϣʄḰdž4Ɵ)ẘúՈrȅ Ćʮ̩ ἗ń Ϭ›µśՈr ȅ Ξ ȘǕ ϣ)Ć᫇ϬிඣՈ)Ɖ¥࣏ک5ͩ«µŃ)ẘú u Ø «à᪩ń Ϭ›µś[ẔᜐՈ üǸᡅń᫇Ϭ fork 7Q Ⱥ࣏ÛՈẔᜐµśḰǜ&Ϭ›µś4 ń᫇Ϭ move_to_user_mode 7Q main ϔPָńிඣźɍ[Ẕᜐ IJ«ÑȒՈẟ࣏ ƅிඣµśḰȕϬ›µśƅிඣµśḰȕϬ›µśƅிඣµśḰȕϬ›µśƅிඣµśḰȕϬ›µś } for(;;) pause(); // 0 ǻẟ࣏Ո1ň4Ǹ඗Ǜ IJ«࣏Ûdz]࿁ỄϦ ¤ÑɥǶɳȫ4 */ * task can run, and if not we return here. * can run). For task0 'pause()' just me ans we go check if some other * as task 0 gets activated at every idle moment (when no other tasks * signal to awaken, but task0 is the sole exception (see 'schedule()') * NOTE!! For any other task 'pause()' would mean we have to get a /* } init(); if (!fork()) { /* we count on this going ok */ // “ϣ 1 ǻẟ࣏ ϬǡËᜐϔ init move_to_user_mode(); // ȺிඣḰ͑Ϭ›µś ÑȒͱʴᡅ̿1ňՈ᪡KᡅϬிඣ᫇Ϭǡǀtr4 sti(); // Ʒń/include/asm/system.h ǎ5&#define sti() __asm__ ("sti"::) // Ōȳ)4ü& ńǸ7Q )P ָ«͟⒱Ո º ǸŌϧɥdzÑ)r4 Sti() «ǃʁÐ floppy_init(); // ḳ֜!ϧĚ hd_init(); // ܰ֜!ϧĚ buffer_init(buffer_memory_end); // ෗Ξľ!ϧĚ sched_init(); // ᫇ò࣏Û!ϧĚ time_init(); // ȳ¬rⒸ!ϧĚ tty_init(); // ඌ঳!ϧĚ ৰ 51 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ úȨ ₎΢ PCB ŤƅՈ 1 )ͱƌ਍4 Ոẟ࣏ỄϦՈrȅ mŅՈ1ň ῁«ϵ 1 ǻẟ࣏ǡ̠ˊՈ ĉŐቻǚẘ ₑᡅՈ ü&̓ᾬ „1 ǻẟ࣏ϬzËᜐϔ init ẝϔĆ͹Ƶ “ϣPẟ࣏ǡËᜐ sh 41 ǻẟ࣏«☢ 1 ǻẟ࣏ǻẟ࣏ǻẟ࣏ǻẟ࣏ :::"ax") "movw %%ax,%%gs" \ "movw %%ax,%%fs \n\t" \ "movw %%ax,%%es \n\t" \ "movw %%ax,%%ds\n\t" \ "1:\tmovl $0x17,%%eax\n\t" \ // )ẘúrĆºẝₐණනËᜐ "iret \n" \ // )ẘú ẝrȅĆʮ̩ɴŖ ȰႸ4Ϭ›ɍՈḰǜ "pushl $1f\n\t" \ // µŃƏ͑)ǕϣrՈϬ› eip ʃǻ 1 «)ẘúrᡅËᜐՈŌŜ ń[☦ "pushl $0x0f\n\t" \ ɉۅ// µŃƏ͑rϬ›ËᜐՈ cs 0x0f ȭàՈ« LDT ՈÏ "pushfl \n\t" \ // µŃƏ͑ʃȣǸƌ„ՈȨ "pushl %%eax\n\t" \ // µŃƏ͑Ϭ›ɍՈ esp Ǹƌ„ՈȨ "pushl $0x17\n\t" \ // µŃƏ͑Ϭ›ɍՈ ss Ǹƌ„ՈȨ 0x17 ȭàՈ« LDT Ոϔǒɉ __asm__ ("movl %%esp,%%eax\n\t" \  // ȺƣǡՈ esp ljƌ4 eax #define move_to_user_mode() \ Ě Y.1 )ǕϣrՈʄ̑Ρ ৰ 52 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;((void) dup(0 (void) dup(0); (void) open("/dev/tty0",O_RDWR,0); setsid(); close(0);close(1);close(2); if (!pid) { } continue; printf("Fork failed in init \r\n"); if ((pid=fork())<0) { while (1) { /* nothing */; while (pid != wait(&i)) // ȐüǸĆණනǶɳ਍Ǒ4 // ΞȘǕɴ« sh Ëᜐ඗Ǜ ɥȕ[Ëᜐ4ΞȘ «͢Ʒẟ࣏ỄϦՈ᪡ ϵzẟ࣏ǻ] if (pid>0) } _exit(2); execve("/bin/sh",argv_rc,envp_rc); // ẔᜐdzËᜐâ sh Ʒ«ிඣƉ¥࣏Û Ĺzâிඣ֜ _exit(1); if (open("/etc/rc",O_RDONLY,0)) close(0); if (!(pid=fork())) { // “ϣPϬzẔᜐ sh Ոẟ࣏ printf("Free mem: %d bytes \n\r",memory_end -main_memory_start); NR_BUFFERS*BLOCK_SIZE); printf("%d buffers = %d bytes buffer space \n\r",NR_BUFFERS, (void) dup(0); (void) dup(0); (void) open("/dev/tty0",O_RDWR,0); setup((void *) &drive_info); int pid,i; { void init(void) static char * envp[] = { "HOME=/usr/root", NULL }; static char * argv[] = { "-/bin/sh",NULL }; static char * envp_rc[] = { "HOME=/", NULL }; static char * argv_rc[] = { "/bin/sh", NULL }; // sh Ոdžϔ ৰ 53 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { /* ()_exit(0); /* NOTE! _exit, not exit } sync(); printf(" \n\rchild %d died with code %04x\n\r",pid,i); break; if (pid == wait(&i)) while (1) } _exit(execve(" /bin/sh",argv,envp)); ৰ 54 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ᫇᪙࣏ÛՈrȅ4&rʃ᪊ẝ࢑̑Ρ ᪂าrẝʳՈźɍ TASK_STOPPED ᜬ߾ẟ࣏ þɈ4ƅՈr ȅẟ࣏^̵ƅ਍ǑǍǻ K]«Ƕ ŷΞ Ǹ«Ȫà᪩$┨à᪩ϵúẟ࣏ǡමĈ rȅɥ ºிඣȺẟ࣏$┨ úẟ࣏ ɥ\ ͩǣ4ẝẘúȨr4ü ᡅՈ Ξ ȘPẟ࣏඗ ǛՈrȅ◄ ᡅȕ úẟ࣏ẘúP ‡Ǎʻ4Ξ Șẝ TASK_ZOMBIE ᜬ߾ẝẟ࣏>ඓǶr IJ«ẜ̵ƅºிඣ$┨ǭ4ẝ«ǔȑ ڱϣ4Ở„ƷՈ਍ǑrⒸɨṇ âǕϣ üǸ¤ƅՈǍǻ῁ĆᝯŦ᰻ָ4ẝwâǕ źɍ4Ʒdz࿁«ń਍ ǑɌP wפ TASK_UNINTERRUPTIBLE Kᜬ߾ẟ࣏Ƿ̠zý ǑỞ„ɨṇ⑃ źɍ Ʒdz࿁ń਍ ǑPǍǻ4ẝ ਍פTASK_INTERRUPTIBLE ᜬ߾ẟ࣏ Ƿ̠zý TASK_RUNNING ᜬ߾ẟ࣏>ඓβ̣ΙŤϬ CPU 4ּƟz8ɥථɍ9 #define TASK_STOPPED 4 #define TASK_ZOMBIE 3 #define TASK_UNINTERRUPTIBLE 2 #define TASK_INTERRUPTIBLE 1 #define TASK_RUNNING 0 state : Ϭzʃ᪊ẟ࣏ՈẔᜐźɍ4Ʒdz࿁«P[όȨ ]࿁ǕϣΝǜ4ẝόǻՈňϬΞ[ z˛ේūϬẝό ǻՈ5ͩɥ«-Ϭẝό ǻՈȻࢿₓ ü ǸẝόȨՈ .Û«ǔₑᡅՈ ūϬẋẝόǻՈȨ ϵۅ 'ᡅ«ńẟ࣏Ո᫇òՈr ȅūϬ4 ń˛ේ΅ՈÏ ẝᾬ long priority; long counter; long state; /* -1 unrunnable, 0 runnable, >0 stopped */ /* these are hardcoded - don't touch */ struct task_struct { ^ẟ࣏᫇òּ͟^ẟ࣏᫇òּ͟^ẟ࣏᫇òּ͟^ẟ࣏᫇òּ͟ /᩶ᢧ4 &όᾬ +£࿁ task_struct Ո඗ȀǡȳẴẟ࣏4&rƫzˊ ᢧẟ࣏ϔǒ඗Ȁ ȈǻՈňϬ u ᩶ẝ‡ǻŭ Linux Ⱥç¥ʐẟ࣏ƟňPú w ƷūϬP ǯɆ«ΞŁᜬ ߾ PCB ẝ඗ȀՈ ɦ PCB 4̱ňிඣ ɥ«Ởẋȭ PCB Ո̱ňǡǒɴȭẟ࣏Ո੥ˊ4 ὧ4ń Linux0.11 ϔǒ ࣏Û  ἗͟zẟ࣏Ոˊ ᩾Z Ոǎ5 Ñ ǎẟ࣏Ո ඈtẟ࣏کº̱ňிඣƣˊ᫂ZuØdzÑ Ð῁ᡅϵƷǡǕϦ4 1ňՈū dzÑ᪸ȭ Linux0.11 Ո1ňƶ :rᢧr4ẟ࣏ிඣɥΙʻ«̱ňிඣՈ ̓࿕ P Ȍr ẝ«P̓ų Ξ Șẟ࣏ிඣr ᢧr ɥ ºẝPতŌϧ ɥ«ȭϘẟ࣏ிඣՈ ৰ÷তৰ÷তৰ÷তৰ÷ত ẟ࣏ՈȳẴẟ࣏ՈȳẴẟ࣏ՈȳẴẟ࣏ՈȳẴ ৰ 55 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ /* /* various fields ẟ࣏ՈPჰȳẴǍʻẟ࣏ՈPჰȳẴǍʻẟ࣏ՈPჰȳẴǍʻẟ࣏ՈPჰȳẴǍʻ 3. Ở„ start_code «ɉՈżĺ঳ start_stack «ɉՈżʌɉ4ü&ʄʺ⑃5ȕ«ȕ[Ո4 2. ɉՈ⑃ò῁«ÑƋᅆ&řĹՈ4 ‡᰻ϧŌŜūϬr⑃ϘƮ4 1. ẝₐՈ᰻ϧŌŜ῁«ūńẝ 64M ाⒸͱՈȻࢿŌŜ ϵzᔞŃŌŜ῁« 32 Ĺ ü Ǹẝ Š᪸Š᪸Š᪸Š᪸ brk «ʇՈϔǒ⑃ò4 ɉՈ⑃òʐϔǒɉՈ⑃ò4ۅ/«Ï end_code ʐ end_data start_stack «ʄՈ᰻ϧŌŜ4 Ո᰻ϧŌŜ4 ɉϔǒɉۅstart_code «Ï Ōẝ࢑̑Ρ4 ɉ^ϔǒɉۅɉ^ϔǒɉՈ᰻ϧŌŜ«PʳՈ ÂƷ]ΓťÏۅʐϔǒɉ4Linux Ï ɉۅŃाⒸ Linux0.11 ẝᔞŃाⒸ « 64M4&rඈඋ Ιẝ 64M ՈͱƌाⒸ ᪂าrÏ ẟ࣏«࣏ÛՈ ṁĿ ࣏Û◄ᡅ¤ṁ4ͱƌ ±࿁̻Ẕᜐ4ẟ࣏ńͱƌƅ؄Ʒ ưƅՈᔞ unsigned long start_code,end_code,end_data,brk,start_stack; ^ẟ࣏ाⒸՈƽǶƅ͟^ẟ࣏ाⒸՈƽǶƅ͟^ẟ࣏ाⒸՈƽǶƅ͟^ẟ࣏ाⒸՈƽǶƅ͟ signaction[32]«ƌʔ^ǍǻՈ̠ˊּ͟ǍʻՈϔඈ ǯɆ8Ǎǻȕₓᜬ94 „94 /ǯɆ8 Ǎǻ ᪻˖Ǹ ƌ„ 9ʐ8ǍǻʃᐁǸƌ signal ʐ blocked ῁« 32 ĹՈĹĚ ܲՈɁ «ʵǒuՈˊᢧේՈ☺ Šƨᵯ̵ƅǒ┉͛ 5 ȺϔȨÑxẟ :ՈƮśᜬ߾Ȓ ɣPĹ ʃ᪊Pźɍ4ǒ ┉Z̵ ƅ dzÑʵǒ¦õΙ╓͛Νǜ.Û4 ·එPɁ ĹĚ ĹĚ«PϔȨ Ở„ẝϔȨ ƅ˛ේ᪱ᣄūϬrẝόǻ üǸƷØՈ.ÛK]࿁Νǜ4ÑȒ᪸ŠՈǻɥ^.Û\͟r ńǍǻ̠ˊPতu Ć᪪ඊՈȭẝόǻẟᜐ᪸Š4ẝ ₐ̴ȭƷØƅ ŴᬥɥdzÑr4K long blocked; /* bitmap of masked signals */ struct sigaction sigaction[32]; long signal; ^Ǎǻ̠ˊƅ͟^Ǎǻ̠ˊƅ͟^Ǎǻ̠ˊƅ͟^Ǎǻ̠ˊƅ͟ priority:ẟ࣏ՈĄ̴൫4ń Linux0.11 Ą̴൫ᱎʌŤϬ CPU ՈrⒸᱎ⑃4 « 10ms 4ƷՈ!ϧȨ^᪩ẟ࣏ՈĄ̴൫ՈȨּ਍4 ÂՈẟ࣏ Ťƅ CPU 4rⒸ ċ«ẟ࣏ẔᜐՈżɃrⒸřĹ4 ń Linux ɣrⒸ ċ4 ɥ«&ɣẟ࣏᪂าPż⑃ẔᜐrⒸ ƟẝrⒸ4rɥₑ,᫇òẟ࣏Ñ ̭᩼ ͢ rẝ Ɂ4 counter ẟ࣏ mŅՈrⒸċ4&r̭᩼Ȉẟּ࣏ȭ͘¿ՈūϬ CPU š͑r ৰ 56 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;unsigned long close_on_exec struct m_inode * executable; struct m_ inode * root; struct m_inode * pwd; unsigned short umask; int tty; /* -1 if no tty, so it must be signed */ /* file system info */ ^࣏Ûâƅ͟^࣏Ûâƅ͟^࣏Ûâƅ͟^࣏Ûâƅ͟ ẟ࣏Ո᰻ϧrⒸ4 Ⓒ Ƅẟ࣏̠zϬ›ɍՈrⒸ Ƅẟ࣏̠zிඣɍՈrⒸ /ᜬ߾ẟ࣏̠zϬ›ɍՈrⒸ ẟ࣏̠zிඣɍՈr utime,stime,cutime,cstime,start_time פإ ΞȘ& 0 ᜬ߾̵ „ՈrⒸǎrפإalarm ẟ࣏ ɍՈrⒸ Ƅẟ࣏̠zிඣɍՈrⒸ4 ›ĉŐrẟ࣏Ո ᰻ϧrⒸ ẟ࣏̠zϬ›ɍՈrⒸ ẟ࣏̠zிඣɍՈrⒸ Ƅẟ࣏̠zϬ Ⓒ ȐʳẝrⒸՈřĹ«rⒸċ4ȐrPẟ࣏ẜᩴơrP‡͢ÂՈrⒸǍʻϬz ɡ᪦ Pẟ࣏dz ࿁◄ ᡅþɈPɉrⒸ ϢȒ͹ᆓ⁖ẋǡ üǸ◄ ᡅƅPǜₓǡᩴơẝr long utime,stime,cutime,cstime,start_time; long alarm; ^rⒸƅ͟^rⒸƅ͟^rⒸƅ͟^rⒸƅ͟ unsigned short gid,egid,sgid; unsigned short uid,euid,suid; ^ᵯéɀ᪅ƅ͟^ᵯéɀ᪅ƅ͟^ᵯéɀ᪅ƅ͟^ᵯéɀ᪅ƅ͟ leader: ǡ᪃Ոẟ࣏à᪩ƅP8̫͐9 leader ɥ«ʃ᪊ẝՈ4 session Ȩ«ּ਍Ո sessionϬzʃ᪊]ȐՈǡ᪃ՈϬ›ẟ࣏ ƅẝ‡ẟ࣏“ϣՈƄẟ࣏^ּàՈúẟ࣏Ո pgrp ඈՈʃ᪊ ẝȨּȐՈẟ࣏ĹzȐPඈͱ father «úẟ࣏Ո PID ǻ ẝʳɥƮtr8Ǫ᫵ʍ9 pid «ȭẟ࣏Ո̳Pʃ᪊ ỞẋẝȨdzÑ̳PՈâ4ẝẟ࣏ exit_code «࣏ÛẘúȨ ՈϬ›K◄ᡅᡅPʃ᪊4 ]Ȑ 4&rľ Ϭ›ȴƇPẟ࣏ Ȑrẝẟ࣏dz࿁Ć “ϣƄẟ࣏ẝdzÑ᪸«PǎՈ ඈՈɁPẟ࣏dzÑȕ̶ẟ࣏ ǕễȐP4ʻ4 ń̶Ϭ›Ո̑Ρ[◄ᡅ&ɣP᪃⒲Ո ͟ிՈ4ẝ͟ிdz࿁«úƄ͟ி Kdz࿁«╺ʒzȐP ඈՈ͟ி4ඈ«ǔƅϬՈ ϵz &r࿁̻ ੥ˊẟ࣏ ɥ◄ ᡅ࿁̻̳PՈʃ᪊Pẟ࣏ Ȑrẟ࣏^ẟ࣏7Ⓒdz ࿁«ƅẢr long pid,father,pgrp,session,leader; int exit_code; ৰ 57 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ [#define LAST_TASK task[NR_TASKS -1 #define FIRST_TASK task[0] &r±ìՈȳẴẝඃ ɳᜬՈ͐ʐ ɲ Linux njǎ5r ǃ4 ǒ┉Z]ȐźɍՈẟ࣏«ǔ╓ƶՈ΢4 task Ո4 ṉ́ňிඣƣˊ᫂Zඓ„ȴ4ɥථⓣ ȭz Linux0.11 ǡ᪸Ʒ«PỿṕZՈ඗Ȁ 4͟z!ϧẟ࣏ init_task.task Ⱥń[Pত·එ4 ᪂าrPȨ &(init_task.task) ẝɥ«ūȕ!ϧẟ࣏Ոū⍌ ᜬ ߾!ϧẟ࣏ƌ΢ń task[0] ẝʳ̱ňிඣ ɥdzÑỞẋ task ǡâ4çŁPẟ࣏r4dzÑ ׏4ńᜬ!ϧՈrȅɥ struct task_struct * task[NR_TASKS] = {&(init_task.task), }; ඃɳᜬɥ« task 4 ń̶ẟ࣏4&r ඈඋ Ιẝ‡ẟ࣏ Linux0.11 ūϬrPඃɳᜬǡƌ΢ẝ‡ẟ࣏4ẝ ȐrPி ඣĆƌ Ɖ☤ PCB ඗ȀՈ ɥ«ẝ task_struct »کᩥਜ਼ƶȭẟ࣏Ոͫ کᩥਜ਼ƶȭẟ࣏Ոͫکᩥਜ਼ƶȭẟ࣏Ոͫکᩥਜ਼ƶȭẟ࣏Ոͫکᩥਜ਼ƶȭẟ࣏Ոͫ ͟z tss ඗ȀՈ᪪ඊ·එȺń[Pত᩶ᢧ4 â5ͩՈËᜐợò:]̶4 5ͩ4 ḳâ5ͩdzÍʉ ɳɨ ܰâ5ͩΙ4]ᡅÑ&ƅ ܰâ5ͩPǎɥȷ ͢ǒ ܰâ5ͩ^ ḳ 4IJ«ńÑȒՈČ ƨ Linux0.11 ɥ]͹«-Ϭẝ࢑ܰâƶ :r ΝϬrḳâՈۅ̶ՈÏ džՈrȅɥ«-Ϭrẝ5ƫλɅrǔ Linux0.11 ńẟᜐẟ࣏ ඊՈ᩶ᢧ ȺńȒ☦ǝẴ ۸ūr࣏ÛËᜐ.ÛՈ̱ňՈrȅ Intel ĆႮ¬ ՈȺƟQՈǸƌ„źɍᩴơ4 tss 4 ᪪ ẝ඗Ȁ᪂า Ιr Ɵ Ōẟᜐ Ɍ࢑ ܰâZȴ ƇrΓť ɥ«᪸ ǮᡅŌȺ tss ç¥źɍɉ ç¥źɍɉՈϔǒ඗Ȁǡljƌ4ẝ඗Ȁẜ«ϵ Intel ȴϦǡՈ &rljƌźɍǍʻ Intel º dž QȈǸƌ„źɍՈ ẝ ‡źɍūϬrPǯɆ džՈrȅ«◄ᡅljƌẟ࣏ ẟ࣏ń }; struct tss_struct tss; /* tss for this task */ ç¥źɍɉç¥źɍɉç¥źɍɉç¥źɍɉ ाⒸՈrȅɥ-Ϭ4r4 ‑ẟ࣏ ŌϧՈǻǰẜ«ᡅϬ4ɴᾬȳẴ৪ᜬ4 ^ϢƅrɴᾬȳẴ৪ᜬɥ.ƫϬϬ ȫ ń ᜬr4>ඓ᪸ẋr Linux ͢ǒ̵ƅūϬɉś੥ˊ ±±ūϬr)ś੥ˊ4 IJ«&rˑà Intel ȭzிඣͱʴǡ᪸ūϬՈ«͔ɴȳẴ৪ᜬ ໐ȭz ɣPẟ࣏ǡ᪸ ɥᡅ«ϬɴᾬȳẴ৪ struct desc_struct ldt[3]; /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ ɴᾬȳẴ৪ᜬɴᾬȳẴ৪ᜬɴᾬȳẴ৪ᜬɴᾬȳẴ৪ᜬ struct file * filp[NR_OPEN]; ৰ 58 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ /* ec,brk... */ 0,\ //exit_code=0 0, \ //blocked=0 ᜬ߾]⓿ɺçŁǍǻ {{},},\ //sigaction[32]={{},} Ǎǻȕₓᜬ&ा /* signals */ 0,\ //signal=0 ᜬ߾̵ƅçŁǍǻ 15, \ //priority=15 ẔᜐՈĄ̴ƿ //priority ՈȨּ਍ 15,\ //counter=15 ç¥ẔᜐՈrⒸċ(150ms) ŌϧՈrȅ^ 0,\ //state=0(TASK_RUNNING) ᜬ߾dzÑẔᜐɥථ /* state etc */ { #define INIT_TASK \ */ * your own risk!. Base=0, limit=0x9ffff (=640kB) * INIT_TASK is used to set up the fi rst task table, touch at /* Ξ[ۅẔᜐ ໐«&͢ƷՈẟ࣏ȴƇP̩:ՈȖͥ4Ï !ϧẟ࣏ÏᜬՈ«ͱʴՈẟ࣏ IJ«Ʒ]Ćᝯ᫇ò࣏Û᫇òՈ4ƷՈֲՈ Ǿ]«&r ᩭͱʴ 4࣏ÛՈ4΅9 ۅẟ࣏Ո ࠚ̴ẟ࣏ Ʒ«Ởẋ8ܰේ ±>ඓ ȴ4r!ϧẟ࣏«P !ϧẟ࣏!ϧẟ࣏!ϧẟ࣏!ϧẟ࣏ Ⓒ4 ‑ͱƌा ǎՈǸƌ„ !ϧĚՈrȅKᡅ᩶ẝ‡Ǹƌ„ՈȨ᪂ǎΙ4Ȑrᡅ&P‡ᜬ඗Ȁ ‑ाⒸՈr ȅ Ȩ ɥ>ඓ᪂ǎΙr4 Ǫ̲ ẟ࣏ ńẔᜐՈrȅĆūϬP‡Ė tՈ4ń&͢ ΅ۅẟ࣏Ոࠚ̴ẟ࣏ ẝ ɥ«!ϧẟ࣏4ƷՈ task_struct ඗Ȁ« ָȉϬÏ P ẟ࣏«P !ϧĚɥĉŐ rẝ ࢑4ϵz Linux ῁«Ởẋ̩:úẟ࣏ǡ“ϣ,ẟ࣏Ո ü Ǹȑ/ƅP mem[3]={1, 2, 3}; ǪP࢑« ń࣏ÛẔᜐ᪂าՈ ŷΞ mem[0]=mem[1]=mem[2]=0 4ẟ࣏Ո ‑ƌ ʔाⒸՈr ȅ>ඓƽǶ ΙՈ ŷΞ int & ࢑ P࢑« ń ࣏ÛՈ!ϧĚdzÑ ȌȈ£࿁ϔ7Q u◄ᡅ̴᩶P[ẟ࣏Ո!ϧĚ4 üǸ ń 4 Ȉǜₓ᪂าՈȨẝ«ₑ7ₑ ɘ͢« ń!ϧĚՈrȅȭ ףuȭȒ☦Ոˊ ᢧ“ϣr Ȼ:4ẝâw7Ȓ uȭ! ϧĚۤᩨ Ȍ ǕɴrP̠ˊᢧՈ⏝ ᪳4ɥ«ü&ẝ⏝ ᪳ū ₑ , z«uȭ ᰻ϧẟ࣏ INIT_TASK K̵ƅᢧΟ4̶{r᰹͛Ş̇ Ոȴ߾ ūuͫᢍ4⒲LՈʵļdz࿁ǡႷz!ϧĚ4ۅ̶ἑÏ ẝâ wČÔruǔ⑃rⒸ u ׏rǔ‑ͱƌ)Ոr ȅ\ dzϬͱƌ ẝ] ɥ« bug rț ˖ )śᯡՈϔՈrȅĆΝǜœȸϔඈ mem_map[] ¤ƅՈȨ ẝʳȰႸՈ඗Șɥ«͹Ƶᡅ Ȍ fork ϔՈrȅ ǕɴƷ ń᫇ϬP r ǕϣՈ wƟuۅ ȌÏ ńǸu̿ ᩶Pâ Н[࠼ʵ4 Ոˊ ᢧۅṇᩨdzº!ϧĚŌϧ͑ ¯4ɘ͢ȭzP ‡᰻ ϧՈϔǒ Ξ Ș̵ƅˊᢧΙĆ ȭÑȒÏ Ȍ uPȕɨ ՈۅՈQȴɥ «!ϧĚ4ȭzÏ ń࣏Û᪂ᩥ dzÑ᪸ ɆçŁPᾬ ৰ€তৰ€তৰ€তৰ€ত ẟ࣏ிඣՈ!ϧĚẟ࣏ிඣՈ!ϧĚẟ࣏ிඣՈ!ϧĚẟ࣏ிඣՈ!ϧĚ ৰ 59 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { \ ,{ \ {} \ , _LDT(0),0x80000000 0,0,0x17,0x17,0x17,0x17,0x17,0x17, \ 0,0,0,0,0,0,0,0, \ /*tss*/ {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir, \ }, \ {0x9f,0xc0f200}, \ {0x9f,0xc0fa00}, \ {0,0}, \ /* ldt */ { \ //ldt[3] /* filp */ {NULL,}, \ //filp[]={NULL} ẟ࣏ūϬՈâᜬ඗Ȁ 0,\ //close_on_exec=0 Ëᜐr͟⒱âǩɀĹĚʃȣ NULL, \ //executable=NULL Ëᜐâ I ᅆͥ඗Ȁ NULL,\ //root=NULL ʵֲơ I ᅆͥ NULL,\ //pwd=NULL ƟQ1ňֲơ I ᅆͥ ņʒɳʃᐁĹ0022,\ //umask=0022 â /* fs info */ -1,\ //t ty= -1 ẟ̵࣏ƅūϬ tty „/* math */ 0, \ //used_math=0 «ȪūϬrœ̠ˊ 0, \ //start_time=0 ẟ࣏ŌϧẔᜐr? 0,\ //cstime=0 Ƅẟ࣏ிඣɍẔᜐrⒸ 0,\ //cutime=0 Ƅẟ࣏Ϭ›ɍrⒸ 0,\ //stime=0 ிඣɍrⒸ 0,\ //utime=0 Ϭ›ɍrⒸ /* alarm */ 0,\ //alarm=0 ĉᨪǎrȨ̵ƅ᪂ǎ 0, \ //sgid=0 ljƌՈඈ id 0,\ //egid=0 ƅάඈ id 0,\ //gid=0 ඈʃ᪊ǻඈ id 0,\ //suid=0 ljƌՈϬ› id 0,\ //euid=0 ƅάϬ› id /* uid etc */ 0,\ //uid=0 Ϭ›ʃ᪊ǻϬ› id 0, \ //leader=0 0,\ //session=0 0,\ //pgrp=0 úẟ࣏ඈǻ -1,\ //father= -1 úẟ࣏ǻᜬ߾̵ƅúẟ࣏ /* pid etc.. */ 0,\ //pid=0 0 ǻẟ࣏ ‑ʄ 0, \ //start_stack=0 ᜬ߾ẜ̵ƅ 0,\ //brk=0 0,\ //end_data=0 ϔǒɉՈ⑃ò ɉՈ⑃òۅ0,\ //end_code=0 Ï ɉ᰻ϧŌŜۅ0,\ //start_code=0 Ï ৰ 60 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ \N æ z ś ʸ Ո ᾬ ƨ Ȗ ɉ ɍ ź ¥ ç {N æSz IN bIz N b‰z Wi}Q b z JH bSz IXæ aIz SSSSSSSSSSSSSSSS QQb a‰z QHb a z SSSSSSSSSSSSSSSS QQa aSz QHa SIz ‰ SSSSSSSSSSSSSSSS QQS QHS   SSSSSSSSSSSSSSSS ⏂ȉƋɉ S \J|æa4\J|aŠ \J|a`4\J|a \J|SYWWQ| Pϔǒ඗Ȁ TSS 4ƷՈʸśΞ[ Ǯ«ńẟᜐɉⒸḰࢿՈrȅǕϣrP‡ǜĚ ͢P -ɥ«ljƌ ɳʟ 4ͱƌ4ü ǸšϦr &ɉⒸḰࢿʐɉͱḰࢿ4ljĈµś[KPʳ ǒµśՈrȅËᜐḰࢿ ūÐ CALL ūÐ ç¥źɍɉç¥źɍɉç¥źɍɉç¥źɍɉTSS Ȍr4 ɉǔʻ ɥ]ۅϔǒɉzÏ 4k Ո᪃⒲ाⒸ4Ȑr DPL Kǜtr 34uŌϧՈrȅȺɉА└Ɵt« 0x07FF ȭà 16M ẝ᪸Š !ϧẟ࣏ ẜ«Ñ 0x00000000 &ȖŌŜ IJ«ɉ А└Ÿ« 0x09F4ȭàՈ« 160 €ʒ ɳ}€a {€a S ¡i€Sij~jL€aluuuaŠ€S H€a {Hi€aa {|€a |H ȳẴ৪ ƌʔɉ \J|d \J|Š \J|` \J|  \J|æ\J|b \J|a \J|S\J|d\J|Š\J|` \J|  \J|æ\J|b\J|a\J|S \áLMh~Š \áLMh~` Ẵ৪ \rnM€æauuub €SS ʒɳ€IShW \rnM€bæuuuS€SShSShSS ij~jLM€a`uuuS€SShlW Zd ZŠ Z` Z  Zæ Zb Za ZSƌʔɉȳ ɉՈϔǒʇ͑ȳẴ৪ۅŭ+ȳẴ৪ՈʸśȺÏ 0x00 c0 f2 00 00 00 00 9f 0x00 c0 fa 00 00 00 00 9f 0x00 00 00 00 00 00 00 00 ᰻ϧẟ࣏Ոẝ 3 ɴᾬȳẴ৪ʉŌȒ« ˊᢧƽˑǔ̓4 ȌPἑ«&rš᰻ͼ͛ 4ü&ƷȭȒ☦Ո ȳẴ৪ᜬՈ඗Ȁ>ඓńQ☦᩶ẋr ẝ ₐnj ɴᾬȳẴ৪ᜬՈ᪂ǎɴᾬȳẴ৪ᜬՈ᪂ǎɴᾬȳẴ৪ᜬՈ᪂ǎɴᾬȳẴ৪ᜬՈ᪂ǎ ৰ 61 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ºᔞŃŌŜाⒸ4ඃɳŌŜाⒸՈœȸ ϵ }{| ʐ i{| ܲǎ ^ Ľǎç¥ּ͟Ոᾬ  ŌŜœȸǸƌ„ľǻŌŜœȸǸƌ„ľǻŌŜœȸǸƌ„ľǻŌŜœȸǸƌ„ľǻ ȕ̲ɶẘú4 ͱɶḰࢿՈỖ ƞ P bǕϣȕɌ൫ ͱɶՈḰࢿ ὧ4ẘú4 ̲ɶՈǷ„Ộǐ«ּĽ‑Ո ՈȨ4ẝᜬŠȕͱɶḰࢿr ʇ« îͱɶȢʄᩨ&«Pा ʄ4ü Ǹ ] ̭᩼ǕϣȐ൫ ʄū⍌ľǻ4ǒ ┉Z ̠ˊ„º]ȕ᪩ľǻ ẟᜐ΅͑ ┨☢࣏Û᪂ᩥ້ᩨ&Νǜ᪩ľǻ IJ« Ɵ Ľƿ൫ϵͱɶȕ ̲ɶǜdžr Â]îͱɶ ȢʄՈū⍌ljƌ4 |QQ ՈͱɶȢ ü& æ ൫«ż̲ɶ ¤ÑçŁPȕͱɶՈḰࢿ῁]dz࿁Ḱࢿ4 æ ൫4 „Ñǜdž4ͱɶȢʄ ̲ɶȢʄՈū⍌ljƌ ńͱɶȢʄ4 ̵ƅūȕ æ ൫Ȣʄ Ոū⍌  3ab ǎ bS ŌϧՈĹา4Ɵ ǕϣȕͱɶḰࢿr îỆƟՈȢʄū ⍌ញ͑ QQ ǎ QH Ǹƌ /ū ȕ S ൫3a ൫ʐ b ൫Ȣʄ Ոʄ* ƉƵ ƌ΢ ń |QQ Ȼࢿ& Ƅʐ æb ĹՈ Ȼࢿ |QQ ՈͱɶȢʄū ⍌ľǻƅY Ȣʄū⍌ Ʒ Ø῁ «  ‰ ĹՈ͔ū⍌€aŠ ĹՈọō ū⍌4 ൫Ȣʄ4¤Ñ Pç¥dz ࿁ͣƅ÷ Ȣʄ ȭà÷Ľƿ ൫4÷ Ȣʄ ◄ᡅ÷Ȣʄ Ɵºͱɶ Ľƿ ൫ S ǜdž4̲ɶĽƿ ൫ æ r ç¥ūϬՈȢʄ KȐrº S ൫Ȣʄ ǜdž4 æ ̲ɶĽƿ ൫ æ ǜdž4ͱɶĽƿ൫ S r ç¥ūϬՈȢʄKȐrº æ ൫ǜdž4 S ൫Ȣʄ &rƅάŌǒɴljĈ ȐPç¥ ń]ȐՈĽƿ ൫[ūϬ] ȐՈȢʄ 4ŷΞ Ɵº  ͱɶȢʄū⍌ľǻͱɶȢʄū⍌ľǻͱɶȢʄū⍌ľǻͱɶȢʄū⍌ľǻ    Ĺ ƽǶ͹ǐƋՈĺ aŠ Ĺ ʌ aŠ ĹƦϬ Pჰàʇ& S4 ŠP æb ĹՈǐƋȈɉǸƌ„KȭàP æb ĹՈ ǐƋ ɉǸƌ„Ոọō ƄǮ ƅ a ºZᜬdzᢅ ȈỞ ϬǸƌ„ȭàP æb ĹՈ ǐƋ ūÐū ⍌ʐʃȣǸƌ„Ȉȭà ç¥࿁̻ʮ̩Ëᜐ4 ljƌľǻ ʮ̩Ϧẝ ‡Ǹƌ„ՈȨ º ໐ ū̠ˊ„ ʮ̩t᪩ç¥džϦ QՈźɍ żඌū džúƣç¥r ͹º džϦr ẝ ‡Ǹƌ„ՈƟ QȨɥljƌń᪩ľǻ4Ɵ[ Ƶ ç¥ᝯ ūÐū⍌ʐʃȣǸ ƌ„4Ɵ |QQ ȭàՈç¥ Ƿń Ëᜐr ljƌ ľǻ «Ʀǎ5Ո ńƟQ Ǹƌ„ljƌľǻĹz |QQ ͱȻࢿ bSz Ⴗ `Wz ̠ ϬzljƌỞϬǸƌ„ 3ɉǸƌ„3  Ǹƌ„ljƌľǻǸƌ„ljƌľǻǸƌ„ljƌľǻǸƌ„ljƌľǻ /᩶ᢧẝ€ľǻ ŌŜœȸǸƌ„ľǻ3Ǹƌ„ljƌľǻʐ͢ƷƋɉ਍€ľǻ4u &⏂ȉƋɉľǻ 3ͱɶȢʄū⍌ľǻ 3 ඣḳâẜdzǎ5ᆩ¾┈¤Ǎʻ4ȖƨՈ aS  Ƌᅆdz |QQ ՈȖƨʸśϵ aS  Ƌᅆඈt4ẝ aS  ƋᅆՈȖƨ ʸś«]dz ΝǜՈ IJńǸ7̲ ி JwY ᩼dzĹĚȻࢿ SSSSSSSSSSSSSSS | Š z SSSSSSSSSSSSSSSS i{|X ŠSz SSSSSSSSSSSSSSSS }Q `Iz SSSSSSSSSSSSSSSS WQ `‰z SSSSSSSSSSSSSSSS {Q ` z SSSSSSSSSSSSSSSS QQ `Sz SSSSSSSSSSSSSSSS IQ  Iz SSSSSSSSSSSSSSSS Q  ‰z {J   z QJ  Sz \H æIz QH æ‰z ৰ 62 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ QH€S æ‰z ś ʸ Ո ᾬ ƨ Ȗ ɉ ɍ ź ¥ ç \N€S æ z {N€S æSz IN€S bIz N€S b‰z Wi}Q€S b z JH€S bSz sjだaIz IX怐ot SSSSSSSSSSSSSSSS QQb€S a‰z QHb€S a z SSSSSSSSSSSSSSSS QQa€S aSz QHa€S SIz ‰ SSSSSSSSSSSSSSSS QQS€STaS   Lrnm QJ›jKjL QHSH} S SSSSSSSSSSSSSSSS ⏂ȉƋɉS \J|æa4\J|aŠ \J|a`4\J|a \J|SYWWQ| !ϧẟ࣏Ո!ϧẟ࣏Ո!ϧẟ࣏Ո!ϧẟ࣏Ո TSS |QQ Ō͐Ōϧᩥਜ਼4͟z JwY ᩼dzĹĚՈňϬ ÑȒՈতȺĆ᪪ඊ·එ4 4ń |QQ ͱȻࢿ ŠŠz ̠Ո ƋϬzƌ΢ JwY ᩼dzĹĚ ń |QQ ͱՈȻࢿ€º ň& |QQ ՈÍʉ ᾬ  &rǒɴ ṗ͑wṗϦljĈ ᡅūϬ JwY ᩼dzĹĚ4ç¥ūϬՈ JwY ᩼dzĹĚKƌ΢ń |QQ  ͢ƷƋɉ͢ƷƋɉ͢ƷƋɉ͢ƷƋɉ Ƌɉ¤ūʮ̩4⏂ZՈQPç¥4 ńẘúr ϵz Ž| ʃȣ Ĺ& a ẘú ūÐ X| z)ẘúūÐ JX| Ⱥūǣȋ: ͓⏂ȉ ᰻ç¥Ո h|QQ Ոọō Ƅ ÂʃȣǸƌ„ Wi}Q Ո Ž| Ĺᝯา a ū⏂ȉƋ ɉƅά4 ΞȘƟQՈç¥ϵɉⒸ᫇Ϭ ūÐ Iii z)wŎ„໐ɬϏ ὧ4⏂ȉƋ ɉljƌ ᝯŦ Ō aŠ ĹljƌQPç¥Ո |QQ ȳẴ৪ՈọōƄ4 ⏂ȉƋɉƽǶ ń |QQ ͱȻࢿ S ŌϧՈ ǐƋ ͢ʌ aŠ ĹƦϬ4 ń᰻ ⏂ȉ ňϬr  ⏂ȉƋɉ⏂ȉƋɉ⏂ȉƋɉ⏂ȉƋɉ ľǻּàƋɉ4 „ΞȘ࣏Û Νǜr i{|X z IXæ ὧ4ȑ/î,Ȩ¦&Ōljƌ4 |QQ ՈŌŜœȸ Ǹƌ ƌ4 |QQ ՈŌŜœȸ Ǹƌ„ľǻ 4wǒZ ̠ˊ„Kºǡ]ȕ᪩ľǻ Ⴎ¬ ΅͑4ü Ǹ džr ̠ˊ„Â]îdžϦç¥IJ«Ո Ǹƌ„ IXæ ʐ i{|X Ոͱ ǭlj IJ« ńç¥ /ញ͑4Ǹƌ„ IXæ ʐ i{|X4ẝʳɥΝǜrᔞŃŌŜाⒸ4ĭˊŌŜाⒸՈœȸ4 džr ̠ˊ„ Ⴎ¬ ºᡅËᜐç¥Ո |QQ ǚϦẝ Ƌɉ ƋƋɉ€i{|Xඈt4 ńç¥ |QQ ՈŌŜœȸ Ǹƌ„ľǻϵĹzȻࢿ aIz ̠Ո ǐƋƋ ɉ€IXæʐĹz Ȼࢿ ŠSz ̠Ո dž4 dž ŌŜœȸ͟ிKᡅ ¥ּ͟ՈᔞŃŌŜाⒸ4ĭˊŌŜाⒸՈœȸϵ i{|X ʐ IXæ ܲǎ4ºϢ ╓؄ç¥Ո ŌŜाⒸՈœȸϵĉȯ )ֲơᜬ᰻ϧĭˊŌŜՈ ȋ: Ǹƌ„ IXæ ܲǎ4¤Ñ ^ Ľǎç )ƶ : ὧ4ϵඃɳŌŜाⒸ4ĭˊ ϵ i{| ܲǎ ໐ i{| njϵ i{|X ܲǎ4ΞȘ₋Ϭ ৰ 63 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ «PūȕƟQ1ňẟ࣏Ոū⍌ ń!ϧĚՈrȅ᪂า&ūȕ!ϧẟ࣏4 current static union task_union init_task = {INIT_TASK,}; }; char stack[PAGE_SIZE]; struct task_struct task; union task_union { Ʒ«Pń sched.c ǎ5Ո͔ɴǜₓ Ïᜬ!ϧẟ࣏4 init_task Š]«ǎ54 idt ʐ gdt ȭà؄ setup.s ʐ head.s Ո _idt ʐ_gdt4ü Ǹ ńିƧ Q¤Zr extern ᜬ߾̌ extern desc_table idt,gdt; desc_table K«PିƧ ȭàՈ«ȳẴ৪ᜬିƧ4ü& IDT ʐ GDT ῁ƅ 256 -4 } desc_table[256]; unsigned long a,b; typedef struct desc_struct { ǡᜬ߾ȳẴ৪ିƧ4 ϵzȳẴ৪Ở„῁« 8 Ƌᅆ ü Ǹ&Ʒǎ5r 8 ƋᅆՈ඗Ȁ Ŀ Ϭẝ඗ȀĿିƧ ȳẴ৪ିƧȳẴ৪ିƧȳẴ৪ିƧȳẴ৪ିƧ ό„ϬՈିƧʐ͔ɴǜₓό„ϬՈିƧʐ͔ɴǜₓό„ϬՈିƧʐ͔ɴǜₓό„ϬՈିƧʐ͔ɴǜₓ JwY ᩼dzĹĚȻࢿ SSSSSSSSSSSSSSS | Š z i{|€S ŠSz €SSSSSSSSSSSSSSSS i{|X SSSSSSSSSSSSSSSS }Q€STad `Iz SSSSSSSSSSSSSSSS WQ€STad `‰z SSSSSSSSSSSSSSSS {Q€STad ` z SSSSSSSSSSSSSSSS QQ€STad `Sz SSSSSSSSSSSSSSSS IQ€STad  Iz SSSSSSSSSSSSSSSS Q€STad  ‰z {J€S   z QJ€S  Sz \H€S æIz ৰ 64 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;(outb(inb_p(0x21)&~0x01,0x21 set_intr_gate(0x20,&timer_interrupt); outb(LATCH >> 8 , 0x40); /* MSB */ outb_p(LATCH & 0xff , 0x40); /* LSB */ outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ «!ϧĚǎr„ Ⱥńǎr„Pত·එ // P[ᾬ lldt(0); // ᪂า LDTR Ǹƌ„ ū͢ūȕՈƟQẟ࣏Ո LDT&!ϧẟ࣏Ո LDT ltr(0); // ᪂า TR Ǹƌ„ ū͢ūȕՈƟQẟ࣏Ո TSS&!ϧẟ࣏Ո TSS __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl"); /* Clear NT, so that we won't have troubles with that later on */ } p++; p->a=p ->b=0; p++; p->a=p ->b=0; task[i] = NULL; for(i=1;i ϔẜĉŐrȭǎr„Ո!ϧĚ4 ϔՈr ȅᩥਜ਼ƶǮƅP!ϧẟ࣏ ü Ǹᡅ±ाç¥ᜬÑǎּàՈ⒬ȳẴ৪4 Ǫ̲ ẝ ৪â4Ո ü Ǹ◄ᡅ&!ϧẟ࣏᪂าƅ͟Ո TSS ʐ LDT Ո⒬ȳẴ৪4 Ȑr ü&᫇Ϭẝ ń!ϧẟ࣏᪂าr TSS ʐ LDT IJ«ᩥਜ਼ƶȭẝ ‡඗ȀՈūϬ«ỞẋּàՈ⒬ȳẴ ẟ࣏Ո!ϧĚẟ࣏Ո!ϧĚẟ࣏Ո!ϧĚẟ࣏Ո!ϧĚ struct task_struct *current = &(init_task.task); ৰ 65 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ \ ""movb %%al,%3 \n\t // ȺȖŌŜʌƋĺƋᅆࢿ͑ȳẴ৪ৰ 4 Ƌᅆ "rorl $16,%%eax\n\t" \  // ȺȖŌŜʌƋࢿ͑ ax "movw %%ax,%2 \n\t" \ // ȺȖŌŜՈĺƋ΢͑ȳẴ৪ৰ 2-3 Ƌᅆ "movw $104,%1 \n\t" \ // Ⱥ TSS ⑃ò 104 Ƌᅆ΢͑ȳẴ৪⑃òǻ(ৰ 0-1 Ƌᅆ) __asm__ ( #define _set_tssldt_desc(n,addr,type) \ // %5 - (ȳẴ৪- n ՈŌŜȻࢿ 6 ̠)%6 - (ȳẴ৪- n ՈŌŜȻࢿ 7 ̠) // %3 - (ȳẴ৪- n ՈŌŜȻࢿ 4 ̠)%4 - (ȳẴ৪- n ՈŌŜȻࢿ 5 ̠) // %0 - eax(ŌŜ addr) %1 - (ȳẴ৪- n ՈŌŜ)%2 - (ȳẴ৪- n ՈŌŜȻࢿ 2 ̠) // type - ȳẴ৪ՈʃȣିƧƋᅆ4 // ŌŜ4 // džϔn - ń͔ɴᜬȳẴ৪- n ¤ȭàՈŌŜaddr - źɍɉ/ɴᾬᜬ¤ńͱƌՈȖ // ń͔ɴᜬ᪂าç¥źɍɉ/ɴᾬᜬȳẴ৪4 ẝₐūϬՈ_set_tssldt_desc() K«ǃǎ5 #define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0x82") // n - «᪩ȳẴ৪Ո ū⍌addr - «ȳẴ৪Ո ȖŌŜȨ4ɴᾬᜬȳẴ৪ՈିƧ« 0x82 4 #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),addr,"0 x89") // « 0x894 // n - «᪩ȳẴ৪Ոū⍌addr - «ȳẴ৪ՈȖŌŜȨ4ç¥źɍɉȳẴ৪ՈିƧ  ẝ«ǃǎ5Ϭz᪂า TSS ʐ LDT Ո ǎ5ń/include/asm/system.h  3. set_tss_desc(n,addr) ʐʐʐʐ set_ldt_desc(n,addr) « gdt+4 8 Ƌᅆʐ gdt+5 8 Ƌᅆ4 ẝₐūϬr gdt+ FIRST_TSS_ENTRY ʐ gdt+ FIRS T_LDT_ENTRY ȭàͱƌՈŌŜǒ┉ üǸȭzିĨ gdt+n Ո̱ňǒ┉Z«ȭàՈŌŜ« gdt+n 8 Ƌᅆ4 ŤϬ 8 Ƌᅆ4 gdt «ǎ5 ń/include/linux/head.h Ո desc_struct ିƧȳẴ৪ିƧ 2. gdt: !ϧĚՈrȅ ȺּàՈ TSS ʐ LDT ¤ȭàՈͱƌř̯±ा4 ẝₐϬẝିƧǎ5rPǜₓ p Ϭǡ ūȕ TSS ᜬʐ LDT ᜬŊ ϢȒńȭẟ࣏ᜬẟᜐ } unsigned long a,b; typedef struct desc_struct { /include/linux/head.h Ɵ4 4Ʒ«ǎ5ń ՈିƧ Ϭǡᜬ߾PȳẴ৪ିƧ 64 Ĺ ẝ«P Ť 8 Ƌᅆ64 Ĺ  1. struct desc_struct Š᪸Š᪸Š᪸Š᪸ } set_system_gate(0x80,&system_call); // ᪂า 0x80 &ிඣ᫇ϬՈ͑ǧ ৰ 66 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ((#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3 ǎ5Ξ[ ẝₐ_TSS(n)ʐ_LDT(n)ᜬ߾ẟ࣏ n Ո TSS ȳẴ৪ʐ LDT ȳẴ৪ GDT ՈȻࢿŌŜ4 #define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n))) #define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n))) TR ʐ LDR Ǹƌ„4 ǎ5ń/include/linux/sched.h  Ϭz ¤ṁৰ n ǻẟ࣏Ո TSS ȳẴ৪ʐ LDT ȳẴ৪4 5. ltr( n)ʐʐʐʐ lldt( n) Ě €.1GDT ᜬՈ඗ȀĚ ẝₐ5ǎ4r TSS ʐ LDT ȳẴ৪ń GDT Ոƌʔ͟ி4GDT Ո඗ȀΞĚ #define FIRST_ LDT_ENTRY (FIRST_TSS_ENTRY+1) #define FIRST_TSS_ENTRY 4  ǎ5ń/include/linux/sched.h  4. FIRST_TSS_ENTRY ʐʐʐʐ FIRST_LDT_ENTRY ) "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \ ::"a" (addr), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \ "rorl $16,%%eax" \ // eax ±► "m ovb %%ah,%6 \n\t" \ // ȺȖŌŜʌƋʌƋᅆࢿ͑ȳẴ৪ৰ 7 Ƌᅆ4 "movb $0x00,%5 \n\t" \ // ȳẴ৪Ոৰ 6 Ƌᅆา 0 "movb $" type ",%4 \n\t" \ // ȺʃȣିƧƋᅆࢿ͑ȳẴ৪Ոৰ 5 Ƌᅆ ৰ 67 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ n16 Ƌᅆ ẟ࣏ǻȐּàՈ LDT Ḱdž͘śFIRST_LDT_ENTRY 8 Ƌᅆ n16 Ƌᅆ ẟ࣏ǻȐּàՈ TSS Ḱdž͘śFIRST_TSS_ENTRY 8 Ƌᅆ #define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3)) ৰ 68 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;(((*p)->signal |= (1<<(SIGALRM -1 // ȕǍǻ᪻˖Ǹƌ„Ǖễ᪻˖Ǎǻ ẝ5☦ՈǍʻdzÑdž+ǍǻՈ̠ˊPত if ((*p)->alarm && (*p)->alarm < jiffies) { // ǎrՈrⒸ4 // jiffies «ிඣ>ඓ1ňrՈrⒸ rⒸ4rՈʃβɥ«ƟQՈிඣՈrⒸ>ඓ᱉ẋr if (*p) { for(p = &LAST_TASK ; p > &FIRST_TASK ; -- p) // ()ɣPẟ࣏Ոǎr„rⒸ«Ȫ4r 4rɥᩭẝẟ࣏β̣1ň /* check alarm, wake up any interruptible tasks that have got a signal */ struct task_struct ** p; in t i,next,c; { void schedule(void) */ * information in task[0] is never used. * tasks can run. It can not be killed, and it cannot sleep. The 'state' * NOTE!! Task 0 is the 'idle' task, which gets called when no other * * The one thing you might take a look at is the signal-handler code here. * in all circumstances (ie gives IO -bound processes good response etc). * probably won't be any reason to change this, as it should work well * 'schedule()' is the scheduler function. This is GOOD CODE! There /* ẟ࣏84̫ͥr94ẝ1ňK΢ńrẝ⓺ɉǡɆ4 ᪩ẟ࣏᪂า& ɥථźɍ4ńȳẴẟ࣏Ոrȅȴ4rẟ࣏ƅǎr„ ƟrⒸ4rɥ◄ ᡅȴ⁖ Ոẟ࣏« ȪȉΚ4r̵ƅᝯ⓿ɺՈǍǻ Ξ ȘǛ4rɥȺפńẝP⓺ɉỞẋ()ὧ‡ý ǍǻՈ̠ˊǍǻՈ̠ˊǍǻՈ̠ˊǍǻՈ̠ˊ dž4 &Y⓺ɉǍǻՈ̠ˊ3ẟ࣏Ոọō3ẟ࣏Ո ẟ࣏Ո᫇òdzÑ ᪸ºɥථⓣọōPmŅՈrⒸċż̶Ոẟ࣏Ą̴ᝯ᫇ò4 ẟ࣏Ո᫇ò5˄ƅǔ̶ Linux0.11 ±±ūϬP࢑ 5˄ ż⑃mŅrⒸ Ą̴4ɥ« sys_waitpid ਍4 interruptible_sleep_on r ⍣)Ɖ¥࣏Û do_timer Ñ ǎP‡ிඣ᫇Ϭ sys_pause sys_exit Ոϔ sleep_on3 פǣ ÑǒɴՈ4ūϬrẟ࣏᫇òՈϔ ĉ Ő r ūẟ࣏ý ± ܄ Ȗ r ό :ẟ࣏¤ƅՈ̱ň ῁«ÑƷ& ẟ࣏Ո᫇òdzÑ᪸«ẟ࣏ிඣż&ʴ ȏՈᾬ «ΞŁȋ:ẟ࣏Ո1ňՈr4 ἗̱ňிඣ ک4Pẟ࣏Ոƌń ỞẋẝPত ɥdzÑک἗rᩥਜ਼ƶ«ΞŁͫکºQόত ৰ͙তৰ͙তৰ͙তৰ͙ত ẟ࣏Ո᫇òẟ࣏Ո᫇òẟ࣏Ո᫇òẟ࣏Ո᫇ò ৰ 69 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ (for(p = &LAST_TASK ; p > &FIRST_TASK ; -- p // Ʒᝯ̨⁖ՈrȅĄ̴ūϬ CPU Ոɋɥʺ̓r4 ẟ࣏ՈmŅrⒸ ċʺ̶r ὧ4਍4פ// & counter=counter/2+prioriy 4ŭ+ẝ5ͩý 4͘ś Ոẟ࣏פ// Νǜ ẟ࣏ⓣ¤ƅՈẟ࣏ՈrⒸċ῁ĆǕϣΝǜĉŐrý ‑rⒸċ Â]«ǮϬɥථՈẟ࣏ՈrⒸċĆǕϣ // -Ϭẟ࣏ՈĄ̴൫ₑ,&ẟ࣏ if (c) break; // ΞȘȨ& 0 ɥ᪸Š¤ƅẟ࣏ՈrⒸċ῁>ඓϬ̵r4 ż̓ՈmŅrⒸċՈȨPǎ]& 0 // ΞȘɣẟ࣏ՈrⒸċ῁̵ƅūϬ̵ } c = (*p)->counter, next = i; if ((*p)->state == TASK_RUNNING && (*p)->counter > c) // ºẟ࣏ՈɥථⓣọōmŅՈrⒸċż̶Ոẟ࣏ continue; if (!* -- p) // ɉЩẟ࣏ᜬՈाĹ while (-- i) { p = &task[NR_TASKS]; i = NR_ TASKS; next = 0; // Ϭzƌ΢ŷȺŤϬ CPU Ոẟ࣏ńẟ࣏ᜬՈĹา c = -1; // ϬzƌʔmŅrⒸՈż̓Ȩ while (1) { /* this is the scheduler proper: */ ,᪂าrⒸċ4ϢȒ ₑ,ŵọ4 dž4Ξ ȘǕ ɴ¤ƅՈẟ࣏ՈrⒸ ċ῁>ඓūϬǀr ɥ-Ϭẟ࣏ՈĄ̴൫ ₑ ̣ẟᜐẟ࣏Ո ẋ̼ϟȈ̠zɥථźɍՈẟ࣏Ո mŅrⒸÑâ4Pż̓Ո ϢȒɥȺẝẟ࣏᫇Ϧǡβ Ȉ࢑᫇òਜ਼ͩ ᩶Ոɥ«ΞŁẟᜐẟ࣏Ոọō Linux0.11 ūϬՈਜ਼ͩǔǭˊᢧ ɥỞ ẟ࣏Ոọōẟ࣏Ոọōẟ࣏Ոọōẟ࣏Ոọō } (*p)->state=TASK_RUNNING; (*p)->state==TASK_INTERRUPTIBLE) if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) && // ǻ̲͛ՈǍǻ4 źɍՈẟ࣏«ȪǡrᝯʃᐁǍפ// «]̭᩼ᝯʃᐁՈ4ẝPǹ()P̠zdz)ý // ẝǃǎ5«Ϭzº⓿ɺ Ǎǻ ±┨ǭȭ SIGKILL ʐ SIGSTOP Ո⓿ɺ ẝ Ǎǻ // #define _BLOCKABLE (~(_S(SIGKIL L) | _S(SIGSTOP))) // _BLOCKABLE ǎ5ń } (*p)->alarm = 0; // Ⱥ alarm ᪂า& 0 ᜬ߾ǎr>ඓ̠ˊ඗Ǜr4 ৰ 70 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ȑ4 ǎᜬ߾ՈିƧz[ᜬ ͢ȯ5^ƌ ʔɉȳẴ৪ՈିƧ Ÿǀ͔]ۅɉ |H ¹«   Ĺ ͢ේ ɉȳẴ৪ ʒɳՈ { ĹńிඣɉȳẴ৪]ūϬ ɴϬ৪ǻ N ᜬ߾4ிඣɉȳẴ৪ՈିƧ Ƌ Ẵ৪Ո͛5ǀּ͔ȐʒɳՈ } Ĺ3¡i Ĺ3H Ĺʐ {Hi ƋɉՈňϬKǀּ͔ Ȑ4ƌ ʔ {|a ᜬ߾ƌʔɉ {|S ᜬ߾ிඣɉ4ிඣɉȳẴ৪ՈɉȖŌŜʐɉ А└Ƌ ɉ^ƌ ʔɉȳ Ո ʃȣ «ʒɳƋᅆՈȳẴ৪ିƧĹ {| ՈȨ4 ^ƌʔɉȳẴ৪ּ ɨ Ʒ ØǔּĨ ľ Ոʒɳ G X 0 AVL Limit(19...16) P DPL DT0 TYPE Ẵ৪ ிඣɉȳ BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 Byte m+6 Byte m+5 ȳẴ৪ Base(31...24) Attributes Segment Base(23...0) Segment Limite(15...0) M+7 M+6 M+5 M+4 M+3 M+2 M+1 M+0ிඣɉ ͢ʸśΞ[ ிඣɉȳẴ৪ிඣɉȳẴ৪ிඣɉȳẴ৪ிඣɉȳẴ৪ ɉȳẴ৪Ոʸś4 ⒬ȳẴ৪^ɉȳẴ৪Ոʸś«ǔʻ 4ç¥⒬ȳẴ৪ʒzிඣɉȳẴ৪ ẝ ₐ͹ ·එP[ிඣ ŌŜ4ẝ ɥΙʻ ɉȳẴ৪«Ϭǡǣ4ɉŌŜ4Ƿ«ü&ƷՈ £࿁ȐɉȳẴ ৪P ʳ ü Ǹç¥ ẝç¥⒬ȳẴ৪dzÑ â4P |QQ ՈŌŜ 7Ȓ-ϬẝŌŜº |QQ ǣ4Ƅ࣏ÛՈ͑ǧ ǒɴɉⒸḰࢿ4ńljĈµś[dzÑūϬP ūȕǯɆ ç¥⒬ȳẴ৪Ո ū⍌ǡǒɴᲷḰ4Ởẋ ńǒµś[Ⓒ ȉḰࢿ«ȺƄ࣏ÛՈ͑ǧŌŜ΢4 ɌPͱƌʃǻ ϢȒ᫇Ϭ ᪩ͱƌʃǻ ⒸָȉḰࢿ ʐɉⒸⒸȉḰࢿି4ΞȘūÐ ¡ZH ʐ Iii ńūÐָȉȯ ƅֲ ʃŌŜ ū⍌ ὧ4ɥ«ɉ &ɉⒸ ָȉ Ḱࢿ ͔ū⍌4^ǒµś[ּĨ ɉⒸḰࢿūÐ ¡ZH ʐɉⒸ᫇ϬūÐ Iii ẜdz ɉ ZẴū⍌ͱՈȻࢿūϬ æb Ĺᜬ ߾ ẝ ʳՈū⍌Kࢴ&  ‰ ĹۅŌŜū⍌4ń æb ĹÏ ńljĈµś[ ɉⒸḰࢿՈֲʃĹาϵọō ƄʐȻࢿȀtՈŌŜᜬ߾ „ îƷࢴ&ֲ ʃ ljĈµś[ՈɉⒸḰࢿljĈµś[ՈɉⒸḰࢿljĈµś[ՈɉⒸḰࢿljĈµś[ՈɉⒸḰࢿ ᪊ȫ4ک᪊ ɥ̴ȺP[8̣ک^ϢϬ4rܰâՈ ẝP£࿁ Ո IJ«ʌČ ƨՈ Linux «ūϬḳâՈ 5ͩ ḳâ5ͩūǣ࣏ÛՈdz ÍʉɳʺƆ 4 dž«ẟ࣏᫇òǣÑǒɴՈ͟ ⏲äƫ Linux0.11 «-Ϭ Intel ȴƇՈܰâ5ͩǒɴ ẟ࣏ dž džẟ࣏Ո džẟ࣏Ո džẟ࣏Ո ẟ࣏Ո } (*p)->priority; (*p)->counter = ((*p)->counter >> 1) + if (*p) ৰ 71 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ˊdž ńƟQç¥ūϬœ̠ ৰ͙ৰ͙ৰ͙ৰ͙ î IXS Ո |Q ʃȣ า& a ẝᜬ߾>Ǖϣẋç¥ ᡅǒ9⏂ȉwᢧ⏂̠ˊ4 dž dž]ǒ 9⏂ȉwᢧ⏂̠ˊ ϵ Iii ūÐ 3)3JX| ūК᰻Ոç¥ ᰻Ոç¥ |QQ ȳẴ৪ିƧา&8dzϬ 9 Ɵ Qç¥ |QQ ȳẴ৪ିƧา&8ȥ94ϵz ¡ZH ūÐ š ᢧ⏂ ὧ4îƣç¥ |QQ ȳẴ৪ିƧ Ν&8dzϬ 94ΞȘ\ᢧ ⏂̠ˊ ὧ4Ⱥ ƣç¥ ৪Ո8ȥ9Ł ÂȺʃȣǸ ƌ„ Wi}Q Ո Ž| Ĺา a ᜬ ߾«΀ͳç¥4Ξ Ș◄ᡅ |QQ Ո⏂ȉƋɉ îƟQç¥ |QQ ȳẴ৪ିƧ Ν&8ȥ9€Â]ǚΝ ƣç¥źɍɉȳẴ ৰ€ৰ€ৰ€ৰ€ ẟᜐ⏂ȉ̠ˊ 4Ξ Ș◄ᡅ⏂ȉ ὧ4Ⱥūȕƣç¥ |QQ ՈọōƄ΅͑Ɵ Qç¥ Ǹƌ„4 ࿁ǕϣՈŎ„ ǮîȭàọōƄញ͑ȈɉǸƌ„4Ǹrọō ƄՈ H Ĺ& S4ẜញṁ IXæ ỞϬǸƌ„3ɉǸƌ„ 3Wi}Q ǎ JH 4ńញ͑Ǹƌ„Ոẋ࣏ &r ࿁ǷܲŌ̠ˊdz ৰ÷ৰ÷ৰ÷ৰ÷ Ȗƨʮ̩ƟQ祀ֲʃç¥ ՈǸƌ„ɴ Ŗ4ʵǒljƌ ń |QQ Ոͱ ǭ ʮ̩Ȉ |X Ոʌợ෗ΞǸƌ„4ǸȒ ƟQç¥Νࢴ&ƣç¥ ֲʃç¥Νࢴ&ƟQç¥4 ৰYৰYৰYৰY îū߾ֲʃç¥ |QQ ՈọōƄញ͑ |X Ǹƌ„4Ȑrîȭà |QQ ՈȳẴ৪ញ͑ ǝūÐ4IJ]î i{|X ʐ IXæ Ոͱǭljƌ4 |QQ 4 džūÐՈ[P ՈƟQȨljƌ4Ɵ Q |QQ 4ljƌՈ JH Ȩ«ẘúŌŜ ūȕš ᰻ç¥ ৰxৰxৰxৰx îǸƌ„ɴ Ŗljƌ4ƟQç¥Ո |QQ4îỞ ϬǸƌ„ 3ɉǸƌ„ 3JH ǎ Wi}Q ਍z aSæ€aS [a4 |QQ dzÑƅϔₓ]਍Ո͢ÂǍʻ ʵǒç¥źɍɉՈȖƨʸś |QQ ՈА└à̓zz ৰPৰPৰPৰP ϟ᪙ֲʃç¥źɍɉՈА└4|QQ Ϭzljƌç¥ՈȈ࢑źɍǍʻ ]ȐՈç¥ džՈPჰẋ࣏Ξ[ ʵǒū߾ֲʃç¥ |QQ ȳẴ৪ՈọōƄẟᜐç¥ Ո |QQ ȳẴ৪4 džՈrȅūϬrP ǯ |X ՈǸƌ„ Ʒ«ϬzƌʔƟQǷń ẔᜐՈẟ࣏ Ʒ4ńẟᜐç¥ Ո {Hi ᢈǎr ᪃⒲᪩ȳẴ৪Ոż̲ɶĽƿ൫ Ǯƅ«ּȐ൫/zŰʌ൫/Ո࣏Û ±dzÑ ᪃⒲ ȋ: ȭ |QQ ɉȳẴ৪Ո᪃⒲4 |QQ ɉȳẴ৪̠ˊ„₋Ϭ^ ᪃⒲ϔǒɉּ ȐՈĽƿ൫ᢈ ¥ |QQ ͱՈ IQ ʐ JH Ƌɉ¤ᢈǎՈū⍌ܲǎ4ẝʳՈ ¡ZH z Iii ūÐͱՈȻࢿᝯŏ4 dž4ֲ ʃç¥Ո͑ ǧͥϵֲʃç ɥǕϣºƟQç¥4ϵ᪩dzϬ |QQ ȭàç¥ €ֲʃç¥ Ո ɉⒸḰࢿ ūÐ ¡ZH zɉⒸ᫇ϬūÐ Iii¤ȯՈū⍌«ūȕPdzϬՈç¥ ⒬ȳẴ৪r -Ϭç¥⒬ǒɴɉⒸᲷḰ-Ϭç¥⒬ǒɴɉⒸᲷḰ-Ϭç¥⒬ǒɴɉⒸᲷḰ-Ϭç¥⒬ǒɴɉⒸᲷḰ ȳẴ৪Ⱥ͹)ிඣ·එ4 ºZᜬdz ᢅ Ɵି ƧǻՈȨ& 9 ʐ B ՈrȅẝȳẴ৪ɥᜬ߾ç¥⒬ȳẴ৪4)⒬ W 扊 ┻⓵⒬ ிඣɉିƧ  扊 )⒬ { Ʀǎ5 I 扊 ᫇Ϭ⒬ \ ȥՈ 扊|QQ  Ʀǎ5 l dzϬ 扊|QQ ‰ Ʀǎ5 Š ᪸ ۅିƧේ d b‰Š ┻⓵⒬ ிඣɉିƧ Š b‰Š )⒬ ` ç¥⒬   b‰Š ᫇Ϭ⒬ æ ȥՈ b‰Š|QQ b i{| a dzϬ b‰Š|QQ S Ʀǎ5 Š ᪸ ۅିƧේ ৰ 72 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ // Ոç¥źɍɉՈŌŜẟᜐɨṇ໐ňϦՈ4 „// ỞẋȺ,ç¥źɍɉՈŌŜ^ljƌń last_task_used_math ǜₓՈūϬẋœ̠ˊ 4 ń(),ç¥ ZƵËᜐ«ȪūϬẋœ̠ˊ„r « džr a Ȩ̵ƅϬ ɉЩ // ¥ // ͢ rϔǒ඗Ȁ__tmp  a ՈȨ« 32 ĹȻࢿȨ b &, TSS Ոọō৪4ńç // dx - ,ç¥ n Ոọō৪ecx - ,ç¥ū⍌ task[n]4task[] «PϬzƌ΢ẟ࣏Ոϔඈ4 // (*&__tmp.b) // ṗ͑%0 - , TSS ՈȻࢿŌŜ(*&__tmp.a)  %1 - ƌ΢, TSS Ոọō৪Ȩ */ ẜ◄̩Ĺȋ:Ǹƌ„ cr0 Ո TS ʃȣ4 * œ̠ˊ„Ո᪡ ūϬẋϔƚ dž4Ոç¥żẕZƵẔᜐ ¬4K]ɆỄϦ4ΞȘuØ* ΞȘ« džƟQç¥4ç¥ n4Ŋ̴̼ϟç¥ n «]«ƟQç¥ /* switch_to(n)Ⱥ ǃǎ5Ĺz include/linux/sched.h4 ₓ Ľ/ ՈɅ4ẝۅdžՈÏ ẝ«Pǃǎ5 Ƿ«ϵz Intel ՈܰâΓť ū ǣç¥ } switch_to(next); Ǎʻ4 ȭàՈ TSS  Ȑr᪂า TR Ǹƌ„ūȕֲʃẟ࣏ȭàՈ TSS ඗Ȁ ʮֲ̩ʃẟ࣏Ոɳʟ džՈɩ̿ɥ«᪂า current ūȕֲʃẟ࣏ ljƌƟQẟ࣏Ո ɳʟ Ǎʻ4Ɵ Qẟ࣏ ẟ࣏ ۅdžՈÏ ۅdžՈÏ ۅdžՈÏ ۅdžՈÏ ẟ࣏ẟ࣏ẟ࣏ẟ࣏ ᜐ[☦Ոç¥ȫ49☺ ᣄ8ȳ᪂̓Ǫ îÑZՈͱǭ῁׏r Âȳ᪂̓Ǫîͱǭ῁׏ŠՁr4Ιr ᩭuØẟ ȫ4ẝr ̭᪻᩼ušϬPƵPĹċ̓Ոਜ਼ͩ ̓T ՈPǩȑۅΞȘẜ]ˊᢧ ɥ̴׏׏Ï -Ϭֲʃ |QQ â4ֲʃŌŜ ńḰࢿՈȐrȺႮᵯՈɳʟǍʻ΢4ႮᵯՈ |QQ 4 ׏4ẝ«]«ͫ4ƅ‡]ɦ ͢ǒ-Ϭ |QQ ǡǒɴՈɉⒸᲷḰՈ ɩ̿«ǔ੄řՈ4ɥ« ś4 ৰŅৰŅৰŅৰŅ î᫇᪙Ǹƌ„ {Xd Ոɴᾬ ȳϬĹา& S Ñ ±┨ɴᾬzƣç¥ՈȈ) ͥʐ5 ẝ^ç¥ͱՈỞẋ᫇Ϭ⒬ՈḰࢿ]Ȑ4 ʐ QH ƋɉՈȨ ໐]«ūϬͱɶʄljƌ ľՈū⍌ ŷūǕϣrȕͱɶĽƿ൫Ոǜdž4 ɉՈ {Hi4Ȣʄ ɉūϬՈ« |QQ Ո QQۅXHiS ញ͑7Ȓ ᫇ Ϙ IQ Ո XHi ਍zֲʃÏ ɉʌợ෗ƌ7Q KᡅẟᜐĽƿ̼ɡ ̠ˊ„᫇Ϙ |QQ Ո IQ ọōƄՈۅńញ͑Ï ɉǸƌ„ IQ 3Ȣʄ ɉǸƌ„ QQ ʐȈϔǒɉǸƌ„ǎ͢ʌ ợ෗ΞǸƌ„4ۅৰIৰIৰIৰI ញṁ Ï Ⱥ i{| ՈƌńĹา& S ᜬŠç¥]ūϬ i{|4 ōƄ&ा ȳẴ৪ ńඓẋϟ᪙Ȓ î¤ᪿՈ i{| ȳẴ৪ ញ͑ i{|X ʌợ෗ΞǸƌ„4Ξ Ș i{| ọ º }{| ᪿϦȭàՈ i{| r |QQ  i{| ọōƄ& S4ΞȘ |QQ  i{| ọōƄ☢ ा ৰ͗ৰ͗ৰ͗ৰ͗ ញṁ i{|X Ǹƌ„4Pç¥dzÑƅ Ⴎ= Ո i{| KdzÑ ̵ƅ4Ɵç¥ ̵ƅ i{| dž4ǪPç¥Ո磼ƿ൫4 ÂdzÑ dždzÑńPç¥ՈçŁ Ľƿ ൫Ǖϣ ȳẴ৪Ո {Hi ȑ/ ਍z᪩ọōƄՈ XHi4ç¥ ɉۅɉȳẴ৪Ո {Hi ¤Ñ |QQ ՈọōƄ¤ū߾ՈÏۅợ෗ΞǸƌ„rᡅ ̼ϟ IHi Ï ৰSৰSৰSৰS î |QQ Ո IQ ọō ƄՈ XHi ň&ƟQç¥ Ľƿ ൫᪂า& IHi4njü&ញ͑ IQ ʌ dž4 ȷợŌẟᜐç¥ „ūÐr “ϣႮ┻4ϵႮ ┻̠ˊ࣏Ûǀtƅ͟ œ̠ˊ„ɴ ŖՈljƌʐʮ̩4ẝƅ-z ৰ 73 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { \ ;((["d" (_TSS(n)),"c" ((long) task[n ::"m" (*&__tmp.a),"m" (*&__tmp.b), \ "1:" \ "clts \n" \ "jne 1f\n\t" \ "cmpl %% ecx,_last_task_used_math \n\t" \ "ljmp %0 \n\t" \ // ƅ¤Ɍѕ ‑Ո᪡ɥĆϦ⒲L ¤Ñuȭ Linux0.11 ՈdzࢿΉɳ // Ո4uᩨ&ΞȘේ᪕„]ẝ4 // ¤Ñ__tmp.a ẝ÷Ƌᅆ«ᝯɉЩՈ ūϬՈ«__tmp.b4ü&ẝǜₓ«Ảනƌ΢ dž ü&«ūϬ TSS ȳẴ৪¤ÑĆɉЩȻࢿŌŜ //-ϬɉⒸᲷḰǒɴç¥Ո "xchgl %%ecx,_current \n\t" \ // ȺƟQՈẟ࣏^,ẟ࣏dž ẝǹǒɴr PCB ඗ȀՈdž "movw %%dx,%1 \n\t" \ // Ⱥ,ç¥Ո TSS ȳẴ৪΢͑__tmp.b  ńɉⒸᲷḰՈrȅĆϬ4 "je 1f\n\t" \ "cmpl %%ecx,_current \n\t" \ // ΢Ո«ƟQՈẟ࣏4 džՈẟ࣏«Ȫɥ«ƟQՈẟ࣏ΞȘ«ɥỄϦ4_current «P͔ɴǜₓƌ //()β̣ __asm__( struct {long a,b;} __tmp; \ #define switch_to(n) {\ ৰ 74 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ẟ࣏¤ưƅՈ ü&ɴᾬǜₓ«-Ϭẟ࣏ՈிඣʄǡƌʔՈ4uØîϘẟ࣏Ɵň«Pê̓Ո ẝₐ◄ᡅͼ͛  ʐ «͔ɴǜₓƅ¤Ñẟ࣏͝— IJ«ɴᾬǜₓ& Ÿ«ϵ]ȐՈ Ě S.1sleep_on ū⍌ǜĚĚǸĚϦႮz9 ǀ͔ͼ₎: « rū⍌current «ƟQç¥ū⍌4ū⍌ǜĚՈ߾͛ĚΞ[ ϔ͝ Ĺ54rYç¥ ū⍌*p 3tmp ʐcurrent ͢*p «਍Ǒⓣ͐ ū⍌ tmp &rƫzˊᢧ uĆϬPŷƄŭ+ẝਜ਼ͩᰴPἑ4 Ոǒɴ«☢„☢„Ո3εՈ4ৰPƵˊᢧrƷՈǒɴՈrȅ uȭ࣏Ûƅr,Ոᩨ᪊4 ƅ׏4ϔǒ඗ȀՈ ⏂ᜬ඗Ȁ Ʒ̵ۅ4 ਍Ո᪡KĆẢ4⏂ᜬՈ͐ᾬ4º Linux0.11 ՈÏ Ո4z«ẟ࣏ 1 ʐẟ࣏ 2 ƮtrP ⏂ᜬ4͹ǡrẟ࣏ 33פᰈļՈr ȅ ẟ࣏ 2 K«ᡅý Ոr ȅ Ξ ȘnjƅPẟ࣏ 2 ᡅ˖Ϸ᪻ẝפr4 ńẟ࣏ 1 ýפǑPɉrⒸ z«ẟ࣏ 1 ý ΞȘƟPẟ࣏ 1 ńϷ᪻ɌP࢑ᰈļՈrȅǕɴẝ ᰈļᝯ⏅ǎr ẝr ȅɥ◄ᡅ਍ ϔϔϔϔ sleep_on ☦dzÑ᪸Š Linux0.11 ±±̠zƣˊ᪸ŠẝPɶƵ4 ʐ̨⁖̱ň Linux0.11 ɆՈ]« ǔΙ βܲՈ᪸ₐ☦ƅ Bug4ºẝP5פȭzẟ࣏Ոý wake_up4 ƿȫ ü Ǹẜ◄ᡅƅP̨⁖Ո̱ň4ȭàՈϔ«]إǪ̲Pẟ࣏ʇ] ႷzˌẠՈ « sleep_on4 ȭàՈźɍ« TASK_UNINTERRUPTIBLE 4᫇ϬՈϔ פᝯ)Ո ü Ǹǯ ]dz)ý ̭᩼[»פŷΞᪿǚâՈrȅ4ńẝ࢑̑ΡՈý ڱIJ«ƅՈrȅẝ ਍ǑՈrⒸǔ ᫇ϬՈϔ« intrruptible_sleep_on4 ՈrȅdzÑᝯ)4פȭàՈźɍ« TASK_INTERRUPTIBLE ᜬ߾ńý פǯɆdz)ý פⒸͱdz࿁Ćƅ͢ƷՈwâǕϣǡắūẝẟ࣏1ň ŷΞŭrǶ⏲4ü ǸȭzẝିՈý ƅՈrȅPẟ࣏ ◄ᡅ਍ǑՈrⒸdz࿁ǔ⑃ ŷΞ਍Ǒ⏲֜Ոṗ͑4 ńẝ4⑃Ո਍Ǒr >ඓ᩶rǔ̶r uɥ]ʱ⒬Ő#r4᪸P[ẝϔՈľ/ ńƣˊ᫂Z פ̱ňƅ͟Ոϔ sleep_on ʐ interruptible_sleep ῁ƅ sleep ẝ᪑4& ¬4ᡅý ẝ ᪑«ü&^ẝפūՈɥ«̱ňிඣ᩶4Ոẟ࣏Ո⓿ɺ 7¤ÑϬýפẟ࣏Ոý ʐ̨⁖פʐ̨⁖ẟ࣏Ոýפʐ̨⁖ẟ࣏Ոýפʐ̨⁖ẟ࣏ՈýפৰSতৰSতৰSতৰSত ẟ࣏Ոý ৰ 75 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ current ẟ࣏͐*pפý tmp Sleep_on tmp Sleep_on tmp Sleep_on // *p ūȕ͐ẟ࣏ ȅ ẝẟ࣏ɥdz࿁Ťƅ CPU r4 ẝϔ±±«ᩭ਍ǑⓣՈ͐ẟ࣏Ոźɍǜt ɥථźɍ ẝ ʳń[P Ƶẟ࣏᫇òՈr ϔϔϔϔ wake_up ̱ňՈϔ wake_up4 &r࿁̻ ǀϘՈ׏Pἑẟ࣏ΞŁP ȈՈº ਍Ǒⓣʮ̩ u ◄ᡅ͹᩶P[Ëᜐ̨⁖ } tmp ->state=0; if (tmp) // Ɵ͹ƵËᜐ᫇ò࣏ÛՈrȅ ὧẟ࣏ɥdz࿁ŌϧËᜐr4 // «Ȫẜƅ͢ƷՈẟ࣏ ΞȘẜƅՈ᪡ɥᩭ[Pẟ࣏Ոźɍ«ɥථźɍ4ẝʳ źɍʮ̩Ոrȅ ɥĆএ?ºẝₐŌϧËᜐr4Ŋ̴()਍Ǒⓣפ// Ɵẟ࣏ºý schedule(); // Ëᜐẟ࣏᫇òūǣ͢ÂdzϬՈẟ࣏Ťƅ CPU current ->state = TASK_UNINTERRUPTIBLE; źɍפźɍ ͼ͛ẝₐūϬՈ«]dz)ýפ// ᩭƟQẟ࣏ẟ͑ý *p = current; // ᩭ਍Ǒⓣ͐ūȕƟQẟ࣏ tmp = *p; // ᩭǜₓ tmp ūȕQPⓣՈ͐ẟ࣏ β̣᩶ƟQẟ࣏ȶń਍ǑⓣՈ͐ᾬ panic("task[0] trying to sleep"); if (current == &(init_task.task)) // ü&!ϧẟ࣏«]ĆƿËᜐẝϔՈüǸΞȘǕɴ«!ϧẟ࣏ɥĆȏƶ return; if (!p) // ܲljẟ࣏͐ū⍌«ƅάՈ struct task_struct *tmp; { void sleep_on(struct task_struct **p) NULL 4 Ոrȅⓣẜ̵ƅẟ࣏ ü Ǹẟ࣏ 1 ȭàՈɴᾬǜₓ tmp Ȩ&פü&Ɵẟ࣏ 1 ý źɍ)פźɍ) (ýפźɍ) (ýפ(ý Null ẟ࣏ 3 ẟ࣏ 2 ẟ࣏ 1 źɍ dzÑƮtẝʳՈP⏂ᜬפȳ᪂ƅWẟ࣏ X WƉƵẟ͑ý ᅆͥ î& Ɵň«ẝᅆͥՈūȕ[Pẟ࣏ū⍌IǯɆ ɨṇʼƟO4ŭ+ẝʳՈˊᢧ ৰ 76 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ 8 ẟ࣏ 1 ËᜐrǕɴ਍Ǒⓣ>ඓ̵ƅẟ࣏r NULL 7 ẟ࣏ 2 ŌϧËᜐ ᪂าẟ࣏ 1 &ɥථɍ NULL 1 0 NULL ńPƵẟ࣏᫇ò7Ȓ NULL 2 0 ẟ࣏ 1 ẟ͑ɥථɍ 6 ẟ࣏ 3 ŌϧËᜐ Ǖɴ tmp ]ा4z«ūǣẟ࣏ 2 5 ᫇Ϭrr wake_up 7Ȓ ẟ࣏ 3 ẟ͑ɥථɍ NULL 3 0 ẟ࣏ 2 4 żȒẟ࣏ 3 ᫇Ϭr is ẟ࣏ 3 3 1 ẟ࣏ 2 3 ƟẝrȅnjƅPẟ࣏ 2 ᫇Ϭr is Ȓ ẟ࣏ 2 2 1 ẟ࣏ 1 2 ƟƅPẟ࣏ 1 ᫇Ϭr is Ȓ ẟ࣏ 1 1 1 NULL 1 ŌϧՈrȅ਍Ǒⓣ͐&ा NULL ՈՈՈՈ tmp ȭ àȭ àȭ àȭ à ẟ ࣏ẟ ࣏ẟ ࣏ẟ ࣏  ẝ ẝ ẝ ẝ źɍźɍźɍźɍ ẟ࣏ẟ࣏ẟ࣏ẟ࣏ ẟ࣏ẟ࣏ẟ࣏ẟ࣏ *p ẟ ࣏ẟ ࣏ẟ ࣏ẟ ࣏ ȕ Ոȕ Ոȕ Ոȕ Ո ͐ ū͐ ū͐ ū͐ ū  ⓣ ⓣ ⓣ ⓣ ÛǻÛǻÛǻÛǻ ਍ Ǒ਍ Ǒ਍ Ǒ਍ Ǒ Is ᜬ߾ interruptible_sleep _on 0 Ïᜬ TASK_RUNNING 1 Ïᜬ TASK_INTERRUPTIBLE ⓣՈẟ࣏῁>ඓẔᜐr4 8 njPƵẟ࣏᫇ò7Ȓ ẟ࣏ 1 Ẕᜐ4 ϵzńẟ࣏ 1 ȭàՈ tmp Ȩ& NULL ᜬŠ ਍Ǒ ϧËᜐ z«᪂าrẟ࣏ 1 &ɥථɍ4 7 Ɵ ͹ƵǕ ϣẟ࣏᫇òՈrȅ ẟ࣏ 2 Ō z«Ⱥẟ࣏ 2 Ոźɍ᪂า& TASK_RUNNING 4 6 Ɵẟ࣏᫇òŌϧՈrȅẟ࣏ 3 ŌϧËᜐ ẟ࣏ 3 Ǖɴ tmp ՈȨ]ा Âū ȕrẟ࣏ 2 4 ǣẟ࣏ 3 &ɥථɍȐrȰႸⓣ͐ᾬ͍5 ū ƟᰈļdzÑūϬՈrȅ ᫇Ϭr wake_up ϔǡʮ̩਍ǑⓣՈ͐ẟ࣏ẟ࣏ 3 4 4פżȒẟ࣏ 3 KϵzȐʳՈƣüẟ͑rý 4 3פ◄ᡅý 4 ϵzẟ࣏ 2 Kᡅ˖ūϬ ᰈļ Ȱ Ⴘẟ࣏ 2 K z«᫇Ϭrϔ sleep_on 2 פ࣏ 1 ◄ᡅý 4 ńϷ᪻Ɍ࢑ᰈļ Ոr ȅϵ zɌ࢑ƣüẟ ȳ᪂ẟ࣏ 1 ËᜐՈrȅ ਍Ǒⓣ«ाՈ 1 ϢȒnjʮ̩Ո4 פẝₐɥÑĚՈ 3 ẟ࣏&ŷǡ᪸ŠẝYẟ࣏«ΞŁẟ͑ý 4̨⁖פ4̨⁖ẟ࣏ºýפ4̨⁖ẟ࣏ºýפ4̨⁖ẟ࣏ºýפẟ࣏ºý } } *p=NULL; // „Ո̑Ρ῁ĆËᜐǀՈ4 // ẝₐȺ*p ᪂& NULL Ȓ ɥ͍ƿrȭ਍ǑⓣՈẟ࣏ՈᲣᳮ4IJ«ẝ‡ẟ࣏ńỞ (**p).state=0; if (p && *p) { { void wake_up(struct task_struct **p) ৰ 77 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { { ;(**p).state=0 if (p && *p) { { void wake_up(struct task_struct **p) ±ȴ4rᡅ᪂าP^ƷּȭàՈ̨⁖ϔ interruptible_wake_up ƷՈǒɴΞ[ } tmp ->state=0; if (tmp) *p=NULL; // interruptible_wake_up zƷּȭà4 tmp 4Ȑr◄ᡅ᪂ǎP,Ո̨⁖ϔ // ͍ƣ̴Ոẟ࣏ⓣ üǸ◄ᡅȺ͢Ν&*p // ⒲LɥϦńẝₐ ΞȘ᪂าⓣ͐& NULL Ո᪡ ń̠ˊǀ,4Ոẟ࣏7ȒɥĆ } goto repeat; (**p).state=0; if (*p && *p != current) { פ// ͹Ƶý r4ẝɥ◄ᡅᩭὧ‡Ǎ4Ոẟ࣏1ň ȐrūႮ=פ// ńᝯ̨⁖7Ȓnjƅ,Ոẟ࣏ý // Ɵẟ࣏ᝯ̨⁖Ոrȅ ̴̼ɡP[«Ȫ&ा Ñǎ«Ȫ&ƟQẟ࣏4ΞȘ]«ɥ᪸ schedule(); repeat: current ->state = TASK_INTERRUPTIBLE; Ո᪂ᩥɥ«&r̠ˊȒ4Ոẟ࣏ ÂᩭȒǡՈẟ̴࣏1ň // Ñ[ᾬ z sleep_on ՈϬּͩȐ4ۅ// Z☦ՈÏ *p=current; tmp=*p; panic("task[0 ] trying to sleep"); if (current == &(init_task.task)) return; if (!p) struct task_struct *tmp; { void interruptible_sleep_on(struct task_struct **p) ՈrȅĆ̴ᩭẝ‡ẟ࣏Ŋ̴Ëᜐ4IJ«ẝϔƅ bug uĆȴϦuՈΝẟ5˄4 Ո᪡ interruptible_sleep_on ϔ࿁̻ Ⱥẝ‡ẟ࣏K¤4⏂ᜬՈ͐ᾬ4Âńẟ࣏᫇òפý ɥּȭǭǣ̶r4̠ˊZՈ:/ńz ńẟ̨࣏⁖ 7Ȓ ẟ࣏᫇ò7Q ΞȘnjƅẟ࣏ẟ͑ ʐ̨⁖Ո᪡ ˊ ᢧ interruptible_sleep_onפΞȘˊᢧrūϬ sleep_on ʐ wake_up ᩭẟ࣏ý ϔϔϔϔ interruptible_sleep_on 4ƣ rȒẟ̴Ɖ¥FILOºẝϕ࣏dzÑ׏Ϧǡ ẟ࣏ǣ̨⁖ƣ ৰ 78 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ☺Ոẟ࣏῁Ëᜐrפẟ࣏ 1 Ëᜐ඗ǛȒ ¤ƅý 18 Ɵ͹ƵǕϣ᫇òՈrȅ ẟ࣏ 1 Ëᜐ 17 ϵzẟ࣏ 2 Ո tmp « 1 Ëᜐ tmp ->state=0 ẟ࣏ 1 1 0 NULL ɥ̵ƅǶɳ ẟ࣏ 2 2 0 ẟ࣏ 1 16 ϵzⓣ͐K« 2ūȕrႮᵯ 15 Ɵ͹ƵǕϣ᫇òՈrȅ ẟ࣏ 2 Ëᜐ ɥ̵ƅǶɳ ẟ࣏ 2 3 0 ẟ࣏ 2 14 ϵzⓣ͐K« 3ūȕrႮᵯ 13 Ɵ͹ƵǕϣ᫇òՈrȅ ẟ࣏ 3 Ëᜐ 12 ϵzẟ࣏ 4 Ո tmp « 3 Ëᜐ tmp ->state=0 ẟ࣏ 3 3 0 ẟ࣏ 2 ɥ̵ƅǶɳ ẟ࣏ 3 4 0 ẟ࣏ 3 11 ϵzⓣ͐K« 4ūȕrႮᵯ 10 ඓẋ᫇ò ẟ࣏ 4 ŌϧËᜐ4 9 ẟ࣏ 4 2 1 ẟ࣏ 1 8 ẟ࣏ 2 Ǖɴ਍Ǒⓣ͐ū⍌« 4 ẟ࣏ 4 4 0 ẟ࣏ 3 7 ẟ࣏᫇òŌϧr ẟ࣏ 2 ᝯ̭᩼Ëᜐ 6 ௫ȉ؄ẟ࣏ 4 nj᫇Ϭr is ẟ࣏ 4 4 1 ẟ࣏ 3 5 ńẟ࣏ 2 Ëᜐ7Q ẟ࣏ 3 ᫇Ϭr is ẟ࣏ 3 3 1 ẟ࣏ 2 4 ᫇Ϭrr wake_up_interruptible 7Ȓ ẟ࣏ 2 2 0 ẟ࣏ 1 3 ƟẝrȅnjƅPẟ࣏ 2 ᫇Ϭr is Ȓ ẟ࣏ 2 2 1 ẟ࣏ 1 2 ƟƅPẟ࣏ 1 ᫇Ϭr is Ȓ ẟ࣏ 1 1 1 NULL 1 ŌϧՈrȅ਍Ǒⓣ͐&ा NULL ՈՈՈՈ tmp ࣏ȭà࣏ȭà࣏ȭà࣏ȭà ẝẟẝẟẝẟẝẟ źɍźɍźɍźɍ ẟ࣏ẟ࣏ẟ࣏ẟ࣏ ẟ ࣏ẟ ࣏ẟ ࣏ẟ ࣏ ࣏࣏࣏࣏*p ȕՈẟȕՈẟȕՈẟȕՈẟ ͐ū͐ū͐ū͐ū ÛǻÛǻÛǻÛǻ ਍Ǒⓣ਍Ǒⓣ਍Ǒⓣ਍Ǒⓣ 4 7ȒՈËᜐ.Û^ sleep_on ǔּĨr4 ūȕrẟ࣏ 2 üǸ͐ū⍌njūȕrẟ࣏ 214 ^ẟ࣏ 4 Pʳ ẟ࣏ 3 Ǖɴr͐ū⍌ūȕႮᵯ4z«᪂า͐ū⍌& tmp ϵzẟ࣏ 3 Ո tmp 4 4ƟnjPƵǕϣrẟ࣏᫇ò7Ȓ ẟ࣏ 3 Ōϧ Ẕᜐ 13 4 Ⱥẟ࣏ 3 Ոźɍ᪂า& 012 4ẟ࣏ 4 ¤ȭàՈǜₓ tmp ūȕrẟ࣏ 3 üǸẟ࣏ p=tmp z«͐ū⍌ūȕrẟ࣏ 311* ۅẟ࣏ 4 ËᜐՈrȅǕɴẝrȅ͐ū⍌ūȕrႮᵯ z«ɥ̵ƅǶɳ4ŭ+ǚΝȒՈÏ 4 4Ɵ ńǸǕϣẟ࣏᫇òՈrȅ ẟ࣏ 4 ŌϧËᜐ 10 TASK_UNINTERRUPTIBLE 8 9 ໐«ūȕẟ࣏ 4 z«Ⱥẟ࣏ 4 Ոźɍ᪂า& TASK_RUNNING ϢȒǶɳ ȺႮᵯ᪂า& 4ẟ࣏ 2 Ǖɴ͐ū⍌]«NULL 4Ɵẟ࣏᫇òŌϧՈrȅẟ࣏ 2 ŌϧËᜐ 7 6 פ࣏ 4 ý 4 ȉ؄njƅẟ r 5פ4 ńËᜐẟ࣏᫇ò7Q njƅrẟ࣏ 3 ý ϔ7Ȓ,̨⁖rẟ࣏ 24 4Ɵ ᰈļ dzÑūϬ᫇Ϭr interruptible_wake_up 3 פKᡅ˖ūϬᰈļ Ȱ Ⴘẟ࣏ 2 K◄ᡅý ẟ࣏ 2 Ոr ȅ2פإ 4Ɵẟ࣏ 1 ẜ«ȳ᪂ẟ࣏ 1 ËᜐՈrȅ ਍Ǒⓣ«ाՈ 1 ±±«Ⱥ*p=NULL Pǩƿǭr4ɴńᩭuØ׏׏,Ոʑ‑ƶ:«ΞŁ1ňՈ4 ৰ 79 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ àՈ̱ň]Ȑ4 Ʒ«ˮP࢑ିƧՈ Ʒ ØᝯPᢊȐ­ ±±«ȭ Linux ிඣȭŎ„Ո̱ň«] Ćƿľ ŷƄ4 ඣᜬʸ Âdz࿁ₑ,ȳ¬̱ňிඣ4ܰâΩ╠ʐிඣᜬϦɴ☢ͩȨ z]PႸՈȨ«ǶՈ “ϣǶr ǷËᜐՈ࣏Û]࿁ᝯʮ̩Ëᜐ4ிඣȉΚǶȒ ̠ˊ࣏Ûᡅₑ ,ņএȈ࢑ி ிඣՈP࢑Ŏ„4š᰻ǶՈūЫ\ͩܲǎՈ4کǶǶǶǶ «ńிඣϦɴₑ̑Ρ r Ở ƅdz࿁ΝǜrǸƌ„zƌʔř̯4ḳ)ūÐ3řǹŎ„«┻⓵ՈŷƄ4 ͥ ǑȌܲǎϦ“ϣŎ„Ո ūÐ4ńḰ͑┻⓵̠ˊ࣏Ûr š ᰻┻⓵ ՈūÐàǷ„ǀt Ʒ PǝᡅËᜐՈ ūÐ ]Pǎ ɥ«[PǝūÐ 4ü Ǹ ┻⓵ ̠ˊ࣏Û Â]«ʇ࿁ʵǒljƌՈ) ̠ˊ࣏Ûr ¤ljƌՈ)ͥ IQ ǎ JH ՈȨūȕš ᰻┻⓵ՈūÐՈ[P ǝᡅËᜐՈūÐ 4[ „ඝிඣՈP࢑Ŏ„4Ɵ ȋ: Ḱࢿ4Ŏک┻⓵┻⓵┻⓵┻⓵ «ńš᰻Ŏ„Ո ūÐ7Ȓ7Ȓ7Ȓ7Ȓ îŎ„ ̑Ρ Ở Ƕ┨Ω╠ 7Ȓ ƣūÐɥdzt£Ëᜐ ႷɅ]͹Ǖϣɉ]ƌńՈΩ╠4 ிඣ“ϣɉΩ╠ ȭàՈɉ Ω╠̠ˊ࣏Ûdz Ởẋ¤ṁ᪩ɉՈ 5ͩǡکǶ᪩ūÐ ՈËᜐ ÂỞ ÐՈₑ,Ëᜐ ǣ4Ƿܲ Ո඗ Ș4ŷΞ ńPǝūÐՈËᜐƛⒸ Ξ ȘǕɴɉ]ƌń ὧ4Ɉ ╠ ὧ4ǶΩ╠ūÐ ÂîūÐ Ո̱ňϔ ʮ̩&ūÐŌϧËᜐ 7Q ՈȨ4ẝdzlj᪅ Ω╠ ū ╠ՈǕɴdz࿁ńūÐŌϧËᜐ7Q Kdz࿁ńūÐËᜐƛⒸ4Ξ Șń ūÐ Ëᜐ ƛⒸ̼ϟ4Ω ±š᰻Ω╠ ՈūÐdzₑ,ǣ4Ëᜐ4ẝ࢑ₑ,Ëᜐ ] ◄ᡅ̱ňிඣḳâՈ Q̲dž^4 Ω Ð4ẝʳ ńΩ╠ ̠ˊ࣏Û îΩ╠ Ƕ┨Ȓ Ëᜐ JX| ẘú4š᰻Ω╠ Ո࣏ÛණනËᜐr dzǶ┨Ո4Ɵ ȋ: Ḱࢿ4Ω╠̠ˊ࣏Ûr ¤ljƌՈ)ͥ IQ ǎ JH ՈȨūȕš ᰻Ω╠ Ոū ඝிඣՈP࢑Ŏ„4 ‰S扊 ᩨ& Ω╠«کΩ╠Ω╠Ω╠Ω╠ «ńš᰻Ŏ„Ո ūÐ7Q7Q7Q7Q îŎ„ ̑Ρ Ở ࣏ÛʐǶ̠ˊ࣏Û4 /ࢴ &Ω╠̠ˊ࣏Û 3┻⓵̠ˊ ┻⓵€|ãroʐǶ€xqãL4uØîȭàՈŎ„̠ˊ࣏Û ି&Ω╠€WrkNL3 ʵǒš᰻Ŏ„Ո࣏Û« Ȫdzᝯʮ̩ʐʮ̩ͥ]Ȑ îŎ„ẟP ǹ )̠ˊ࣏Ûࢴ&Ŏ„̠ˊ࣏Ûdz࿁ŰȌỆ ̠ˊ„ɥᬥˑà)ὧʳ̠ˊŎ„ ŷʵǒ)ȕₓǻ ḰּàՈ)̠ˊ࣏Û4 îẝ࢑ ‰S扊 ᪊/̶࢑] Ȑି/ՈŎ„ Âᰏt ɣP࢑ି /Ñ]ȐՈ)ȕₓǻ4Ŏ„ǕϣȒ zŎ„໐]ࢴ&) ẝ«ü&Ëᜐẝ‡ūГϣŎ„wâ4 Ƿܲ4ƟǕϣẝ‡̑Ρr ūÐɥ]࿁t£ǀt4ḳ)ūÐ8JŽ|hK 9ʐ8JŽ|Y9Kƞି ūÐƅָȉՈ༘ி4 ŷΞ Ëᜐ ┨ͩūÐ r ┨ϔ਍z S4͹Ξ ËᜐūÐrǕɴĽƿ ൫] Ŏ„« ‰S扊 ńËᜐūÐƛⒸ̼ϟ4] Ƿ„Ոz☢ͩՈǝ⤚᰻Ո4Ŏ„^ǷËᜐՈ ̵ƅ͟ி4Ở„ )Ϭzū߾ JwY ᪂̣ՈPƵ̱ň>ǀt4 ȭ ‰S扊 ໐ᣄ )« ϵŎǹՈ̲ᾬwâš ᰻Ո4̲ᾬwâǎ)ˑà^ ǷËᜐՈūÐ Ở„ńǝūÐ7Ⓒˑà)zŎ„4‰S扊 ż̶̠ˊ b`Š ࢑)zŎ„4 &ͱᾬ)ʐ̲ᾬ)̓ ି4 ̲ᾬ)ࢴ&8)9 ͱᾬ) ࢴ&8Ŏ„94 ) ̲ᾬẟᜐϕ4dzÑ᪸)«̱ňிඣՈ̓⒬4 ȭz)Ո̠ˊ«̱ňிඣP ǔₑᡅՈ ɳᅆ Ƿ«ϵz)±ūǣ̱ňிඣ ࿁̻^ ৰ͗তৰ͗তৰ͗তৰ͗ত )ிඣ)ிඣ)ிඣ)ிඣ ৰ 80 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ W 扊 ┻⓵⒬ ிඣɉିƧ  扊 )⒬ { Ʀǎ5 I 扊 ᫇Ϭ⒬ \ ȥՈ 扊|QQ  Ʀǎ5 l dzϬ 扊|QQ ‰ Ʀǎ5 Š ᪸ ۅିƧේ d b‰Š ┻⓵⒬ ிඣɉିƧ Š b‰Š )⒬ ` ç¥⒬   b‰Š ᫇Ϭ⒬ æ ȥՈ b‰Š|QQ b i{| a dzϬ b‰Š|QQ S Ʀǎ5 Š ᪸ ۅିƧේ ǎᜬ߾ՈିƧz[ᜬ ͢ȯ5^ƌʔɉȳẴ৪ՈିƧǀ͔]Ȑ4ۅTYPE« 4 Ĺ ͢ේ P DPL DT0 TYPE 000 Dword Count ʒɳ ⒬ȳẴ৪ BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 Byte m+5 Byte m +4 Offset(31...16) Attributes Selector Offset(15...0) M+7 M+6 M+5 M+4 M+3 M+2 M+1 M+0⒬ȳẴ৪ )ȳẴ৪ŤϬ 4 Ƌᅆ ʸśΞ[ «PʳՈ :/ɥńzିƧǻ4&rƫzˊᢧ u͹Ⱥ͢ŐՈȳẴPἑ4 ń·එ TSS Ոrȅ>ඓ ᩶ᢧ rç¥⒬ȳẴ৪ )⒬^┻⓵ ⒬ȳẴ৪^ç¥⒬Ոʸś )ȳẴ৪ᜬǸƌ„ J{|X ȖŌŜ А└ \J| d4\J|aŠ \J|a`4\J|S śּȐ )ȕₓᜬՈ͑ǧŌŜ«Ɖ☤ IDTR Ǹƌ„ǡâ4Ո ƷՈʸś^ GDTR Ǹƌ„Ոʸ ϔǒ඗Ȁϔǒ඗Ȁϔǒ඗Ȁϔǒ඗Ȁ                    ाⒸ4¿xqqLwyMrsunÀ ‑ՈVɣȳẴ৪Ť‰Ƌᅆ & b`Š ȳẴ৪8 Нr )ȕₓᜬՈाⒸ«ń࣏Û ǎՈūϬ້Ɖ¥Ո4 Ո͑ǧr ໐«Ű̩ƾՈ඗Ȁ ĉŐrƿ└ Ո̼ϟ4ɥʻPƅr⏅͐̓⒬P ʳ « ☦ȕĽ zŎ„̠ˊ࣏Û4 Ⱥẝ‡ȳẴ৪Ϭ8⒬9ǡࢴʀ«ǔƮᬥՈ ü&ƷØ>ඓ]±±«) Kɥ«᪸ ńljĈµś[ ‰S扊 ǮƅỞẋ) ⒬3┻⓵⒬zç¥⒬±࿁Ḱࢿ4ȭàՈ) ¤Ñ J{| ż̓⑃ò« bâ4)ȳẴ৪ᜬ J{| ¤ȯՈȳẴ৪Ǯ࿁«)⒬3┻⓵⒬ʐç¥⒬4 )ȳẴ৪ᜬ Ǹƌ„ J{|X ū߾ J{| ńͱƌՈĹา4 ϵz ‰S扊 Ǯ᪊/ b`Š )ȕₓǻ )ȕₓՈ௦š4 ᬥ͔ɴȳẴ৪ᜬ }{| Pʳ ńϘிඣ )ȳẴ৪ᜬ J{| ǮƅP4 [ ‰S扊 î)ȕₓǻň&)ȳẴ৪ᜬ J{| ȳẴ৪Ո௦š ໐]͹«)ȕₓᜬՈ Ĉµś[ ‰S扊 ]ūϬǒµś[Ո)ȕₓᜬ ໐«ūϬ)ȳẴ৪ᜬ J{| 4ńljĈµś ńˑà)z້̠ˊŎ„r ‰S扊 ʵǒ)ȕₓǻḰ 4ּàՈ̠ˊ࣏Û4 IJ« ńlj )ȕₓᜬ)ȕₓᜬ)ȕₓᜬ)ȕₓᜬ ৰ 81 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ /* movw $0x8E00,%dx /* interrupt gate - dpl=0, present  ƌ΢Ո«ȻࢿŌŜՈʌ 16 Ĺ ẝₐ«ȺʒɳǍʻ΢͑ dx // edx ՈʌƋᅆᾬ movw %dx,%ax /* selector = 0x0008 = cs */ // edx ƌ΢Ɖ¥࣏ÛՈ 32 ĹȻࢿŌŜ üǸ dx ƌ΢Ո«ȻࢿŌŜՈĺ 16 Ĺ movl $0x00080000,%eax ɉՈọōƄ« 0x0008 Ⱥ͢ljƌń eax ՈʌƋᅆᾬۅ// ϵzÏ lea ignore_int,%edx „ᩨƉ¥࣏ÛՈȻࢿŌŜ΢͑ edx Ǹƌڌ// Ⱥ setup_idt: */ * written by the page tables. * sure everything is ok. This routine will be over - * are enabled elsewhere, when we can be relatively * in the idt -table may do so themselves. Interrupts * idt. Everyt hing that wants to install itself * ignore_int, interrupt gates. It then loads * sets up a idt with 256 entries pointing to * * setup_idt /* Ě ͗.1 Ǹƌ„᪂ǎ̑Ρ(ǸĚϦႮz9The Linux Process Manager :) ń setup_idt ȭȈǸƌ„Ո᪂ǎ̑ΡΞ[Ě setup_idt K«Ϭ˛ේ΅Ո Ẕᜐzǒµś[4 call setup_idt ᩨՈƉ¥࣏Û ignore_int4ڌȳẴ৪῁᪂ǎ&ūȕP ȭz)ȕₓᜬՈ!ϧĚńிඣšȰՈrȅɥ>ඓŌϧr4ƷȺ)ȕₓᜬՈ ɣP !ϧĚ)ȕₓᜬ!ϧĚ)ȕₓᜬ!ϧĚ)ȕₓᜬ!ϧĚ)ȕₓᜬ ໐ūϬ┻⓵⒬Ÿ]Ćẝ4Ɇ üǸ┻⓵⒬Ϭz̠ˊŎ„4 üǸ)⒬Ϭz̠ˊ JŽ|X Ո)4 )⒬^ ┻⓵ ⒬Ո :/ńz ƟūϬ)⒬ՈrȅĆȺʃȣĹ JW ᪂า& S ǡ͟ ⒱)4 ọōƄ4 ɉՈۅQMNMLqã Ϭzº }{| ọō ּàՈɉȳẴ৪ ü Ǹȭzẝₐ nMNMLqã ȑ/«Ï ᪃⒲rĆš᰻Ŏ„4 ń ŷńͱƌ HS ᜬ߾ȳẴ৪ȭŌŜḰdž \ά ŷ᪩ɉ]ƌń4ūϬ ᪩ȳẴ৪ẟᜐͱƌ H Ĺࢴ&ƌńĹ4 Ha ᜬ߾ȳẴ৪ȭŌŜḰdž«ƅ άՈ z້᪸᪩ȳẴ৪¤ȳẴՈɉƌ {Hi ᜬ߾ȳẴ৪Ľƿ൫͝ b Ĺ ϬzĽƿ̼ɡ ÑΟǎ࿁Ȫ᪃⒲4 ৰ 82 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ call _printk pushl $int_msg // Ⱥȴ߾ǍʻƏ͑ʄ Ɇ&džϔČỖඝϔ printk mov %ax,%fs mov %ax,%es mov %ax,%ds movl $0x10,%eax push %fs push %es push %ds pushl %edx pushl %ecx pushl %eax ignore_int: // ᔕ // &rමĈȢʄ Ոʸśü Ǹń᫇Ϭ printk 7QȕʄƏ͑rK‡Ǹƌ„ dzÑþr]໇ .align 2 .asciz "Unknown interrupt\n\r" int_msg: // Ϧ⏝ȴ߾Ǎʻ Ɵ᫇Ϭ̵ƅńிඣₑ,᪂ǎՈ)ՈrȅɥĆº߾ẝǍʻ /* This is the default interrupt "handler" :-) */ ¡ZṗϦϦ⏝Ǎʻ4 ƷK«P˛ේ΅Ոϔ IJ«ń͢ǒɴՈr ȅ᫇Ϭr c ᪱ᣄՈϔ printk 4Ϭzńʃ ᩨƉ¥࣏Û ignore_intڌᩨƉ¥࣏ÛڌᩨƉ¥࣏ÛڌᩨƉ¥࣏Ûڌ ret lidt idt_descr // ¤ṁ IDTR Ǹƌ„ū͢ūȕ)ȕₓᜬ jne rp_sidt dec %ecx addl $8,%edi // Ⱥ edi ࢿ4[Pᡅ᪂าՈȳẴ৪Ĺ̠ movl %edx,4(%edi) // ƌ΢Ո«ȳẴ৪Ոʒɳ // Ⱥ edx ΢͑ȳẴ৪Ոʌ 32 Ĺ edx ՈʌƋᅆƌ΢ȻࢿŌŜՈʌ 16 Ĺ ĺƋᅆ movl %eax,(%edi) // ʌƋᅆƌ΢Ո«ɉọōƄ 0x0008 // Ⱥ eax ΢͑ȳẴ৪Ոĺ 32 Ĺ ẝrՈ eax ĺƋᅆƌ΢Ո«ȻࢿŌŜՈĺ 16 Ĺ rp_sidt: mov $256,%ecx // ᪂ǎǶɳƵϔ& 256 ü&ƅ 256 ȳẴ৪ lea _idt,%edi  // Ⱥ)ȕₓᜬՈŊŌŜ΢͑ edi ৰ 83 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ \ : \ ""movl %%edx,%2 "movl %%eax,%1 \n\t" \ ᪂า)ȕₓ "movw %0,%%dx\n\t" \ ŌŜ ȺିƧʃȣƋ΢4 edx ՈĺƋᅆ edx Ոʌ Ƌɉƌ΢Ո«Ɖ¥࣏ÛՈʌ 4 ƋᅆՈȻࢿ "movw %%dx,%%ax\n\t" \ «ɉọōƄ ȺƉ¥࣏ÛȻࢿŌŜՈ ĺ 4 Ƌᅆ΢4r eax ՈĺƋᅆ ẝrՈ eax Ոʌ Ƌᅆƌ΢Ո __asm__ ( #define _set_gate(gate_addr,type,dpl,addr) \ eax ʌƋᅆȯƅɉọō৪4 edx Ɖ¥࣏ÛՈȻࢿŌŜ%4 3 ȳẴ৪Ոʌ 4 Ƌᅆ ȳẴ৪Ո ĺ 4 Ƌᅆ2 ϵ dpl ʐ type ඈtՈିƧʃȣƋ 1 0 ȳẴ ĽƿȨ ȳẴ৪ିƧ ǻՈȨdpl )ȳẴ৪ՈŌŜtype džϔgate_addr r44 c r ɥ◄ᡅἹƼP‡ᢈ ƷՈ᪂ǎ 5ͩ^šȰ⓺ɉȭȳẴ৪Ո᪂ǎ5ͩ«PʳՈ Ǯ]ẋẝ ₐ«Ⱥ˛ේ᪱ᣄ΀͑ áɶǃǎ5áɶǃǎ5áɶǃǎ5áɶǃǎ5 tՈ4 _set_gate Ϭzǀtȭ⒬ȳẴ৪Ո᪂ǎ4ʌɶՈǎ5« Ởẋȕ _set_gate ČỖ]ȐՈdžϔǡǀ ǡǀt⒬ȳẴ৪Ո᪂ǎ4áɶ« &r5ƫ ࣏Û᪂ᩥ Linux ȴƇrɶϔǃǎ5 ⒬ȳẴ৪Ո᪂ǎ⒬ȳẴ৪Ո᪂ǎ⒬ȳẴ৪Ո᪂ǎ⒬ȳẴ৪Ո᪂ǎ ŅՈ)dzÑϵ̱ňிඣႮᜐ᪂ǎ IJ«ẝ࢑᪂ǎẜ«ƅPǎՈL̻Ո4 )ȕₓ« Intel ljНՈ c⒬Ϭz̠ˊ CPU ՈŎ„4m 0x19 ȭzQ 32 0x 00 ඣẟᜐʌPɶƵՈ!ϧĚՈrȅ◄ᡅₑ,᪂ǎ)ȕₓᜬ4 Û̵ƅǒ ┉Ϭ̠Ո4Ʒ±±Ϭzȴ߾àϬ࣏Û᫇Ϭr ̵ƅₑ ,᪂ǎՈ)ȕₓ4ü Ǹ ńி ᩨƉ¥࣏ڌᩨƉ¥࣏Û IJ«ẝڌᩨȨū͢ūȕڌńšȰ⓺ɉń)ȕₓᜬ᪂ǎr )ȕₓᜬՈ᪂ǎ)ȕₓᜬՈ᪂ǎ)ȕₓᜬՈ᪂ǎ)ȕₓᜬՈ᪂ǎ iret popl %eax popl %ecx popl %edx pop %ds pop %es pop %fs popl %eax ৰ 84 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;int i { void trap_init(void) ிඣϬ4Ո CPU Ŏ„̠ˊ࣏Û«ńϔ trap_init ᪂ǎՈ4 ᪂าிඣϬՈ)ȕₓ᪂าிඣϬՈ)ȕₓ᪂าிඣϬՈ)ȕₓ᪂าிඣϬՈ)ȕₓ _set_gate(&idt[n],15,3,addr) #define set_system_gate(n,addr) \ // &idt[n]ȭà)ǻń)ȳẴ৪ᜬՈȻࢿȨ )ȳẴ৪ՈିƧ« 15 Ľƿ ൫« 34 // džϔn - )ǻaddr - )࣏ÛȻࢿŌŜ4 // ᪂าிඣ᫇Ϭ⒬ϔ4 _set_gate(&idt[n],15,0,addr) #define set_trap_gate(n,addr) \ // &idt[n]ȭà)ǻń)ȳẴ৪ᜬՈȻࢿȨ )ȳẴ৪ՈିƧ« 15 Ľƿ ൫« 04 // džϔn - )ǻaddr - )࣏ÛȻࢿŌŜ4 // ᪂า┻⓵⒬ϔ: _set_gate(&idt[n],14,0,addr) #define set_intr_gate(n,addr) \ // &idt[n]ȭà)ǻń)ȳẴ৪ᜬՈȻࢿȨ )ȳẴ৪ՈିƧ« 14 Ľƿ ൫« 04 // džϔn - )ǻaddr - )࣏ÛȻࢿŌŜ4 // ᪂า)⒬ϔ: set_trap_gate() ᪂ า Ո Ľ ƿ ൫ « 0 ໐ set_system_gate() ᪂ า Ո Ľ ƿ ൫ « 3 4 Ϭzǀtȭ)ȕₓᜬ]ȐିƧՈ⒬ȳẴ৪Ո᪂า4 ிඣ⒬᪂าϔ 3set_system_gate() 3ste_trap_gate() ┻⓵⒬᪂าϔ set_intr_gate() )⒬᪂าϔ ʌɶǃǎ5ʌɶǃǎ5ʌɶǃǎ5ʌɶǃǎ5 "a" (0x00080000)) Ĺ«Ϭzº GDT ọō͔ɴɉȳẴ৪4ń GDT ৰ 1 ǻȳẴ৪ɥ«ϬzȳẴ CS ɉՈ4 Ոɉ40008 Ոxẟ:ʸś« 0000 0000 0000 10004Q☦>ඓ ȴẋrɉ Ǹƌ„Ոʸś Q 13 Ⱥ 0x00080000 ΢4 eax  ʌƋᅆ« 00084ẝȨ«ɉọō Ƅ ᜬ߾ọōr CS ିƧ "d" ((char *) (addr)),  ȺƉ¥࣏ÛՈ 32 Ĺ͑ǧŌŜ΢4 edx "o" (*(4+(char *) (gate_addr))), \ "o" (*((char *) (gate_addr))), \ 8o9ᜬ߾ͱƌŌŜ¤ZȻࢿₓ : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ „‑ՈPǸƌ ȺିƧʃȣƋ΢4ϵේ᪕„Ⴎᜐ ৰ 85 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ń!ϧĚՈrȅ ͢Q 17 )ͣĿՈȯ5ᢅ[ᜬ } set_trap_gate(39,¶llel_interrupt); outb(inb_p(0xA1)&0xdf,0xA1); outb_p(inb_p(0x21)&0xfb,0x21); // ȭ 8259A Ո̠ˊ set_trap_gate(45,&irq13); set_trap_gate(i,&reserved); for (i=17;i<48;i++) set_trap_gate(16,&coprocessor_error); set_trap_gate(15,&reserved); set_trap_gate(14,&page_fault); set_trap_gate(13,&general_protection); set_trap_gate(12,&stack_segment); set_trap_gate(11,&segment_not_present); set_trap_gate(10,&invalid_TSS); set_trap_gate(9 ,&coprocessor_segment_overrun); set_trap_gate(8,&double_fault); set_trap_gate(7,&device_not_available); set_trap_gate(6,&invalid_op); set_system_gate(5,&bounds); set_system_gate(4,&overflow); set_system_gate(3,&int3); /* int3 -5 can be called from all */ set_trap_gate(2,&nmi); set_trap_gate(1,&debug); set_trap_gate(0,÷_error); ৰ 86 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ϔ«no_error_code3error_code ʐ system_call 4ỄϦ⓺ɉ'ᡅ«Ⱥʄʮ̩4ƣǡՈźɍ ńẟ͑⓺ɉ'ᡅ«᪂ǎ ʄՈʸś ȭà 3 ࢑Ŏ„ƅY࢑ϔǡ᪂ǎʄՈʸś4ẝY ẟ͑⓺ɉʐỄϦ⓺ɉẟ͑⓺ɉʐỄϦ⓺ɉẟ͑⓺ɉʐỄϦ⓺ɉẟ͑⓺ɉʐỄϦ⓺ɉ Ŏ„ʐிඣ᫇Ϭ4ۅrϦ⏝ Ŏ„3ۅ&]rϦ⏝ „ϣʄǜdž ż̴ƏʄՈ«SS ʐ ESP 4Ƿ«ẝƣüẜdzÑȺŎ ƏʄΞȘńǕ error_codeۅńżȒĆȺϦ⏝ ۅƅ͢Ʒ̑ΡΞȘŎ„rƅϦ⏝ /Ə͑ʄ4 IJ«ńljĈµś[dz ࿁ ńǒµś̠ ˊŎ„r ĆȺ EFLAG 3CS ʐ EIP PʐৰY⓺ɉ4 ͟ȏՈ«ৰ ȭz]ȐŎ„Ɖ¥࣏Û ń̠ˊ⓺ɉ :Ŏdz࿁«ǔ̓Ո ü Ǹƨ তȒ ☦Ոᾬ 3. ỄϦ⓺ɉỄϦ⓺ɉỄϦ⓺ɉỄϦ⓺ɉ ϵ˛ේ΅Ո Ϭzʮ̩Ȣʄ ÑǎȭǍǻՈ̠ˊńிඣ᫇Ϭ «Ϭ C ᪱ᣄ΅Ո ǀtȭּàŎ„Ո̠ˊ4 2. ̠ˊ⓺ɉ̠ˊ⓺ɉ̠ˊ⓺ɉ̠ˊ⓺ɉ ̓ᾬ 1. ẟ͑⓺ɉẟ͑⓺ɉẟ͑⓺ɉẟ͑⓺ɉ ϵ˛ේ΅Ո'ᡅ«ǀtȭʄՈ᪂ǎ4 &P[Y⓺ɉ 4Ŏ„ՈƉ¥࣏Û̠ˊẋ࣏dzÑ ɴńŌϧ)ிඣՈǒᯬՈᾬ Ŏ„̠ˊŎ„̠ˊŎ„̠ˊŎ„̠ˊ Ȍ: ۅĚ ͗.2Intel ljНՈ)ȕₓϦႮz9Linux0.11 ļ ৰ 87 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ pushl %edx lea 44(%esp),%edx // ቻǚẘúŌŜՈ EIP ՈȨ ΢͑ edx  β̣ň&ৰx⓺ɉϔՈdžϔ pushl $0 # "error code" push %fs push %es push %ds pushl %ebp pushl %esi pushl %edi pushl %edx pushl %ecx pushl %ebx xchgl %eax,(%esp) // ΢͑ eax  ȐrȺ ea x ƣǡՈȨljƌ4ʄ // ń᫇ϬQ>ඓȺৰx⓺ɉᡅËᜐՈ࣏ÛՈ͑ǧŌŜƏʄr ẝₐ«Ⱥẝ͑ǧŌŜ no_error_code: pushl $_do_divide_error _divide_error: üǸɥńʄƏ͑rP 04ȭàՈŎ„Ɖ¥࣏Û& ۅϵz̵ƅϦ⏝ Ŏ„Ոʄ̑ΡۅĚ ͗.3 ]rϦ⏝ Ŏ„ńẟ͑ৰx⓺ɉQʄՈ̑ΡΞ[ۅ]rϦ⏝ „ŎۅŎ„]rϦ⏝ۅŎ„]rϦ⏝ۅŎ„]rϦ⏝ۅ]rϦ⏝ ȭzிඣ᫇ϬՈỄϦ Ʒẜƅ͢ƷՈ̱ň4 ৰ 88 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ pushl $_do_invalid_op _invalid_op: jmp no_error_code pushl $_do_bounds _bounds: jmp no_error_code pushl $_do_overflow _overflow: jmp no_error_code pushl $_do_int3 _int3: jmp no_error_code pushl $_do_nmi _nmi: jmp no_error_code pushl $_do_int3 # _do_debug _debug: iret // ẘú4ʄ EIP ūǎՈŌŜ popl %eax popl %ebx popl %ecx popl %edx popl %edi popl %esi popl %ebp pop %ds pop %es pop %fs addl $8,%esp // ẜƣȈǸƌ„ՈȨ call *%eax // ᫇Ϭৰx⓺ɉՈ̠ˊ࣏Û mov %dx,%fs mov %dx,%es mov %dx,%ds movl $0x10,%edx // ᪂ǎȈɉǸƌ„Ëᜐிඣϔǒɉ ৰ 89 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ push %ds pushl %ebp pushl %esi pushl %edi pushl %edx pushl %ecx xchgl %eb x,(%esp) # &function <-> %ebx xchgl %eax,4(%esp) # error code <-> %eax error_code: pushl $_do_double_fault _double_fault: Pʳ4ȭàՈŎ„Ɖ¥࣏Û& ΢ńʄՈ͐ᾬ«Ϭzň&džϔ ǒɴՈ 5ͩ^ no_error_code Ո5ͩό :ǀ͔ۅȺϦ⏝ Ŏ„Ոʄ̑ΡۅĚ ͗.4 rϦ⏝ Ŏ„ńẟ͑ৰx⓺ɉQʄՈ̑ΡΞ[ۅrϦ⏝ „ŎۅŎ„rϦ⏝ۅŎ„rϦ⏝ۅŎ„rϦ⏝ۅrϦ⏝ jmp no_error_code pushl $_do_reserved _reserved: jmp no_error_code pushl $_do_coprocessor_segment_overrun _coprocessor_segment_overrun: jmp no_error_code ৰ 90 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ϬɥǯɆ ிඣ᫇Ϭ4Ʒ ØĉŐ̲ƌâ^ֲơՈ ᪿ΅ Ȉ࢑ I/O ᪂̣ՈūϬ ń࣏Ûȳ ɣ̱ňிඣ ῁ȴ Ƈǔ̶࢑ிඣ൫Ոϔň&ிඣ^ ̲АՈȉǧ ̲А ȭẝ ‡ϔՈ᫇ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ jmp error_code pushl $_do_general_protection _general_protection: jmp error_code pushl $_do_stack_segment _sta ck_segment: jmp error_code pushl $_do_segment_not_present _segment_not_present: jmp error_code pushl $_do_invalid_TSS _invalid_TSS: iret popl %eax popl %ebx popl %ecx popl %edx popl %edi popl %esi popl %ebp pop %ds pop %es pop %fs addl $8,%esp call *%ebx mov %ax,%fs mov %ax,%es mov %ax,%ds movl $0x10,%eax pushl %eax lea 44(%esp),%eax # offset pushl %eax # error code push %fs push %es ৰ 91 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ǫ̲ ń)ẘú⓺ɉ ĆȭǍǻẟᜐ̠ˊ4ẝɥ◄ᡅȭ PCB ẟᜐ̠ˊ &r5ƫՈ᪃ OLDSS = 0x2C OLDESP = 0x28 EFLAGS = 0x24 CS = 0x20 EIP = 0x1C DS = 0x18 ES = 0x14 FS = 0x10 EDX = 0x0C ECX = 0x08 EBX = 0x04 EAX = 0x00 // ǎ5ȈǸƌ„ńȢʄՈȻࢿₓ ȨƏ͑ʄ4 ࢿŌŜ4 ͼ͛ ȭ ȢʄՈūϬ«Ǖϣńẘú⓺ɉ4໐ń᫇Ϭ £࿁ ϔ 7ȒĆȺ eax Ոẘú &r࿁̻ɨṇ5ƫ ՈūϬʄՈẝ ‡Ȩ Linux Ởẋǃǎ5r ȈǸƌ„Ȩ ńʄՈȻ Ě ͗.5 ிඣ᫇ϬrʄՈ̑Ρ 7Q ȕʄƏ͑ՈȨΞ[Ě ^͢ƷՈŎ„Pʳ ńிඣ᫇ϬՈrȅĆljƌǸƌ„ՈȨ4 ńËᜐிඣ᫇ϬՈ £࿁ϔ ՈǍʻ ◄ᡅȺƣǡՈȨljƌ4ிඣʄ4 ʄǜdž« ūȺƣǡËᜐϬ› ʄՈ esp ʐ ss ǜdž4Ëᜐிඣʄ &rljƌƣǡ esp ʐ ss ǜĚ4ẝʳɥĆǕϣʄǜdž4 ඣ᫇Ϭ«&r ࿁̻ᩭϬ›Ո࣏Û᫇ϬிඣՈϔ ü Ǹń“ϣŎ„Ոr ȅPǎĆǕϣƿ└Ո ΢͑ eax Ǹƌ„4ƅՈிඣ᫇Ϭ ◄ᡅdžϔ ẝ ‡džϔ◄ᡅūϬ Ǹƌ„ǡČỖ4ẝ«ü&ி ȭz]Ȑிඣ᫇ϬՈͣĿǒɴ«ϵּàՈ£࿁ǻΟǎՈ ẝ £࿁ ǻᡅ ńிඣ᫇Ϭ7Q ĈǪȽՈ1ňɥ੄řr ὧɥƼΙẝ«⒬4 ϔ4ẝỞ἗ɥΙʻ«P ĦĖՈǪȽ Ո̓⒬ ¤ƅՈ¦Ǯ࿁Ởẋẝ «⒬ẟ͑ ǪȽ4ẝ ʳlj ¤ƅՈிඣ᫇Ϭ῁ȑ/Ởẋ int 0x80 ǡǀt çŁ͢ ÂՈ5ͩ῁\ͩūϬẝ‡ிඣ &r࿁̻lj᪅ẝ࢑£࿁࿁̻Ƿ„ūϬ ◄ᡅƅPͳƽ͔ƶ:ǡlj᪅ƷՈǒɴ4 ¬ǪP࣏Û ɡ᪦ʐඣᩥிඣᰈļūϬ̑Ρ਍਍4ϵzிඣ᫇Ϭ«ȭிඣ൫ϔՈūϬ ৰ 92 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ // zẟ࣏᫇òՈ̱ňr4 // ඣɳʟǍʻ Ở ẋ£࿁ǻńϔū⍌ᜬȺּàՈிඣϔ â4ǡËᜐȉ ؄ɥ«͟ // ¦4ƷՈËᜐẋ࣏« ̴ẟᜐ⏝̼᪳ ɡÑlj᪅ ࿁̻Ƿܲ Ո᫇ϬՈிඣϔϢȒljƌி ǒɴՈ Ʒ«̱ňிඣՈ׏⒬ۅ// ிඣ᫇ϬՈrȅऺণ «Ëᜐ ˮPϔ ɥ«ϵẝɉÏ .align 2 jmp _schedule pushl $ret_from_sys_call reschedule: //ret_from_sys_call ̠ණනËᜐ ẝₐ«Ởẋȭʄ̱ňǡµŃ call ̱ňǒɴẝ£࿁Ո // ிඣϔËᜐǀr 7Ȓ ◄ᡅËᜐ᫇ò࣏Û Ɵ᫇ò࣏ÛË ᜐǀȒ ◄ᡅú4 .align 2 iret movl $-1,%eax bad_sys_call: 1 EAX Ǹƌ„ϬzljƌẝẘúȨ // Ɵẟᜐிඣ᫇ϬϦ⏝ՈrȅɥĆẘú .align 2 .globl _device_not_available, _coprocessor_error .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt .globl _system_call,_sys_fork,_timer_interrupt,_sys_execve */ * strange reason. Urgel. Now I just ignore them. * Ok, I get parallel printer interrupts while using the floppy for some /* nr_system_calls = 72  // ிඣ᫇ϬՈʇϔ 72 SIG_CHLD = 17 ńẘú⓺ɉ ẟᜐ()«Ȫ◄ᡅËᜐẟ࣏᫇òȭǍǻẟᜐ̠ˊÑǎʮ̩ɴŖ4 sa_resto rer = 12 sa_flags = 8 sa_mask = 4 sa_handler = 0 # offsets within sigaction blocked = (33*16) sigaction = 16 # MUST be 16 (=len of sigaction) signal = 12 priority = 8 counter = 4 state = 0 # these are offsets into the task -struct. ⒲ tast_struct ඗ȀՈP‡ǜₓ KỞẋǃǎ5rẝ‡ǜₓՈȻࢿₓ ৰ 93 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ? cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 jne 3f cmpw $0x0f,CS(%esp) # was old code segment supervisor ? je 3f cmpl _task,%eax movl _current,%eax # task[0] cannot have signals // ẝₐ'ᡅ5ǎ4rȭǍǻՈ̠ˊ ͣĿ̑ΡȺńǍǻ̠ˊPত᩶ᢧ // \᩾Ëᜐrẟ࣏᫇ò^Ȫ ῁ĆºẝₐËᜐẘú⓺ɉ ret_from_sys_call: je reschedule cmpl $0,counter(%eax) # counter jne reschedule cmpl $0,state(%eax) # state movl _current,%eax // ΞȘƟQẟ࣏ՈẜmŅrⒸċ ]Ëᜐẟ࣏᫇ò4 «ΞȘƟQẟ࣏Ոźɍ]«ɥථɍ ]Ëᜐẟ࣏᫇ò// ƣ // Ōϧȭ«ȪËᜐẟ࣏᫇òẟᜐ()4 pushl %eax // üǸ◄ᡅȺ͢ljƌ4 „// Ëᜐǀৰx⓺ɉՈẘúȨĆ΢͑ eax Ǹƌ„ ϵzȒ☦Ո̱ňĆΝǜ eax Ǹƌ call _sys_call_table(,%eax,4) // ඣ᫇Ϭ C ̠ˊ// ϔՈŌŜϔඈᜬ4 Ʒ«PĉŐ 72 ி  // Ո« C ࣏ÛՈ sys_call_table ń include/linux/sys.h //%eax 44ᜬՈɣP-῁ŤϬ 4 Ƌᅆü&«ϔū⍌4ẝₐ_sys_call_table ȭà //[☦«Ởẋ£࿁ ǻńிඣϔᜬ â4ּàՈிඣϔ4᫇ ϬŌŜ = _sys_call_table + mov %dx,%fs movl $0x17,%edx # fs points to local data space //FS ūȕɴᾬϔǒɉ(ɴᾬȳẴ৪ᜬϔǒɉȳẴ৪) mov %dx,%es mov %dx,%ds movl $0x10,%edx # set up ds,es to kernel space // ᩭ DS,ES ūȕͱʴϔǒɉ(͔ɴȳẴ৪ᜬϔǒɉȳẴ৪) pushl %ebx # to the system call pushl %ecx # push %ebx,%ecx,%edx as parameters pushl %edx push %fs push %es push %ds // Ո ESP 3ƣǡՈ SS Ǹƌ„ՈȨ4ÂØ«ϵܰâƏ͑ȢʄՈ4 // ŌϧljĈɴ ŖՈ̱ň ńǸ7Qń ிඣ Ȣʄ >ඓljƌr EIP3 CS 3EFLAGS 3ƣǡ ja bad_sys_call cmpl $nr_system_calls -1,%eax // ΞȘ£࿁ǻ᱉ẋr 71 ɥĆϦ⏝ ü&P͝ɥ 72 ிඣ᫇Ϭϔ4 _syst em_call: ৰ 94 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;()ex tern int sys_lseek extern int sys_stat(); extern int sys_break(); extern int sys_chown(); extern int sys_chmod(); extern int sys_mknod(); extern int sys_time(); extern int sys_chdir(); extern int sys_execve(); extern int sys_unlink(); extern int sys_link(); extern in t sys_creat(); extern int sys_waitpid(); extern int sys_close(); extern int sys_open(); extern int sys_write(); extern int sys_read(); extern int sys_fork(); extern int sys_exit(); extern int sys_setup(); ᜬՈ!ϧĚ«ń include/linux/sys.h â dzÑ ׏4 ிඣ᫇ϬּàՈ £࿁ «ỞẋɡâPϔ ū⍌Ոϔ ඈâ4Ո4ẝۅºÏ iret pop %ds pop %es pop %fs popl %edx popl %ecx popl %ebx 3: popl %eax „// ʮ̩Ǹƌ popl %eax call _do_signal pushl %ecx incl %ecx movl %ebx,signal(%eax) btrl %ecx,%ebx je 3f bsfl %ecx,%ecx andl %ebx,%ecx notl %ecx movl blocked(%eax),%ecx movl signal(%eax),%ebx jne 3f ৰ 95 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;()extern int sys_dup2 extern int sys_ustat(); extern int sys_ch root(); extern int sys_umask(); extern int sys_uname(); extern int sys_ulimit(); extern int sys_setpgid(); extern int sys_mpx(); extern int sys_fcntl(); extern int sys_ioctl(); extern int sys_lock(); extern int sys_phys(); extern int sys_acct(); extern int sys_getegid(); extern int sys_geteuid(); extern int sys_signal(); extern int sys_getgid(); extern int sys_setgid(); extern int sys_brk(); extern int sys_prof(); extern int sys_times(); extern int sys_pipe(); extern int sys_dup(); extern int sys_rmdir(); extern int sys_mkdir(); extern int sys_rename(); extern int sys_kill(); extern int sys_sync(); extern int sys_ftime(); extern int sys_nice(); extern int sys_access(); extern int sys_gtty(); extern int sys_stty(); extern int sys_utime(); extern int sy s_pause(); extern int sys_fstat(); extern int sys_alarm(); extern int sys_ptrace(); extern int sys_stime(); extern int sys_getuid(); extern int sys_setuid(); extern int sys_umount(); extern int sys_mount(); extern int sys_getpid(); ৰ 96 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ #define __NR_open 5 #define __NR_write 4 #define __NR_read 3 #define __NR_fork 2 #define __NR_exit 1 #define __NR_setup 0 /* used only by init, to get system going */ ifdef __LIBRARY__# ۅń/include/unistd.h âuØdzÑ׏4ẝʳՈÏ ẝ«ΞŁǒɴՈɦ ϢȒ ń࣏ÛɥdzÑūϬ fork() ẝϔr4«]«ƞࠢՈ☺4 static inline _syscall0(int,fork) Ñr4Ñȭ fork() ϔ᫇Ϭ&ŷ ̴ńūϬQ¤Z _syscall? (int, ிඣϔ)4ńūϬՈūϬՈr ȅń ᫇ϬQȺẝǃǎ5 ¤ń âՈ Q঳ɥdz ń Linux [ &rū ǣń C ᪱ᣄǒɴிඣ᫇Ϭǜ ǣ5ƫ ᪂าrPǃǎ5 4 ʐ edx Ǹƌ„ɥdzÑrֲQż̶Γť 3 džϔ ᪂า eax & 2 ϢȒËᜐ int 0x80 ɥdzÑr4ΞȘƅdžϔ Ǯ◄Ⱥdžϔ ŭ. Û΢͑ ebx3ecx ிඣ᫇Ϭ«Ởẋ] ȐՈ£࿁ ǻǡū߾ƷּàՈËᜐϔՈ ü Ǹᡅ̿ūϬிඣ᫇ϬǮ◄ ΞŁūϬிඣ᫇ϬΞŁūϬிඣ᫇ϬΞŁūϬிඣ᫇ϬΞŁūϬிඣ᫇Ϭ 4 ẝ‡ϔՈǒɴἑO4rϘ̱ňிඣՈȈᾬ sys_setreuid,sys_setregid }; sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask, sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid, sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit, sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys, sys_rmdir, sys_dup, sys_pipe, sy s_times, sys_prof, sys_brk, sys_setgid, sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir, sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access, sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm, sys_chown, sys_break, sys_stat, sys_lseek , sys_getpid, sys_mount, sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod, sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, extern int sys_ setregid(); extern int sys_setreuid(); extern int sys_ssetmask(); extern int sys_sgetmask(); extern int sys_sigaction(); extern int sys_setsid(); extern int sys_getpgrp(); extern int sys_getppid(); ৰ 97 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ #define __NR_geteuid 49 #define __NR_signal 48 #define __NR_getgid 47 #define __NR_setgid 46 #define __NR_brk 45 #define __NR_prof44 #define __NR_times 43 #define __NR_pipe42 #define __NR_dup 41 #define __NR_rmdir 40 #define __NR_mkdir 39 #define __NR_rename 38 #define __NR_kill 37 #define __NR_sync 36 #define __NR_ftime 35 #define __NR_nice 34 #define __NR_access 33 #define __NR_gtty 32 #define __NR_stty 31 #define __NR_utime 30 #define __NR_pause 29 #define __NR_fstat28 #def ine __NR_alarm 27 #define __NR_ptrace 26 #define __NR_stime 25 #define __NR_getuid 24 #define __NR_setuid 23 #define __NR_umount 22 #define __NR_mount 21 #define __NR_getpid 20 #define __NR_lseek 19 #define __NR_stat 18 #define __NR_break 17 #define __NR_chown 16 #define __NR_chm od 15 #define __NR_mknod 14 #define __NR_time 13 #define __NR_chdir 12 #define __NR_execve 11 #define __NR_unlink 10 #define __NR_link 9 #define __NR_creat 8 #define __NR_waitpid 7 #define __NR_close 6 ৰ 98 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ \ (if (__res >= 0 : "0" (__NR_##name),"b" ((long)(a))); \ : "=a" (__res) \ __asm__ volatile ("int $0x80" \ long __res; \ { \ type name(atype a) \ #define _syscall1(type,name,atype,a) \ } return -1; \ errno = -__res; \ return (type) __res; \ if (__res >= 0) \ : "0" (__NR_##name)); \ : "=a" (__res) \ __asm__ volatile ("int $0x80" \ long __res; \ { \ type name(void) \ #define _syscall0(ty pe,name) \ #define __NR_setregid 71 #define __NR_setreuid 70 #define __NR_ssetmask 69 #define __NR_sgetmask 68 #define __NR_sigaction67 #define __NR_setsid 66 #define __NR_getpgrp 65 #define __NR_getppid 64 #define __NR_dup2 63 #defi ne __NR_ustat 62 #define __NR_chroot 61 #define __NR_umask 60 #define __NR_uname 59 #define __NR_ulimit 58 #define __NR_setpgid 57 #define __NR_mpx56 #define __NR_fcntl 55 #define __NR_ioctl 54 #define __NR_lock 53 #define __NR_phys 52 #define __NR_acct 51 #define __NR_getegid 50 ৰ 99 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;return –1 errno = -__res; return (int) __res; if (__res>=0) : “0” (__NR_fork)); : “=a ” (__res) __asm__ volatile (“int $0x80” long __res; { static inline int fork(void) ńේ᪕Q ේ᪕„Ćȭẝǃǎ5ẟᜐʉŌ ǣ4 ẜ«Ñȭ fork() ϔՈ᫇Ϭ& ŷ Ɵ ń᫇ϬQ¤Z static inline _syscall0(int,fork)7Ȓ4 #endif /* __LIBRARY__ */ } return -1; \ errno=-__res; \ return (type) __res; \ if (__res>=0) \ : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \ : "=a" (__res) \ __asm__ volatile ("int $0x80" \ long __res; \ { \ type name(atype a,btype b,ctype c) \ #define _syscall3(type,name,atype,a,btype,b,ctyp e,c) \ } return -1; \ errno = -__res; \ return (type) __res; \ if (__res >= 0) \ : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b))); \ : "=a" (__res) \ __asm__ volatile ("int $0x80" \ long __res; \ { \ type name(atype a,btyp e b) \ #define _syscall2(type,name,atype,a,btype,b) \ } return -1; \ errno = -__res; \ return (type) __res; \ ৰ 100 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ _syscall3(type,name,atype,a,btype,b,ctype,c) 4 «_syscall0(type,name) 3_syscall1(type,name,atype,a) 3_sy scall2(type,name,atype,a,btype,b)3 / ºẝₐdzÑ׏4 ń Linux0.11 ČƨȴƇՈϔ ż̶ɥ« 3 4ּàՈǃǎ5 ϬՈrȅPǎūϬǸƌ„ẟᜐdžϔČỖ ü&ńிඣ᫇ϬՈrȅĆǕϣȢʄḰdž4 ȭàՈ« 2 ɥ«᪸ fork() ȭàՈ£࿁ǻ« 24Ⱥ͢Ȩ΢4r EAX Ǹƌ„ ͼ͛ńிඣ᫇ ^_^ƣǡẜ«ūϬ˛ේ᪱ᣄẟᜐ 0x80 ) Ǯ«ȵញՈɨṇΙ໐>4ńẝₐ__NR_fork } ৰ 101 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ .align 2  ǎr)Ո̠ˊ࣏Û« timer_interrupt ƷĹz/kernel /sytem_call.s ˑàǎr)ˑàǎr)ˑàǎr)ˑàǎr) ϢȒȺ LATCH ễ͑4⏅ƌ„4 #define LATCH (1193180/HZ) ń/kernel/sched.c â #define HZ 100 ń/include/kernel/sched.h â ⏅ƌ„ՈȨ᪂& 1193180/100 ɥdzÑr4Linux0.11 «ẝ4ɆՈ „Ոr⍣࿍ΞEɋ« 1193180Hz 4ȭz 10ms ՈɬƛȭàՈEɋ« 100Hz ü ǸȺ Ǎǻ“ϣ) ü Ǹᡅ̿᪂ǎǎr„Ո)rⒸⒸ╘ Ǯ◄᪂ǎ⏅ƌ„ՈȨ4ǎr ń3ǻ1ňµś[Ɵ⏅ƌ„ՈȨńr⍣࿍Ξ Ոȥ¬[λႷ0Ոr ȅĆǕϦP 2. rⒸⒸ╘Ո᪂ǎrⒸⒸ╘Ո᪂ǎrⒸⒸ╘Ո᪂ǎrⒸⒸ╘Ո᪂ǎ ǎȨ4 ᪂ ⏅ƌ„ 2 Ϭz Ð̌„ǕϦ̌⚷ ŌŜ& 0x424üǸẝₐ«ȕ 0x40⏅ƌ„ 0 ⏅ƌ„ 1 Ϭz ɬƛ ɳՈȕ DMA ǕễϔǒǍǻ Ƈƌʔ„;,Ϭ ŌŜ& 0x41 4⏅ƌ„ 0 ϬzමĈிඣr ⍣ŌŜ& 0x40ǎr„ƅ 3 ⏅ƌ„ ÂØ Ȉƅ͢ „1. ǎr„⏅ƌ„ǎr„⏅ƌ„ǎr„⏅ƌ„ǎr„⏅ƌ Š᪸Š᪸Š᪸Š᪸ outb(inb_p(0x21)&~0x01,0x21); // ·Ōȭǎr„Ոʃᐁ OCW1 Ո M0 ű►ᩭǎr„Ōϧ1ň set_intr_gate(0x20,&timer_interr upt); // ᪂าǎr„Ո)ˑà࣏Û)ȕₓ outb(LATCH >> 8 , 0x40); /* MSB */ outb_p(LATCH & 0xff , 0x40); /* LSB */ // ᪂าǎr„Ո)Ⓒ╘& 10ms 100HZ outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ // 8253 ȋ:ƋǸƌ„ՈŌŜ« 0x43 // ᪂า 8253 Ոȋ:Ƌū̠͢z 3 ǻ1ňµś ̴ūϬ LSB ȒūϬ MSB ේ΅Ở἗& 0 Ξ[ۅǎr„Ո!ϧĚ1ň«ń sched_init()(/kernel/sched.c) ǀtՈ4Ï 0x204 »ۅ0x20 ɥ«᪸ǎr„Ո)ȕₓ »ۅüǸẝrȅ IR0 ȭàՈ)ȕₓ ń᩶ǎr„Ո!ϧĚ7Q u̿͹᪸P[ ńLinuxȳ¬Ոrȅ>ඓȺ ICW2 ᪂า& 0x20 ǎr„Ո!ϧĚǎr„Ո!ϧĚǎr„Ո!ϧĚǎr„Ո!ϧĚ „ৰIতৰIতৰIতৰIত ǎr„ǎr„ǎr„ǎr ৰ 102 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ } (void do_timer(long cpl  ńrⒸċϬɱ7Qś]ĆᩭϦ CPU Ո4ƷĹz/kernel/sched.h ϔdzÑ׏Ϧǡ Linux0.11 «☢ĆŤśՈ ȭz>ඓŤƅ CPU Ոẟ࣏ ┨☢Ǖϣ)Ȫ 4ºẝ܄r £࿁ ՈȖ ẝϔ«ǒɴ ϔ do_timer «Ëᜐǎr)Ոʴ ȏᾬ ϔϔϔϔ do_timer: 4ȭzr⍣)dzÑūϬ 00 1 00 000(xẟ:) ẟᜐ̩Ĺ4 & 0x20 Ɵ)ǕϣȒ ◄ᡅ̩Ĺ ISR Ĺ ΞȘ«¯¬̩ĹՈ᪡ɥȑ/ ᪂า ʁÐƋ OCW2 ŌŜ Š͟z͟z͟z͟z EOI Ո᪸ŠՈ᪸ŠՈ᪸ŠՈ᪸ jmp ret_from_sys_call addl $4,%esp # task switching to accounting ... call _do_timer # 'do_timer(long CPL)' does everything from pushl %eax andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor) movl CS(%esp),%eax // do_timer() Ոdžϔ ň&ϔ ࡿϦϬ›Ոƿ└ȨCPL // rȅϵܰâƏ͑ʄ4ºẝȨ ɉǸƌ„ՈȨ CS Ǹƌ„ՈȨ«ń)ǕϣՈۅ// ºிඣʄǣ4ƟQ࣏ÛՈÏ outb %al,$0x20 movb $0x20,%al # EOI to interrupt controller #1 // I SR Ĺ ◄ᡅ¯¬᪂า4 // ϵz Linux ńẟᜐிඣ!ϧĚՈrȅȺிඣ᪂า&☢ EOI 5ś &r࿁̻̩Ĺ incl _jiffies // ʺ¤ƠਘϔՈȨ mov %ax,%fs movl $0x17,%eax // ᩭ FS ūȕϬ›Ոϔǒɉ mov %ax,%es mov %ax,%ds movl $0x10,%eax // ᩭ DS ES ūȕிඣՈϔǒɉ pushl %eax pushl %ebx # is saved as we use that in ret_sys_call pushl %ecx # save those across function calls. %ebx pushl %edx # we save %eax,%ecx,%edx as gcc doesn't push %fs push %es # into them. %fs is used by _system_call push %ds # save ds,es and put kernel data space _timer_interrupt: ৰ 103 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;()schedule // ẟ࣏᫇òŌϧr if (!cpl) return; // ȭzிඣ൫Ո࣏Û«]Ćẟᜐிඣ᫇òՈ ẝɥ«ƣ᪱ current ->counter=0; if (( -- current ->counter)>0) return; // ẟ࣏᫇òr ɥᡅẟᜐ// ΞȘǕɴϬ›ՈrⒸċ̵ƅϬɱ ɥᩭƷණනẔᜐ4Ȫ do_floppy_timer(); if (current_DOR & 0xf0) // Ṉ̀ňȐḳȥƅ͟ } } (fn)(); next_timer = next_timer ->next; next_timer ->fn = NULL; fn = next_timer ->fn; void (*fn)(void); while (next_timer && next_timer ->jiffies <= 0) { next_timer ->jiffies --; if (next_timer) { „// ̠ˊϬ›Ոǎr current ->stime++; else current ->utime++; if (cpl) // ʵǒ࣏ÛՈƿ└Ȩǡ()ֲQ«ńϬ›ɍẜ«ிඣɍ sysbeepstop(); if (! -- beepcount) if (beepcount) extern void sysbeepstop(void); extern int beepcount; // ̠ˊȐÐ̌„ּ͟Ո̱ň ৰ 104 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;(void (*sa_restorer)(void int sa_flags; sigset_t sa_mask; Ởẋ᪂าẝȨ ǡΟǎ«ʃᐁẜ«ẟᜐ΀ͳ4// ¢ɦ // ǻ«Ō΢Ո4IJ«ƟẝǍǻ̠ˊ࣏ÛẔᜐՈrȅ ΞȘȐPǍǻ͹Ƶǡrɚ4 // ẝₐ4ǒ┉ZƷỞ„±±ȺႮ=ʃᐁr ü&ẝǍǻႮᵯ4ǡr ẟ࣏ȭẝǍ // ƟPǍǻ̠ˊ1ňr dz࿁◄ᡅʃᐁ,ՈǍǻ4ẝ‡◄ᡅʃᐁՈǍǻǍʻƌ΢ń void (*sa_handler)(int); ּƟz)Ɖ¥࣏Û // Ǎǻ̠ˊ࣏Ûū⍌ϔū⍌ struct sigaction { :::::::: typedef unsigned int sigset_t; /* 32 bits */ // Ʒ͢ǒ«P 32 ĹՈĹĚ 4 ńÑȒՈ,Čƨ Ĺϔʺ̶ ǎ5Ո 5śKǜĚr4 // ǎ5rP,ିƧǍǻ▊  ǎ5΢ń/include/kernel/signal.h ń)ȕₓᜬƌ΢Ո«)ȕₓȳẴ৪ ẝ ₐƌ΢Ո«^Ǎǻ̠ˊƅ͟ՈǍʻ4ƷՈ }; :::::::: long blocked; /* bitmap of masked signals */ „// ǍǻՈʃᐁĹĚ ɥʻ)ʃᐁǸƌ struct sigaction sigaction[32]; // ɥࢴƷ«Ǎǻȕₓᜬȫ // ǍǻՈËᜐϔඈ Ιʻ«)ȕₓᜬ ]ȐՈǍǻȭàẝₐ]ȐՈËᜐ඗Ȁ4ÑȒ long signal; // ƷՈৰ n ĹȭàǍǻ n // Ʒ«P 32 ĹՈĹĚ ɣPĹȭà؄P࢑ǍǻିƧ4ɥΙʻ«) ᪻˖Ǹƌ„Pʳ4 :::::::: struct task_struct { ʻ«ẟ࣏Ո໷Ʊ4ń Ǎǻ«Ϭzńẟ࣏ⒸẟᜐỞᩳϬՈ ü ǸƷà᪩΢4ẟ࣏ň&ẟ࣏ՈPʒɳ ɥΙ ǍǻՈȳẴǍǻՈȳẴǍǻՈȳẴǍǻՈȳẴ ̴׏׏ń Li nux0.11 Ǎǻ«ΞŁǎ5Ո4 ]ȐՈǍǻƅּàՈ̠ˊϔ4)ƅʃᐁĹ ǍǻKƅ4 ń᩶ᢧΞŁūϬǍǻ 7Q ּàՈƉ¥࣏ÛՈ͑ǧ4ȭzǍǻK«PʳՈ ] ȐՈǍǻȭà]ȐՈǍǻିƧ ໐ȭà ּʻr4 ń)̠ˊ ◄ᡅƅ)ȕₓᜬ ƅ)ǻ4Ởẋ)ǻdzѺ)ȕₓᜬâ4 ἗¬ 4rȅĆΚ4Ǎǻ4ẝ ɥȐ) ☢„Ո ک[:«ŎǹՈ ɥ«᪸Pẟ࣏ńËᜐՈrȅ ǍǻdzÑ᪸« ϵ̱ňிඣȴƇՈḳ) «Ϭǡ ńẟ࣏7ⒸņএỞᩳϬՈ4ẝ࢑Ởᩳƶ ৰŅতৰŅতৰŅতৰŅত Ǎǻ̠ˊǍǻ̠ˊǍǻ̠ˊǍǻ̠ˊ ৰ 105 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ <ŁǍǻ4ȭzɣPǍǻ̠ˊϔՈǩɀ῁« 04ிඣǎ5rǩɀ/>ۅ!ϧẟ࣏r INIT_TASK ń INIT_TASK ƅẝ4PɉÏ Ǎǻ«ϵẟ࣏ǡමĈՈ ¤ƅՈẟ࣏῁«Ởẋ̩:úẟ࣏ǡ “ϣՈ4 żƣϧՈẟ࣏ɥ« ǍǻՈ!ϧĚǍǻՈ!ϧĚǍǻՈ!ϧĚǍǻՈ!ϧĚ ᫇Ϭ4Ⱥẝிඣ᫇Ϭ7Q uẜ«̴ᫌᫌ!ϧĚ⒲L4 ǻńūϬ 7Q◄ᡅ᪂า^ǍǻȭàՈ̠ˊ࣏Û4&rẝ̱ň Linux ிඣ ȴƇrிඣ ^)P ʳ &r ࿁̻ ˑà)◄ᡅń)ȕₓᜬ᪂า)Ɖ¥࣏ÛՈ͑ǧŌŜ4Ǎ ǍǻՈ᪂าǍǻՈ᪂าǍǻՈ᪂าǍǻՈ᪂า #define SIGTTOU 22 #define SIGTTIN 21 #define SIGTSTP 20 #define SIGSTOP 19 #define SIGCONT 18 #define SIGCHLD 17 #define SIGSTKFLT 16 #define SIGTERM 15 #define SIGALRM 14 #define SIGPIPE 13 #define SIGUSR2 12 #define SIGSEGV 11 #define SIGUSR1 10 #define SIGKILL 9 #define SIGFPE 8 #define SIGUN USED 7 #define SIGIOT 6 #define SIGABRT 6 #define SIGTRAP 5 #define SIGILL 4 #define SIGQUIT 3 #define SIGINT 2 #define SIGHUP 1  ń Linux0.11 ᪂าr 22 ࢑Ǎǻ ͢ǎ5Ĺz/include/kernel/signal.h ǍǻିƧǍǻିƧǍǻିƧǍǻିƧ }; ৰ 106 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ (struct sigaction * oldaction int sys_sigaction(int signum, const struct sigaction * action, // ljƌƣǡՈǍǻËᜐ඗Ȁ4 // džϔ signum «ǍǻିƧ action «,ՈǍǻËᜐ඗ȀoldactionΞ Ș]ाɥϬǡ Ʒ«ỞẋǍǻՈËᜐ඗Ȁǡ᪂าՈ4 sys_sigaction ^ sys_signal ǔʻ Ǯ« sys_sigaction &᪂าȴƇrŰ̶ՈႮϵò ü& ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_sigaction } return handler; current ->sigaction[signum -1] = tmp; // Ⴎ=ՈǍǻƉ¥࣏Û4 // Ⱥ,ՈǍǻ̠ˊ඗Ȁljƌ4ƟQẝẟ࣏ՈǍǻȕₓᜬ4ºẝdzᢅẟ࣏ẝ࿁᪂า handler = (long) current ->sigaction[signum -1].sa_handler; // ᪂าẘúȨ&ƣǍǻ̠ˊ࣏ÛՈǩɀ tmp.sa_restorer = (void (*)(void)) restorer; tmp.sa_flags = SA_ONESHOT | SA_NOMASK; // ᪂าǍǻ̠ˊ5śʃȣ&Ǎǻ±±ūϬPƵ ]ʃᐁǍǻƨᵯ tmp.sa_mask = 0; // ńǍǻƉ¥࣏Û̠ˊ]͹ƵʃᐁçŁǍǻĉŐႮ= tmp.sa_handler = (void (*)(int)) handler; // ᪂าǩɀ return -1; if (signum<1 || signum>32 || signum==SIGKILL) // ()«Ȫ&ƅάՈିƧÂ]࿁« SIGKILL struct sigaction tmp; { int sys_signal(int signum, lo ng handler, long restorer) // džϔsignum «ǍǻିƧhandler «ϔǩɀ͢ǒɥ«Ⱥϔū⍌Ḱdž&ϘƧ ᩨȨ 04ڌ&̩ ᪂าǍǻƉ¥࣏ÛՈ ǩɀ ƟƉ¥࣏ÛËᜐ 7ȒĆȺǍǻՈ ǩɀʮ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_signal ᩨՈ̱ň4ڌȘǡrǍǻிඣĆūϬ & 0 ᜬ߾ẜ̵ ƅȉǛ4çŁǍǻ4ẝ ʳńPẟ̵࣏ƅ᪂า Ⴎ= ՈǍǻƉ¥࣏ÛՈr ȅ Ξ ȭzÑȒ᫇Ϭ fork Ոrȅ Ćණãú ẟ࣏Ǎǻȕₓᜬʐ ʃᐁĹ4IJ«᪂าƄẟ࣏Ո signal ǍǻՈ̱ň4 ᩨՈ̱ň4Ξ Șǩɀ& 1 ɥĆ ɉЩẝڌẝɥ᪸ŠΞȘ᪂า ǩɀ& 0 ẝǍǻ ɥËᜐ #define SIG_IGN ((void (*)(int))1) /* ignore signal */ #define SIG_DFL ((void (*)(int))0) /* default signal handling */ ৰ 107 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;((verify_area(to, sizeof(struct sigaction int i; { static inline void save_old(char * from,char * to) ẝ‡1ňĆƅϔ verify_area , Ĺz, ǡɆ4 ɥĆƿϷ᪻P)ाⒸ4ẝϔ ńËᜐQĆ̼ɀᡅ΅͑ՈŌŜाⒸ«Ȫᱷ̻ Ȫ 2. ϔϔϔϔ save_old: } *(to++) = get_fs_byte(from++);  // ẝǃǎ5Ĺz include/asm/segment.h for (i=0 ; i< sizeof(struct sigaction) ; i++) int i; { static in line void get_new(char * from,char * to) Ǹƌ„4ǔ੄ř]ɆŰ̶Ո᪸Šr4 ϬzºϬ› ľǚǣǍǻËᜐ඗Ȁ Ϭ›Ոɉọō Ƅńிඣ᫇ϬՈrȅljƌ4r fs  1. ϔϔϔϔ get_new Šṉ­ϔ᪸Šṉ­ϔ᪸Šṉ­ϔ᪸Šṉ­ϔ᪸ } return 0; current ->sigaction[signum -1].sa_mask |= (1<<(signum -1)); else current ->sigaction[signum -1].sa_mask = 0; if (current ->sigaction[signum -1].sa_flags & SA_NOMASK) // ()«Ȫ̭᩼ǍǻႮᵯՈ΀ͳ ϢȒΟǎΞŁ᪂าʃᐁĹ save_old((char *) &tmp,(char *) oldaction); if (oldaction) // ΞȘ oldaction ]ाɥȺƣËᜐ඗Ȁljƌẟƿ4ūϬϔՈƣüȐZ (char *) (signum -1+current ->sigaction)); get_new((char *) action, // ¤ÑȺּ͟Ո̱ň΢4ϔr4 // ϔ«ü& ẝ ,ՈǍǻËᜐ඗ȀPǎ«ĹzϬ›ľՈ ᡅūϬϬ›ɍՈọōƄ4 // Ⱥ,ՈËᜐ඗Ȁśᯡ4ẟ࣏ՈǍǻȕₓᜬ4ẝₐ̵ƅָȉ̩: ໐«ūϬrP tmp = current ->sigaction[signum -1]; // ljƌƣǍǻËᜐ඗Ȁ return -1; if (signum<1 || signum>32 || signum==SIGKILL) // ẜ«̴()«Ȫ&ƅάՈିƧÂ]࿁« SIGKILL struct sigaction tmp; { ৰ 108 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ (static inline int send_sig(long sig,struct task_struct * p,int priv // džϔsig «ǍǻିƧp ūȕȉΚǍǻՈẟ࣏priv ƿ└ ϔ send_sig ]«ிඣ᫇Ϭ  é4ń Linux0.11  dzÑ ׏4Ëᜐr Ǖễ Ǎǻ̱ňՈ῁ń â kernel/exit.c 4ͼ͛ ᡅ̼ɡP[ǕễǍǻՈẟ࣏Ոƿ└ ẝ Ȑ«ிඣɍẜϬ›ɍ]Ȑ4ẝ ₐՈƿ└ūՈ« Կ┊ ᵯ ◄ᡅ᪂าּà ẟ࣏Ո8Ǎǻ ᪻˖Ǹ ƌ„ 9signal ɥdzÑr4&rܲljƽ͔ ńČỖՈr ȅ◄ 4 Ǯ ^)Ɇିɨ ǍǻՈČỖà᪩«Pâ ǔ੄řՈw̑ń Linux0.11 «ẝ ʳՈ ǍǻՈČỖǍǻՈČỖǍǻՈČỖǍǻՈČỖ } return current ->blocked; { int sys_sgetmask() Ո8ǍǻʃᐁǸƌ„9block 4 ȴƇrȭ block ᪂าՈ̱ň Ȑr ẜᡅƅ ௦ǚՈ4ẝிඣ᫇Ϭ ɥ«ϬzẘúƟQẟ࣏ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_sgetmask } return old; „// ȺƣǡՈʃᐁĹĚẘú Ȑʳ«ūϬ eax Ǹƌ current ->blocked = newmask & ~(1<<(SIGKILL -1)); // ʃᐁƿǭ4 // ┨rǍǻ SIGKILL, ¤ƅǍǻϬ› ῁dzÑʃᐁǭ4ü Ǹ\᩾ ΞŁ ῁ᡅȺȭ SIGKILL Ո int old=current ->blocked; { int sys_ssetmask(int newmask) z Ǎ ǻ Ո Č Ỗ Ȓ ☦· එ 4 ȭ z blocked Ո ᪂ า ɥ«ūϬẝிඣ᫇ϬǡǒɴՈ4 8Ǹƌ„ 98Ǎǻ᪻˖Ǹ ƌ„9signal ʐ8ǍǻʃᐁǸƌ„9blocked 4ȭz signal Ո᪂า ʒ  Q ிඣ᫇Ϭ«Ϭǡ᪂าǍǻՈËᜐ඗ȀՈ IJ«ǍǻՈˑàƶ :ẜȴ 4ẋ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_ssetmask } } to++; from++; put_fs_byte(*from,to); for (i=0 ; i< sizeof(struct sigaction) ; i++) { ৰ 109 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ andl %ebx,%ecx notl %ecx // ቻǚ̵ƅᝯʃᐁՈǍǻ ΢͑ ecx movl blocked(%eax),%ecx // ቻǚƟQẟ࣏ՈǍǻʃᐁǸƌ„΢͑ ecx movl signal(%eax),%ebx // ቻǚƟQẟ࣏ՈǍǻ᪻˖Ǹƌ„΢͑ ebx jne 3f cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? jne 3f cmpw $0x0f,CS(%esp) # was old code segment supervisor ? ɉʐϔǒɉ üǸᡅ()ۅ// ϵzǍǻƉ¥ϔ◄ᡅūϬƣǡẟ࣏ՈÏ je 3f cmpl _task,%eax // ΞȘǕɴƟQẟ࣏«!ϧẟ࣏ɥ]ËᜐǍǻ̠ˊ ü&!ϧẟ࣏«]ĆȉΚǍǻՈ movl _current,%eax # task[0] cannot have signals // ȺƟQẟ࣏Ոū⍌΢͑ eax ret_from_sys_call: &Ëᜐ⓺ɉβ̣džϔ4 ᪊4ńẝP⓺ɉȺĆʵǒǍǻ ʃᐁǸƌ„ǡ()« Ȫ◄ᡅּàǍǻ ᪻˖ ک‡^Ǎǻƅ͟Ո ǍǻËᜐՈ8̠ˊ⓺ɉĹzிඣ᫇ϬՈẘú⓺ɉ Ɵru̵ƅ·එ «ü&͢5ǎ4P 8̠ˊ⓺ɉ8̠ˊ⓺ɉ8̠ˊ⓺ɉ8̠ˊ⓺ɉ ɉ8̠ˊ⓺ɉʐËᜐ⓺ɉ4 & ⓺ Ǯƅńºிඣ᫇ϬẘúՈr ȅ±Ćƿ̠ˊǍǻּà࣏Û4ǍǻՈËᜐdzÑ ǍǻՈËᜐǍǻՈËᜐǍǻՈËᜐǍǻՈËᜐ } return 0; return -EPERM; else p->signal |= (1<<(sig -1)); if (priv || (current ->euid==p ->euid) || suser()) // // #define suser() (current->euid == 0) // ɥ᪂า signal 4ǃǎ5 suer() Ĺz include/kernel/kernel.h 4 ›// ΞȘƅƿǕễǍǻz້ᡅȉΚǍǻՈẟ࣏^ƟQẟ࣏Ȑ൫z້ƟQẟ࣏«᱉൫Ϭ return -EINVAL; if (!p || sig<1 || sig>32) // ()Ǎǻ«Ȫƅά ÑǎᡅȉǛǍǻՈẟ࣏rȅƌń { ৰ 110 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;((do_exit(1<<(signr -1 else return; if (signr==SIGCHLD) if (!sa_handler) { ᩨ࣏Ûڌ// ΞȘǩɀ« 0 ᜬ߾ŌϧËᜐ return; if (sa_handler==1) // ΞȘǩɀ« 1 ᜬ߾ɉЩǍǻՈ̠ˊ sa_handler = (unsigned long) sa ->sa_handler; // ºǍǻËᜐ඗ȀቻǚǍǻ̠ˊ࣏ÛՈǩɀ unsigned long * tmp_esp; int longs; struct sigaction * sa = current ->sigaction + signr - 1; // ºǍǻȕₓᜬቻǚǍǻËᜐ඗Ȁ long old_eip=eip; unsigned long sa_handler; { unsigned long * esp, long ss) long eip, long cs, long eflags, long fs, long es, long ds, void do_signal(long signr,long eax, long ebx, long ecx, long edx, ńǍǻՈËᜐ⓺ɉż'ᡅՈ1ň&Ǎǻ̠ˊ࣏Û᪂ǎּàՈẔᜐɳʟ4 ǍǻՈËᜐǍǻՈËᜐǍǻՈËᜐǍǻՈËᜐ iret :::::::: popl %eax call _do_signal pushl %ecx // ȺǍǻିƧň&džϔČỖඝϔ do_signal incl %ecx ¤ 1  // ϵzǍǻିƧ«º 1 ŌϧᩥϔՈ üǸᡅȺȻࢿₓń ecx movl %ebx,signal(%eax) „// ljƌǍǻ᪻˖Ǹƌ btrl %ecx,%ebx // Pǹ«̩ĹּàՈǍǻĹ // Ⱥ ebx Ȼࢿₓ& ecx Ոű 0 ebx ƌ΢Ո«ƟQẟ࣏Ǎǻ᪻˖Ǹƌ„ üǸẝ je 3f // ΞȘ̵ƅâ4᪸Š̵ƅ◄ᡅ̠ˊǍǻ bsfl %ecx,%ecx ΢͑ ecx 31 // º ecx Ոৰ 0 Ĺȕৰ 31 ĹÏȳ ȯ âৰP& 1 ՈĹՈȻࢿȨ 0 ৰ 111 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;current ->blo cked |= sa ->sa_mask „// ΞȘ sa_mask ᪂ǎrȭ Ⴎᵯʃᐁ ẝPǹɥĆ Ⱥẝʃᐁ᪂า4ǍǻʃᐁǸƌ put_fs_long(old_eip,tmp_esp++); put_fs_long(eflags,tmp_esp++); put_fs_long(edx,tmp_esp++); put_fs_long(ecx,tmp_esp++); put_fs_long(eax,tmp_esp++); put_fs_long(current ->blocked,tmp_esp++); if (!(sa ->sa_flags & SA_NOMAS K)) put_fs_long(signr,tmp_esp++); put_fs_long((long) sa ->sa_restorer,tmp_esp++); // &ǍǻƉ¥࣏Û᪂ǎʄՈͱǭ tmp_esp=esp; verify_area(esp,longs*4); // ቻǚᱷ̻ՈाⒸ *(&esp) -= longs; longs = (sa ->sa_flags & SA_NOMASK)?7:8; // ᪂ǎǍǻ̠ˊ࣏ÛȺᡅūϬՈʄՈ⑃ò *(&eip) = sa_handler; // ɀɥ࿁̻ūிඣ᫇ϬẘúȒËᜐǍǻ̠ˊ࣏Û // &eip ȭàՈ«ʄிඣ᫇ϬȺᡅẘúËᜐՈŌŜ ȺẝȨ᪂&Ǎǻ̠ˊ࣏ÛՈǩ sa ->sa_handler = NULL; if (sa ->sa_flags & SA_ONESHOT) // ΞȘËᜐ඗ȀՈʃȣƅ SA_ONESHOT ᜬ߾ẝǍǻ̠ˊ࣏Û±ËᜐPƵ } ৰ 112 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;long last_pid=0 ‑Ոẟ࣏ǻ // last_pid «P͔ɴǜₓϬzljƌż, ϔϔϔϔ int find_empty_process(void) 1: ret addl $20,%esp // ẝǒ┉Z«PµŃƅʄՈẋ࣏ ü&]◄ᡅʮ̩ẝ‡Ǹƌ„¤Ñ±ūϬr¤ͩ call _copy_process pushl %eax pushl %ebp pushl %edi pushl %esi push %gs // džϔ4ϢȒ᫇Ϭ copy_process() ẟᜐẟ࣏Ոśᯡ // ȺǸƌ„ gs3esi 3edi3ebp ʐ eax ՈȨº߾ՈƏ͑ʄϬň copy_process() ϔՈ js 1f testl %eax,%eax call _find_empty_process // â4PdzϬाⒸ ȺाⒸՈ௦šǻẘú4ϔ«Ởẋ eax ǡČỖẘúȨՈ4 _sys_fork: .align 2  // «ǎ5ń/kernel /fork.c ᫇Ϭ C ϔ copy_process( )̩:ẟ࣏4ẝ ₐՈ C ϔ ῁// ç¥ϔඈ>ƍ,ָȉ ỄϦ4 Ȫ ᪸ŠֲQ// Ŋ̴᫇Ϭ C ϔ find_empty_process() ǚ ǣPẟ࣏ǻ pid 4ᆩẘúᯣϔ ाⒶՈẟ࣏ id ǻ ϢȒ̩:úẟ࣏4 sys_call_table []( Ĺz include/linux/sys.h ) dzÑ׏4ƷȭàՈ«ϔ sys_fork 4Ʒ ̴ቻǚP ඣ ᫇ Ϭ Ո £ ࿁ ǻΟǎ Ո 4 ȭ z fork ǡ ᪸ Ʒ ȭ à Ո £ ࿁ ǻ « 24 º ி ඣ ᫇ Ϭ ᜬ ń)ிඣ ᩶4rPிඣ᫇Ϭ ẟ͑⓺ɉʐỄϦ⓺ɉ Ⴗzிඣ᫇ϬËᜐ⓺ɉ«ϵி ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ fork Ϧǡr4 úՈrȅĆ&úẟ࣏ʐƄẟ࣏᪂ǎ]ȐՈẘúȨ4ỞẋẝẘúȨɥdzÑľ Ϧẝ࣏Û« ϵúẟ࣏Ẕᜐẜ«ϵƄẟ࣏Ẕᜐ fork ńẘ ͝ȐẔᜐP࣏Û4&r࿁̻ľ ņȒ Ƅẟ࣏^úẟ࣏͝— ȐPųͱƌाⒸ ɥ«᪸ Ƅẟ࣏^úẟ࣏Ϭ fork ǀtՈ4ń Ởẋ̩:cẟ࣏“ϣՈ4ü ǸɥȺ,ẟ࣏ǯƄẟ࣏ cẟ࣏ǯúẟ࣏4ẝ̱ň«ϵிඣ᫇ ੄řՈ᪸ ,ẟ࣏ɥ«Q☦᩶rὧ4̶^ẟ࣏ƅ͟Ո̱ň IJ«ẟ࣏ū ɚ4“ϣՈ ɦ ņņẟ࣏Ոņẟ࣏Ոņẟ࣏ՈৰŅPতৰŅPতৰŅPতৰŅPত ẟ࣏Ո ৰ 113 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;struct file *f int i; struct task_struct *p; { long eip,long cs,long eflags,long esp,long ss) long fs,long es,long ds, long ebx,long ecx,long edx, int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, */ * also copies the data segment in it's entirety. * information (task[nr]) and sets up the necessary registers. It * Ok, this is the main fork -routine. It copies the system process /* ẟ࣏„ᢈǜₓՈ᪂ǎẟ࣏„ᢈǜₓՈ᪂ǎẟ࣏„ᢈǜₓՈ᪂ǎẟ࣏„ᢈǜₓՈ᪂ǎ ‑ͱƌ 3â᪂ǎǎ͢Ʒ4 ẟ࣏„ᢈǜₓՈ᪂ǎ3TSS Ո᪂า3 ᢧt 5 ᾬ dzÑȺ͢ ẝϔdzÑ᪸« fork Ոʴ ȏ ̩:úẟ࣏Ո̱ňɥ«ϵƷǀtՈ4 ŭ+ ËᜐՈ.Û ϔϔϔϔ int copy_process(… ..) } return -EAGAIN; return i; if (!task[i]) for(i=1 ; ipid == last_pid) goto repeat; for(i=0 ; iඓ // ɡâ̵ƅūϬՈ PID Ո5ͩ«̴“ϣP last_pid ϢȒʀ௦ç¥ᜬ ȺֲQ // last_pid «º 0 ŌϧᩥϔƉƵỖʺ Ẃ4Z└Ȓₑ,º 1 Ōϧᩥϔ4 int i; { int find_empty_process(void) // Ⱥ᪩ाⒸȭàՈ௦šǻẘú ΞȘ̵ƅâ4ाⒸɥẘú-EAGAIN(-11) // ̴â4PֲQ̵ƅūϬՈ PID ϢȒç¥ᜬâ4PֲQ̵ƅūϬՈाⒸ 444444444444444444444444 ৰ 114 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;p->tss.eax = 0 „// ᪂าȭƄẟ࣏Ëᜐ fork ϔȒՈẘúȨ ிඣ᫇ϬẘúȨ«ń eax Ǹƌ p->tss.eflags = eflags; p->tss.eip = eip; // ᪂าƄẟ࣏ẔᜐrՈ IP Ʒ^úẟ࣏᫇Ϭிඣ᫇ϬrՈ IP ּȐ p->tss.ss0 = 0x10; p->tss.esp0 = PAGE_SIZE + (long) p; PCB ඗Ȁ ƦūϬ ிඣʄ // ᪂าிඣʄՈŌŜ ிඣʄ^ PCB ĹzȐP) ʄá«)*ΞĚ p->tss.back_link = 0; // ᪂า,ẟ࣏Ո TSS ͱǭ TSS Ո᪂าՈ᪂าՈ᪂าՈ᪂า p->start_time = jiffies; // ᪂าẟ࣏ՈŌϧrⒸ&ƟQՈƠਘϔ p->cutime = p->cstime = 0; p->utime = p->stime = 0; p->leader = 0; /* process leadership doesn't inherit */ p->alarm = 0; p->signal = 0; p->counter = p->priority; // ᩭƄẟ࣏^úẟ࣏ՈĄ̴൫ּȐ p->father = current ->pid; // ᪂าƄẟ࣏Ոúẟ࣏ ID p->pid = last_pid; // ᪂าƄẟ࣏Ո ID p->state = TASK_UNINTERRU PTIBLE; // ,ẟ࣏Ոźɍ«]dz)Ո਍Ǒźɍ *p = *current; /* NOTE! this doesn't copy the supervisor stack */ // ϵzƟQՈẟ࣏ɥ«úẟ࣏ ¤Ñẝₐ«ȭúẟ࣏ՈǀϘśᯡ task[nr] = p; // Ⱥ,ẟ࣏ाⒸՈŊŌŜᰏඝç¥ᜬ return -EAGAIN; if (!p) ۅ‑͍ᯩɥẘú⏝᪳ // ΞȘ p = (struc t task_struct *) get_free_page(); ‑P)ͱƌाⒸ // &,Ոẟ࣏ ৰ 115 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ⑃└// ǚɴᾬȳẴ৪ᜬϔǒɉȳẴ৪-ɉ code_limit=get_limit(0x0f); ɉȳẴ৪-ɉ└⑃ۅ// ǚɴᾬȳẴ৪ᜬÏ unsigned long old_code_base,new_code_base,code_limit; unsigned long old_data_base,new_data_base,data_limit; { int copy_mem(int nr,struct task_struct * p) // nr &,ç¥ǻp «,ç¥ϔǒ඗ȀՈū⍌ ʐϔǒɉȖŜ3└⑃Â̩:)ᜬۅ// ᪂า,ç¥ՈÏ ‑ϔ copy_mem ‑ϔͱƌ ‑ϔͱƌ ‑ϔͱƌ ͱƌ ẝₐ᫇ϬrPϔ copy_mem 4 } return -EAGAIN; free_page((long) p); task[nr] = NULL; if (copy_mem(nr,p)) { ɉۅ// &Ƅẟ࣏᪂าÏ ‑ͱƌ ‑ͱƌ ‑ͱƌ ‑ͱƌ __asm__("clts ; fnsave %0"::"m" (p ->tss.i387)); if (last_task_used_math == current) // ΞȘƟQç¥ūϬrœ̠ˊ„ ɥljƌ͢Z[ p->tss.trace_bitmap = 0x80000000; p->tss.ldt = _LDT(nr); // ᪂า,ẟ࣏Ո LDT ŌŜ p->tss.gs = gs & 0xffff; p->tss.fs = fs & 0xffff; p->tss.ds = ds & 0xffff; p->tss.ss = ss & 0xffff; p->tss.cs = cs & 0xffff; p->tss.es = es & 0xffff; // ɉǸƌ„ǮƅĺƋᅆƅά p->tss.edi = edi; p->tss.esi = esi; p->tss.ebp = ebp; p->tss.esp = esp; p->tss.ebx = ebx; p->tss.edx = edx; p->tss.ecx = ecx; ৰ 116 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ « 0x174 ɉ« 0x0f ϔǒɉǣọōƄۅńẝₐü&«Ϭ›ɍọōɴᾬȳẴ৪ ¤ÑÏ ᪩ūÐǮƽˑ ZF ʃȣ4 ͼ͛ Ξ ȘūÐūϬ 16 Ḻ́ňϔ ὧ4ǮƅɉА└Ոĺ 16 Ĺᝯញ͑4 OPRD1 4 12 Ĺ ाϦՈĺĹ͔ᾬʇt 14 ΞȘȳẴ৪ՈА└Ƌ ɉÑ 4K Ƌᅆ&řĹ(G=1) ὧ4ញ͑4 OPRD1 rᝯ2ࢿ ញ͑4 OPRD1 Ոϵ OPRD2 ¤ū߾ ՈȳẴ৪Ո А└ƋɉÑ ƋᅆĹ& řĹ4 ZF ± 0 OPRD1 ljť]ǜ4า 1 ÂîȳẴ৪ͱՈ А└Ƌɉញ͑ OPRD1 Ȫ ±ūϬĺ 16 Ĺ) Ξ Ș OPRD2 ¤ū߾ ՈȳẴ৪ ƍᱷΞ[ǝâ ὧ4►ʃȣ ZF ᝯ ʐ OPRD2 ՈɮȬ ȑ/ PႸ4᪩ūÐî ̱ňϔ OPRD2 ᢊ&ọō Ƅ(Ɵ& 32 Ĺr ĹỞϬǸƌ„ zƌʔř̯ KdzÑ« 32 ĹỞϬǸƌ„ zƌʔř̯4̱ňϔ OPRD1 ͢ ̱ňϔ OPRD1 dzÑ« 16 Ĺz 32 ĹỞϬǸƌ„ ̱ňϔ OPRD2 « 16 LSL L OPRD1,OPRD2 ẝₐϬ4rPūÐ LSLL ƷϬzºȳẴ৪ǚǣɉ└⑃4͢ʸś& __limit;}) __asm__("lsll %1,%0 \n\tincl %0":"=r" (__limit):"r" (segment)); \ unsigned long __limit ; \ #define get_limit(segment) ({ \ ǎ5ń/kernel/sched.h  Ϭzǚǣ get_limit(): Š᪸Š᪸Š᪸Š᪸ } return 0; } return -ENOMEM; free_page_tables(new_data_base,data_limit); if (copy_page_tables(old_data_base,new_data_base,data_limit)) { set_base(p ->ldt[2], new_data_base); set_base(p ->ldt[1],new_code_base); p->start_code = new_code_base; // Ʒ¤œȸ4ՈĭˊाⒸ^úẟּ࣏Ȑ ɉՈ᰻ϧŌŜ ẝ«PᔞŃŌŜ ńËᜐr copy_page_tables 7Ȓۅ// ᪂าÏ new_data_base = new_code_base = nr * 0x4000000; panic("Bad data_limit"); if (d ata_limit < code_limit) panic("We don't support separate I&D"); if (old_data_base != old_code_base) Ōẝ࢑̑Ρ ɉۅ// Linux0.11 ]ΓťϔǒɉȐÏ old_data_base = get_base(current ->ldt[2]); // ǚƣϔǒɉՈȖŌŜ old_code_base = get_base(current ->ldt[1]); ɉՈȖŌŜۅ// ǚƣÏ data_limit=get_limit(0x17); ৰ 117 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ǡ͝—᫇Ϭ fork() Ո࣏Ûɉ4 ϔ«Ϭz“ϣẟ࣏Ո ü Ǹǒ┉Z«ƅẟ࣏ úƄẟ࣏ Ոܲ Ξ ȘǮ ϬPẟ࣏ǡūϬẝϔՈrȅẘúȨɿ\ѕ5ɥ«P4IJ« fork() } return 0; printf( “I’m father! \n”); else printf( “I’m child !\n”); if (fork()==0) { int main () static inline _syscall0(int,fork) ŷΞẝ࣏Ûà᪩Ćńʃ¡ZṗϦᜐ(᪩࣏ÛɎƦ̼ɀ) Ȑ!uৰPƵȰ4Ոrȅ ȇ̖rǔ1 ໐ẝẘúȨẜ]ּȕƄẟ࣏ẘú 04ƅ ̵ƅ̿ẋPϔɚ4dz ࿁ƅẘúȨ ɦ ἗ ń᫇Ϭ fork() ϔ 7Ȓ ẝϔ Ćȕúẟ࣏ẘú Ƅẟ࣏Ոẟ࣏ǻ PID ໐کuØ ϣtẟ࣏ȒՈẘúȨ⒲Lϣtẟ࣏ȒՈẘúȨ⒲Lϣtẟ࣏ȒՈẘúȨ⒲Lϣtẟ࣏ȒՈẘúȨ⒲L } return last_pid; p->state = TASK_RUNNING; /* do this last, just in case */ set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p ->ldt)); set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p ->tss)); // ֲQՈ LDT ^úẟ࣏Ո LDT«ּȐՈ̩:ẋǡՈ7 // ,ẟ࣏ՈȳẴ৪ȭàՈ TSS ʐ LDT«ºẟ࣏ǚǣՈ4 // ńͱƌՈ TSS ȳẴ৪ᜬʐ LDT ȳẴ৪ᜬņএ,ẟ࣏ՈȳẴ৪4 ͢Ʒ͢Ʒ͢Ʒ͢Ʒ current ->executable ->i_count++; if (current ->executable) current ->root->i_count++; if (current ->root) current ->pwd ->i_count++; if (current ->pwd) Ո pwd, root ʐ executable šϬƵϔţʺ 1 // ƟQẟ࣏úẟ࣏ f->f_count++; if (f=p ->filp[i]) for (i=0; iඓ᪸ ϵǸdzᢅ fork() ϔ Ƿܲ ËᜐՈẘúȨɥ«º)ẘúȒՈ eax Ǹƌ„ՈȨ4ńËᜐி } return –1; errno = -__res; return (int) __res; if (__res>=0) : “0” (__NR_fork)); : “=a ” (__res) __asm__ volatile (“int $0x80” long __res; { static inline int fork(void) Ŋ̴ ȺẝₐՈǃǎ5ʉŌǣ4 ňிඣՈǒɴ4 ໐ȭzẝ ẟ࣏ǡ᪸ ɥ«ẘúr4&rˊ ᢧẝ⒲L u Øǡₑ,׏׏ ẝẋ࣏ṉ́ ৰ 119 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ě ŅP.1fork ϔϣtẘúȨՈẋ࣏ &rˊᢧẝẋ࣏ dzÑdž໇[Ě ńẝₐɥ«&Ƅẟ࣏᪂าẘúȨ4 p->tss.eax = 0; ɥdzÑr4Linux0.11 Ոܲɥ«ẝ4ɆՈ4ń copy_process() ƅPǩ ºẝₐdzÑ׏Ϧǡᡅ̿᪂า Ƅẟ࣏ՈẘúȨ ǮᡅȺ Ƅẟ࣏ TSS ඗ȀՈ eax ᪂& 0 4 džϦƿՈẟ࣏Ո TSS 4ẝ ₐɥ ĉŐ rljƌúẟ࣏ȭàՈẝ eax Ǹƌ„Ȩ4 úẟ࣏ TSS džՈ4ńɉⒸḰࢿՈrȅ Intel ºܰâZɥǒɴrȺȈǸƌ„ՈƟQȨljƌ4ŷȺᝯ ǎ5 switch_to(n)ǡǒɴՈ4ȭzẝǃǎ5u>ඓ᩶ẋr Ʒ« ỞẋɉⒸḰࢿǡǒɴẟ࣏ džՈr ȅ«ỞẋËᜐǃ ò࣏Û ὧ4úẟ࣏dz ࿁Ć͍ƿŤƅ CPU Ոƿ-4IJ« ńẟ࣏ ò࣏Û ὧ4ɥĆ ָȉ ºிඣ)ẘú4ẝrȅ eax ႮϢɥ «Ƅ࣏Ûǻ4Ξ ȘËᜐr᫇ ƟËᜐǀ sys_fork() ϔ7Ȓ Ćʵǒ̑ΡǡΟǎ«ȪËᜐ᫇ò࣏Û4ΞȘ̵ƅËᜐ᫇ ljƌ؄ẘúȨ ΞȘƅʄr ẘúȨɥĆ͍4 Ű«ü&ń eax šϬẋ gs3esi 3edi ʐ ebp Ǹƌ„ eax ńūϬ Q>ඓỞẋƏʄ̱ňljƌr ń sys_fork() ϔՈƧɲ7¤ Ñ̵ƅËᜐ ƅʄ̱ň ^«ü&ń system_call() ϔ̵ƅ ѕ⒲nj[׏ PĆ̫uĆỞẋ᪅ŠuՈᢆͥՈ☺4 ƌ„ɦ ẘúȨɚ4ɥ]΢ ń ebx edx ecx z e ɌɌ x ɦ᪻þrּǍƷ ϢȒr؄ẝ ϙ¬4ɥ᪸ϔՈẘúȨ ɥ«΢ń eax  ὧ4̶Ǹẟ࣏ǻ4ƅ ̵ƅͫ ᢍ4uńệὃᯧç 4ẝϔՈẘúȨɥ«ƌ΢ń eax Ǹƌ„ üǸ eax ƌ΢Ոɥ«Ƅ ẘúƄẟ࣏ǻ ẝₐūϬr copy_process() ϔ ໐ copy_process() ϔՈżȒPǩ᪡« return last_pid; 1: ret addl $20,%esp ৰ 120 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ &6. ūϬ W32DASM ǡȭ main.com Ǒ˛ේ ǣ4඗Ș exe2com main.exe 5. Ⱥ main.exe Ḱdž& main.com: link main.obj func.obj, main.exe,,, 4. ȺâẢȉt main.exe: nasmw –f obj –o main.obj –main.asm tcc –mf –ofunc.obj –c –func.c 3. Ⱥâේ᪕t.obj ʸś ṗ͑ call _copy push ax push dx start: [extern _copy] [global start] [BITS 16] 2. ņএP˛ේ᪱ᣄâ main.asm ṗ͑ } return id; int id = 1; { void copy(int dx, int ax) 1. ņএP C ᪱ᣄâ func.c ṗ͑ ᪙ɀǹɘ᪙ɀǹɘ᪙ɀǹɘ᪙ɀǹɘ ᪙ɀֲՈ᪙ɀֲՈ᪙ɀֲՈ᪙ɀֲՈ ᪅ŠūϬ tcc ේ᪕„ේ᪕Ո࣏Û ϔՈẘúȨƌ΢ń eax Ǹƌ„4 «PጛȑՈ Windows [ՈǑ˛ේḳâ) , nasmw.exe, link.exe(masmV5.0 ՈẢȉ „),exe2com.exe, w32dasm( ẝ ᪙ɀ„nj᪙ɀ„nj᪙ɀ„nj᪙ɀ„nj tcc.exeV2.0 ᪙ɀ᪙ɀ᪙ɀ᪙ɀ ͟zϔՈẘúȨ⒲L͟zϔՈẘúȨ⒲L͟zϔՈẘúȨ⒲L͟zϔՈẘúȨ⒲L ৰ 121 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ϵǸdzᢅ ϔ copy() «Ởẋ eax ࢳƌ„ẘúẔᜐ඗ȘՈ4 ₓ a ̴Ⱥ 1 Č͑ si Ǹƌ„4ϢȒȺ si ՈȨᰏඝ ax Âƅʄẘú4 º 0001.0105 Ōϧ4 0001.0112 ῁«ϔ copy() ՈǑ˛ේ඗Ș si Ǹƌ„ּƟzɴᾬǜ Ȍ Ȍ඗Ș Ȍ඗Ș Ȍ඗Ș ඗Ș Ě ŅP.2 Ǒ˛ේՈẔᜐ඗Ș ৰ 122 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ :Ȍ 2 ʼႮ9Linux0.11 Čƨǀ͔ u nsigned a_entry; /* start address */ unsigned a_syms; /* length of symbol table data in file, in bytes */ unsigned a_bss; /* length of uninitialized data area for file, in bytes */ unsigned a_data; /* length of data, in bytes */ unsigned a_text; /* length of text, in bytes */ unsigned long a_magic; /* Use macros N_MAGIC, etc for access */ struct exec { Ξ[¿jKNksMwruqkLuyÀ Ōϧ4᪩ϔǒ඗ȀՈƮś ɣxẟ :ËᜐâţÑPËᜐϔǒ඗Ȁ exec structure â͐ʸśâ͐ʸśâ͐ʸśâ͐ʸś 4ȯƅ^৪ǻȑּȭàՈƋ৪ (string table) ᪩ᾬ ᜬᾬƋ৪ ᜬᾬƋ৪ ᜬᾬƋ৪ ᜬᾬƋ৪ ẟᜐǍšϬ4 ֲʃâ7ⒸȭʁȑՈǜₓʐϔ৪ǻ Ȑʳȯ ƅƇ⏂ȉ ࣏ÛūϬՈᩴơϔǒ Ϭz ńxẟ : (si mbol table) ẝᾬ ৪ǻᜬᾬ ৪ǻᜬᾬ ৪ǻᜬᾬ ৪ǻᜬᾬ ū⍌ՈₑǎĹ4 ՈňϬି Ĩ IJ««Ϭzϔǒɉ ₑǎĹᾬۅ (data relocations) ^Ï ϔǒₑǎĹᾬ ϔǒₑǎĹᾬ ϔǒₑǎĹᾬ ϔǒₑǎĹᾬ ɉՈū⍌zŌŜ4ۅẟ:ֲʃârϬzǎĹÏ ȯƅƇ⏂ȉ࣏ÛūϬՈᩴơϔǒ4ńඈȌx (text relocations) ẝᾬ ₑǎĹᾬۅÏ ₑǎĹᾬۅÏ ₑǎĹᾬۅÏ ₑǎĹᾬۅÏ ͱƌ4 ȯƅ>ඓ!ϧĚẋՈϔǒ ʇ«ᝯ¤ṁ4dzᪿ΅Ո (data segment) ẝᾬ ϔǒɉᾬ ϔǒɉᾬ ϔǒɉᾬ ϔǒɉᾬ ÑÑǮᪿƮśẟᜐ¤ṁ4 ʐּ͟ϔǒ4dzۅ (text segment) ȯƅ࣏ÛËᜐūᝯ¤ṁ4ͱƌՈūÐÏ ɉᾬۅÏ ɉᾬۅÏ ɉᾬۅÏ ɉᾬۅÏ 4 â4ẝ«̳PȑᡅՈඈtᾬ 4ͱƌÂËᜐ ໐⏂ȉ࣏Û(ld)ūϬẝ‡džϔȺP‡xẟ:ֲʃâඈȌtPdzËᜐ  ȯƅP‡džϔ ͱʴūϬẝ‡džϔȺËᜐâ¤ṁ (exec header) ᪩ᾬ Ëᜐ͐ᾬ Ëᜐ͐ᾬ Ëᜐ͐ᾬ Ëᜐ͐ᾬ « ඈt4ŭ+.Û ẝ‡ᾬ Sᅆ PËᜐâ͝dzƅSᾬ 4 âxẟ:âۅdzËᜐՈƶ„ ń͐â ϷŠrYϔǒ඗ȀÑ ǎP‡ǃϔ4ẝ ‡ϔǒ඗ȀȳẴrிඣ Z ʸś4 Linux ͱʴ0.11 Č±Γťa.out(Assembley out) Ëᜐâʸś4[☦͔☦·එP[a.out dzËᜐâՈʸśdzËᜐâՈʸśdzËᜐâՈʸśdzËᜐâՈʸś2 âՈǍʻ&͢ņএּàՈẔᜐɳʟ4Ȑr ƷĆ̠ˊÝ̠ˊâ4 ᡅȺᡅËᜐՈ࣏Û᫇͑ͱƌ4ẝ1ň« ϵிඣ᫇Ϭ execve ǀtՈ4ƷdzÑ ʵǒdzËᜐ ņt£Ȓ Ć^úẟ࣏͝— ȐP࣏Û4&r ࿁̻«Ƅẟ࣏Ëᜐ͢ƷՈ࣏Ûɥ◄ẟ࣏ ৰŅxতৰŅxতৰŅxতৰŅxত ẟ࣏ՈËᜐẟ࣏ՈËᜐẟ࣏ՈËᜐẟ࣏ՈËᜐ ৰ 123 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ struct relocation_info Likewise, the data -relocation section applies to the data section. */ all of which apply to the text section. The text-relocation section of the file is a vector of these structures, /* This structure describes a single relocation to be performed. ₑǎĹᩴơͣƅʃβʸś ƷūϬₑǎĹǍʻ(relocation_info)඗ȀǡȳẴ ₑǎĹᩴơₑǎĹᩴơₑǎĹᩴơₑǎĹᩴơ ᜬՈ᰻ϧĹาƋᅆȻࢿȨ4N_STROFF(exec) Ƌ৪ N_SYMOFF(exec) ৪ǻᜬՈ᰻ϧĹาƋᅆȻࢿȨ4 ₑǎĹᜬՈ᰻ϧĹาƋᅆȻࢿȨ4ۅN_TRELOFF(exec) Ï N_DRELOFF(exec) ϔǒₑǎĹᜬՈ᰻ϧĹาƋᅆȻࢿȨ4 N_DATOFF(exec) ϔǒɉՈ᰻ϧĹาƋᅆȻࢿȨ4 ɉՈ᰻ϧĹาƋᅆȻࢿȨ4ۅN_TXTOFF(exec) Ï ẘú☢►Ȩ4 N_BADMAG(exec) ΞȘa_magic Ƌɉ]࿁ᝯ᪊/ ՈĹาȻࢿȨ4ẝ‡ǃƅ ᅆ Ȉᾬ ńa.out.h ͐âǎ5rόǃ ẝ ‡ǃūϬ exec ඗Ȁǡϟ᪙P Ⴘɳz້ǎĹËᜐâ a_drsize ᪩ƋɉȯƅϔǒₑǎĹᜬՈ̓Ƀ «Ƌᅆϔ4 ₑǎĹᜬՈ̓Ƀ «Ƌᅆϔ4ۅa_trsize ᪩ƋɉȯƅÏ a_entry ȯƅͱʴȺËᜐâ¤ṁ4ͱƌÑȒ ࣏ÛËᜐ᰻ϧͥՈͱƌŌŜ4 ՈƋᅆ⑃òȨ4 a_syms ȯƅ৪ǻᜬᾬ ࣏Ûr ẝɉdz΅ͱƌºɴϦ̠zϔǒɉȒ☦ Â!ϧr&͔►4 4ͱʴń¤ṁ a_bss ȯƅ6bss ɉ7Ո⑃ò ͱʴϬ͢᪂าńϔǒɉȒ!ϧՈbreak brk a_data ᪩ƋɉȯƅϔǒɉՈ⑃òȨ Ƌᅆϔ4 ɉՈ⑃òȨ Ƌᅆϔ4ۅa_text ᪩ƋɉȯƅÏ Ո ໐ϔǒɉՈ)☦«dz΅Ո4 rǮᪿ☦(ۅɉʐϔǒɉ῁ᝯ⏂ȉ࣏Û̠ˊt̶)☦̓ɃՈų4ͱʴ¤ṁՈÏ ۅZMAGIC ͱʴńȑᡅrºxẟ:Ëᜐâ¤ṁưএՈ)☦4Ëᜐ͐ᾬ3Ï ΅ͱƌṽАŌϧ4 ɉȒ[P)dzᪿۅṁ4rǮᪿ ͱƌ Âîϔǒɉ¤ṁ4ϤۅՈ4Ϣ໐ ͱʴȺÏ ʐϔǒɉ௫╓ńËᜐ͐Ȓ☦«Ảනƌ΢ۅNMAGI C ȐOMAGIC Pʳ Ï ʐϔǒɉ῁¤ṁ4dzᪿ΅ͱƌ4 ۅʐϔǒɉ௫╓ńËᜐ͐Ȓ☦«Ảනƌ΢Ո4ͱʴȺÏۅOMAGIC ᜬ߾Ï ȑ/ĉȯÑ[Ȩ7P Š̈ϔ Ʒ ̳PŌ ܲǎrxẟ:Ëᜐâ^͢Ʒ ¤ṁՈâ 7ⒸՈľ/4Ƌɉ ৪(machine-id) ū߾Ϧxẟ:âȺń¬4ƶ„ZẔᜐ4N_GETMAGIC() ǃū «ϵ⏂ȉ ࣏Û ńẔᜐr ¤ṁ4ẟ࣏ŌŜाⒸ4ǃ N_GETMID() Ϭzẘúƶ„ʃ᪊ a_midmag : ᪩ƋɉȯƅᝯN_GETFLAG() 3N_GETMID ʐN_GETMAGIC() ᪃⒲ՈƄᾬ ȈƋɉՈ£࿁Ξ[ }; unsigned a_drsize; /* length of relocation info for data, in bytes */ unsigned a_trsize; /* length of relocation info for text, in bytes */ ৰ 124 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ r_symbolnum ƋɉūǎՈ৪ǻȺᝯₑǎĹtẋ࣏⏂ȉᜬ r_jmptable ΞȘᝯาĹ Ŝ4 (GlobalOffset Table) ՈPȻࢿȨ4ńẔᜐr? ͔ɴȻࢿᜬ᪩Ȼࢿ̠ᝯ᪂า&৪ǻՈŌ r_symbolnum ƋɉūǎՈ৪ǻȺᝯₑǎĹt͔ɴȻࢿᜬ r_baserel ΞȘ᪂าr᪩Ĺ ⏂ȉ࣏ÛᝯₑǎĹՈū⍌ūȕὧɉ4 ẝିƋɉɎ᪍ 4 ńẝ࢑ ̑Ρ [ r_symbolnumƋɉՈͱǭ«P n_type Ȩ ᢅ[☦ ☦ Ȉɉ¤ṁŌŜՈǜĚ ໐]«ǑœP৪ǻȨՈǜĚ ┨☢Ȑ r᪂าr r_baserel ᢅ[ œₑǎĹ« 8ɴᾬ 9Ո⏂ȉ ࣏Û Ű,ū⍌ÑǑ ǻŌŜǡ Ű,ּà ū⍌4Ɵ ᪩Ĺ« 0 r r_extern ΞȘᝯาĹ ᜬ ߾᪩ₑǎĹ ◄ᡅP ̲ᾬšϬ Ǹr⏂ȉ࣏Ûȑ/ūϬP৪ ߾4 Ƌᅆ⑃4 r_length ᪩Ƌɉȯƅū⍌⑃òՈ2 ՈƵ5Ȩ 0 ᜬ߾1 Ƌᅆ⑃ 1 ᜬ߾2 Ƌᅆ⑃ 2 ᜬ śŌ¤4᪩ū⍌Z4 4ƟẔᜐ࣏ÛūϬẝ ᝯₑǎĹՈ ū⍌r ᪩ū⍌ՈŌŜᝯ╔ ūÐᾬۅ5ś « ʒzƶ„ r_pcrel ΞȘ᪂าr ᪩Ĺ ⏂ȉ࣏Û ɥᩨ&ǷńŰ,Pū⍌ ᪩ū⍌ūϬ pc ּ͟ȯŜ ɨĽĹ«0 ὧ4̑Ρɥ]Ȑ ᢅ[☦4 ࣏Ûńਜ਼Ϧ৪ǻՈ ඡȭŌŜÑȒ ɥȺ᪩ŌŜ¤4ǷńẟᜐₑǎĹՈ ū⍌Z4ΞȘr_extern 4⏂ȉ r_symbolnum ᪩Ƌɉȯƅ৪ǻᜬP৪ǻ඗ȀՈÛǻȨ]«ƋᅆȻࢿȨ ĆȺ>ඓƌʔń᪩Ȼࢿ̠ՈȨ^ūϬₑǎĹᩴơᩥਜ਼ϦՈ,Ȩּ¤4 ɉŌϧ̠ᩥϔՈ ϔǒₑǎĹՈ ȻࢿȨ«ºϔǒɉŌϧ̠ᩥਜ਼Ո4⏂ȉ࣏ÛۅȻࢿȨ«ºÏ ₑǎĹՈۅՈū⍌ՈƋᅆȻࢿȨ4Ï r_address ᪩Ƌɉȯƅ◄ᡅ⏂ȉ࣏Û̠ˊේṕ ᪩඗ȀȈƋɉՈȯ5Ξ[ }; unsigned int r_pad:4; it is desirable to clear them. */ /* Four bits that aren't used, but when writing an object file unsigned int r_extern:1; (the N_EXT bit may be set also, but signifies nothing). */ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS 0 => relocate with the address of a segment. in file's the symbol table. r_symbolnum is the index of the symbol /* 1 => relocate with value of symbol. unsigned int r_length:2; Thus, a value of 2 indicates 1<<2 bytes. */ /* Length (as exponent of 2) of the field to be relocated. unsigned int r_pcrel:1; as well as for changes in the symbol or section specified. */ and it should be relo cated for changes in its own address /* Nonzero means value is a pc-relative offset unsigned int r_symbolnum:24; /* The meaning of r_symbolnum depends on r_extern. */ int r_address; /* Address (within segment) to be relocated. */ { ৰ 125 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ zϔǒ৪ǻିĨ IJńxẟ :ֲʃâ ̵ƅȭàՈ Ȼࢿ4ۅN_BSS P BSS ৪ǻ^Ï ՈȻࢿ4 ÂλƿƷ ϢȒ¤Z᪩ᾬ Ōϧ ¤ṁՈŌŜ ]«âՈȻࢿȨ ໐«ŌŜ &r âϦâՈȻࢿ ɥƅȑᡅܲǎּ͟ᾬ ʐϔǒ৪ǻՈȨۅ N_DATA Pϔǒ৪ǻ^N_TEXT ିĨ IJ«ϬzϔǒŌŜ4ȭàÏ ,͢Ȩ4 ŌŜ ⏂ȉ࣏ÛńȌÂxẟ:ֲʃârĆŰۅ৪ǻ4᪩৪ǻՈȨ«ÏۅN_TEXT PÏ N_ABS Pඡȭ৪ǻ4⏂ȉ࣏Û]ĆŰ,Pඡȭ৪ǻ4 ⏂ȉ࣏ÛȺọō¤ƅxẟ:ֲʃâż̓Ո⑃ò4 ẟ:ֲʃâȭ͢⑃òȨ]PႸ Н⑃ò਍zn_valueՈƋᅆ4ΞȘ৪ǻń̶zPxẟ:ֲʃâ῁̵ƅǎ5Âẝ‡x ⏂ȉ࣏ÛńBSS ɉȺ᪩৪ǻᢧȌ&PŌŜ lj ̵ƅxẟ:âǎ5rẝ৪ǻ ࢴՈ̲ᾬ৪ǻ Ñܲǎ᪩৪ǻՈඡȭϔǒȨ4ĽȞ̑Ρ[ ΞȘn_type Ƌɉ«☢►Ȩ  N_UNDF PƦǎ5Ո৪ǻ4⏂ȉ࣏Ûȑ/ń͢Ʒxẟ:ֲʃâǎĹPͣƅּȐȑ ɨĽĹ Ϭz⏂ȉ࣏Ûͫ͠ᱧՈۅǻ Â̭᩼͢Ʒxẟ:ֲʃâȭƷØՈšϬ4N_TYPE ʃᐁ vtYƄƋɉ ȭz N_EXT ିƧĹาĹՈ৪ǻ ⏂ȉ ࣏ÛȺƷ Ø׏ ň« 8̲ᾬՈ9৪ n_type Ϭz⏂ȉ࣏ÛܲǎΞŁŰ,৪ǻՈȨ4ūϬĹ ʃᐁ(bitmasks) dzÑȺn_type Ƌɉ Ոū⍌4P৪ǻᜬr ᪩ƋɉᝯŻdž&n_un.n_name Ƌɉ ẝ«ͱƌƋ৪ ᜬՈƋᅆȻࢿȨ4Ɵ࣏ÛūϬ nli st() ϔ᪃⒲n_un.n_strx ȯƅƨ৪ǻՈ ȑࢴńƋ৪ ͢ȈƋɉՈȯ5& #endif }; unsigned long n_value; short n_desc; char n_other; unsigned char n_type; } n_un; long n_strx; struct nlist *n_next; char *n_name; union { struct nlist { #ifndef N_NLIST_DECLARED ৪ǻᜬ«nlist ඗ȀՈPϔඈ Ξ[¤߾ ৪ǻᜬ৪ǻᜬ৪ǻᜬ৪ǻᜬ ᜬՈdzǜ⑃òȑࢴඈt4ǻᜬĖǎ⑃òՈᩴơÑǎƋ৪ Ո᫇Ϙ P৪ǻՈȑࢴȑ/Ϭǡᜬ߾͢ŌŜ ָ4>ᝯᰏtPඡȭŌŜȨ4৪ǻ« ϵ৪ 4 ϵz⏂ȉ࣏ÛȭŌŜ œȸ4ȨtՈ4৪ǻȺ ȑࢴœȸ&ŌŜ z້ŰỞǃŌ᩶«Ƌ৪ ūǎՈŌ 54᪩̩:̱ň«Ởẋ͝—ֲʃµųPȌ ỆՈϔǒ-ՈẔᜐr?⏂ȉ࣏Ûǀ r_copy ΞȘᝯาĹ ᪩ₑǎĹᩴơūǎrP৪ǻ ᪩৪ǻՈͱǭȺᝯ̩:4r_address Ẕᜐrᝯ¤ṁՈŌŜּ͟4ẝିₑǎűń͝—ֲʃâϦɴ4 Ոœᬥâń ᪸ŠǸₑǎĹ^᪩ֲʃâȺt&͢ඈtᾬ r_relative ΞȘᝯาĹ (ProcedureLinkage Table) ՈPȻࢿȨ4 ৰ 126 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ret addl $4,%esp call _do_execve // ᜬŌŜ3ɳʟᜬŌŜ // ிඣ᫇ϬrՈ IP Ոƌ΢ŌŜ3᫇Ϭ_sys_execve rՈ IP Ȩ3âȑŌŜ3džϔ // ᫇Ϭϔ do_execve 4ẝrȅºிඣʄ*ŌϧՈ 20 Ƌᅆƌ΢Ո« pushl %eax lea EIP(%esp),%eax // ȺËᜐிඣ᫇ϬՈrȅՈƌ΢ IP ȨՈŌŜň&džϔČỖඝϔ do_execve _sys_execve: .align 2  systemcall.s) Ⱥẝ 3 Ǹƌ„ՈȨň&džϔƏ͑ிඣ Ȣʄ 4ȭà execve Ոͱʴϔ« sys_execve( Ĺz 4 ebx Ǹƌ„ 3argv ƌ4 ecx Ǹƌ„3envp ƌ4 ebx Ǹƌ„4 ń᫇ϬּàՈƉ¥࣏Û 7Q /Ⱥẝ 3 džϔ filename ƌ΢ ϔ execve ūϬr 3 džϔ ńËᜐிඣ᫇ϬՈrȅ **,argv,char **,envp)4444 ϔ execve dzѺ/lib/exec.c ׏4ƷՈǎ5 _syscall3(int,execve,const char *,file,char Ոrȅ±±Ⱥ ĉȯ ᪩ϔ̌ŠՈ͐â ĉŐ 4 â ɥdzÑūϬּàՈϔr4ü Ǹ ȭz /΢4 .c ʐ.h â4ūϬ Š5ǎ4r C Ո̶âේ᪕ Ⱥඓ„ūϬՈϔՈǎ5ʐ̌ ̵ƅ׏4ÂՈǎ54ẝ char * filename, char ** argv, char ** envp); Ĺz /include/unistd.h static inline _syscall0(int,fork)4IJ« u ØŸǮ࿁׏ 4ȭϔ execve Ո̌Š int execve(const Ȑ4ü&ȭz fork ᫇ϬՈr ȅ ẝϔՈǒɴ>ඓ ńâ͐ᾬūϬǃǒɴrȭ͢Ոǎ5 4 ńৰP Ƶ׏ 4᫇ϬẝϔՈr ȅ ^᫇Ϭ fork ] init() Ոrȅ᫇ϬՈĹz/init/main.c ẟ࣏ՈËᜐ« Ɖ☤ிඣ᫇Ϭ execve ǡǒɴՈ4ৰPƵ᫇Ϭ execve «ńËᜐ!ϧĚϔ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ execve ʇ«44 ՈȻࢿƋ৪  ඈt4⑃òÏᜬϘᜬՈƋᅆ̓Ƀ ¤Ñń32 ĹՈƶ„Z͢żɃȨ z້«ৰ1ǻƋ৪ ᜬ«ϵ⑃ò&u_int32_t ȒᲣPnull ඗ɲՈ৪ ȨdzÑ«ç͛Ո4Ƌ৪ Ξ᫇ś࣏Û৪ǻ 3ϔǒʐ BSS ৪ǻ ẝ«PŌŜ ȭz͢Ʒ৪ǻ ŷۅn_value ȯƅ৪ǻՈȨ4ȭzÏ ň]ȐՈϬỘ4 n_desc ljНඝ᫇ś࣏ÛūϬ⏂ȉ࣏Û]ȭ͢ẟᜐ̠ˊ4]ȐՈ᫇᪙࣏ÛȺ᪩ƋɉϬ ņ4 ɉẜ«ϔǒɉ4 ᪩Ƌɉ'ᡅϬz⏂ȉ ࣏Û ld Ϭz¬ɍdzËᜐ࣏ÛՈۅ໐]੥Ʒ Ø«ĹzÏ 4 AUX_FUNC Ⱥ৪ǻ^dz᫇ϬՈϔּ͟ AUX_OBJECT Ⱥ৪ǻ^ϔǒּ͟ ᢅ Q n_other ƋɉՈżĺ4 ĹȯƅȨ7PAUX_FUNC ʐAUX_OBJECT ƅ͟ǎ5dž n_other ᪩Ƌɉŭ+n_type ܲǎՈɉ ȴƇƅ͟৪ǻₑǎḺ́ňՈ৪ǻ ưএɳǍʻ4ֲ Ϭzọō৪ǻ᫇ś࣏Û(ŷΞgdb)ͫ͠ᱧՈĹ͢Ȩństab() ᪸Š4ۅN_STAB ʃᐁ ŌŜ4⏂ȉʐ¤ṁr]◄ᡅâȑ৪ǻ IJȭz᫇ś࣏Û☢„ƅϬ4 ɉۅՈ৪ǻ 7Q 4৪ǻՈ ȑࢴɥ«ඝt⏂ȉ࣏ÛՈâ ȑ ໐͢Ȩ«xẟ:âŊÏ N_FN Pâȑ৪ǻ4ńȌÂxẟ:ֲʃâr ⏂ȉ࣏ÛĆȺ᪩৪ǻ ȶ͑ńxẟ :â ৰ 127 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;(argc = count(argv // ᩥਜ਼ϦdžϔՈϔʐɳʟǜₓՈϔ return -ENOENT; if (!(inode=namei(filename))) /* get executables inode */ page[i]=0; for (i=0 ; ib_data+2, 1022); unsigned long old_fs; char buf[1023], *cp, *interp, *i_name, *i_arg; */ * Sorta complicated, but hopefully it will work. -TYT * This section does the #! interpretation. /* if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) { // ȭÝ̠ˊâՈ()ǎ̠ˊ ex = *((struct exec *) bh->b_data); /* read exec -header */ ±ቻǣՈϔǒųǚǣâ͐ᾬǍʻ// º } goto exec_error2; retval = -EACCES; if (!(bh = bread(inode->i_dev,inode->i_zone[0]))) { // ቻǣ࣏ÛՈৰPųϔǒ΢4෗Ξľ } goto exec_error2; retval = -ENOEXEC; !((inode->i_mode & 0111) && suser())) { if (!(i & 1) && i >> = 3; else if (current ->egid == inode->i_gid) i >>= 6; if (current ->euid == inode->i_uid) e_gid = (i & S_ISGID) ? inode->i_gid : current ->egid; e_uid = (i & S_ISUID) ? inode->i_uid : current ->euid; i = inode->i_mode; } goto exec_error2; retval = -EACCES; if (!S_ISREG(inode->i_mode)) { /* must be regular file */ restart_interp: envc = count(envp); ৰ 129 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ . * OK, now restart the process with the interpreter's inode /* } goto exec_error1; retval = -ENOMEM; if (!p) { argc++; p = copy_strings(1, &i_name, page, p, 2); } argc++; p = copy_strings(1, &i_arg, page, p, 2); if (i_arg) { argc++; p = copy_strings(1, &filename, page, p, 1); */ * user environment and arguments are stored. * This is done in reverse order, because of how the * * (3) filename of shell script * (2) (optional) argument to interpreter * Splice in (1) the interpreter's name for argv[0] /* } p = copy_strings( -- argc, argv+1, page, p, 0); p = copy_strings(envc, envp, page, p, 0); if (sh_bang++ == 0) { */ * (optional) argument. * OK, we've parsed out the interpreter name and /* } i_arg = cp; *cp++ = '\0'; if (*cp) { } i_name = cp+1; if (*cp == '/') for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) { i_arg = 0; interp = i_name = cp; } goto exec_error1; retval = -ENOEXEC; /* No interpreter name found */ if (!cp || *cp == '\0') { ৰ 130 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ (++for (i=0 ; i<32 ; i curr ent ->executable = inode; iput(current ->executable); if (current ->executable) /* OK, This is the point of no return */ } } goto exec_error2; retval = -ENOMEM; if (!p) { // ΞȘ p & 0 ɥᜬ߾džϔᜬ>ඓƍr p = copy_strings(argc,argv,page,p,0); p = copy_strings(envc,envp,page,p,0); if (!sh_bang) { // ̩:džϔʐɳʟǜₓ4 r)ᜬ } goto exec_error2; retval = -ENOEXEC; printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename); if (N_TXTOFF(ex) != BLOCK_SIZE) { } goto exec_error2; retval = -ENOEXEC; inode->i_size < ex.a_text+ex.a_data +ex.a_syms+N_TXTOFF(ex)) { ex.a_text+ex.a_data+ex.a_bss>0x3000000 || if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize || ⑃òՈʇʐ4 // +ϔǒɉ+৪ǻᜬ⑃ò+Ëᜐ͐ᾬ ɉۅɉ+ϔǒɉ+Ȣɉ⑃ò᱉ẋ 50MB 3z້ i ᅆͥᜬŠՈ᪩Ëᜐâ ⑃òɃzÏۅ// Ï ⑃ò a_trsize ]਍z 03z້ϔǒₑǎĹǍʻ⑃ò]਍z 03z້ ₑǎĹᾬۅ// ້Ï // ȭz[ ̑Ρ Ⱥ]Ëᜐ࣏ÛΞ ȘËᜐâ]« ◄˖)dzËᜐâ(ZMAGIC) 3z // [☦ȭËᜐ͐Ǎʻẟᜐ̠ˊ4 brelse(bh); // ₎΢෗Ξľ } goto restart_interp; set_fs(old_fs); } goto exec_error1; retval = -ENOENT; set_fs(old_fs); if (!(inode=namei(interp))) { /* get executables inode */ set_fs(get_ds()) ; old_fs = get_fs(); */ ৰ 131 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;(return(retval free_page(page[i]); for (i=0 ; iegid = e_gid; current ->euid = e_uid; current ->start_stack = p & 0xfffff000; // ᪂าẟ࣏dzūϬՈȢʄŌŜ (current ->end_code = ex.a_text)); (current ->end_data = ex.a_data + current ->brk = ex.a_bss + âƦ!ϧĚϔǒɉ⑃ò âϔǒɉ⑃ò // ⑃ò ɉۅâՈÏâϔǒɉ⑃òȢ඗ɲ ɉ⑃òۅâՈÏ// a_text ϔǒɉ඗ɲ ɉ⑃òۅzâඝϦՈÏɉ඗ɲۅ// ʵǒâǍʻₑ,᪂าẟ࣏ՈǍʻ͢Ï p = (unsigned long) create_tables((char *)p,argc,envc); // &džϔņএdžϔᜬ p += change_ldt(ex.a_text,page) -MAX_ARG_PAGES*PAGE_SIZE; ɉ⑃òʐdžϔՈ̑Ρₑ,᪂า LDTۅ// ʵǒâՈÏ current ->used_math = 0; last_task_used_math = NULL; if (last_task_used_math == current) free_page_tables(get_base(current ->ldt[2]),get_limit(0x17)); free_page_tables(get_base(current ->ldt[1]),get_limit(0x0f)); // úẟ࣏͝—ȐPͱƌाⒸՈ fork ϦǡՈƄẟ࣏«^// ŷȺₑ,᪂า LDT ◄ᡅ₎΢ƣǡ¤ŤƅՈ LDT 4 current ->close_on_exec = 0; sys_close(i); if ((current ->close_on_exec>>i)&1) for (i=0 ; isigaction[i].sa_handler = NULL; ৰ 132 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ // ȺdžϔºȒȕQȺdžϔ̩:4)ᜬՈȒᾬ set_fs(new_fs); if (from_kmem==2) old_fs = get_fs(); new_fs = get_ds(); // ọōƄ4ń۸ū7Q◄ᡅljНẝ‡Ȩ4 // ிඣƿ└ՈūϬ͔ɴȳẴ৪ᜬọōƄ ń fs Ǹƌ„ƌ΢rϬ›൫ՈɴᾬȳẴ৪ᜬ // ϵzń᫇Ϭ system_call( Ĺz/kernel /system_call.s) Ոrȅ>ඓń ds Ǹƌ„ƌ΢rƅ return 0; /* bullet -proofing */ if (!p) // ()«Ȫƅƌ΢ՈाⒸ unsigned long old_fs, new_fs; int len, offset = 0; char *tmp, *pag; { unsigned long p, int from_kmem) static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, */ * set_fs() unless we absolutely have to. * it is expensive to load a segment register, we try to avoid calling * We do this by playing games with the fs segment register. Since it * * 2 kernel space kernel space * 1 kernel space user space * 0 user space user space * from_kmem argv * argv ** * * whether the string and the string array are from user or kernel segments: * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies * * to be put directly into the top of new user memory. * memory to free pages in kernel mem. These are in a format ready * 'copy_string()' copies argument/envelope strings from user /* džՈ4ȭzɳʟdžϔẝ«PʳՈ4 ȭz]ȐՈाⒸ¤◄ᡅՈƿ└K«]ȐՈ ẝₐ«ỞẋūϬ fs Ǹƌ„ǡǒɴƿ└Ոǜ 2džϔ argv* ńிඣाⒸ3džϔᜬ argv** ńிඣाⒸ 1džϔ argv* ńிඣाⒸ3džϔᜬ argv** ńϬ›ाⒸ 0džϔ argv* ńϬ›ाⒸ3džϔᜬ argv** ńϬ›ाⒸ & 3 ̑Ρ ṇ˔ݒ4ʵǒdžϔᜬʐdžϔƌ΢ՈाⒸ]ȐdzÑ ẝϔՈňϬ«ȺɳʟǜₓᜬʐdžϔǜₓᜬºȒȕ Q̩:4 r)ᜬ ƷՈǒɴɨ ϔϔϔϔ copy_strings ৰ 133 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;return p // ẘú̩:ǀdžϔ7ȒՈ r)ᜬՈȻࢿȨ set_fs(old_fs); if (from_kmem==2) } } *(pag + offset) = get_fs_byte(tmp); } set_fs(new_fs); if (fro m_kmem==2) return 0; (unsigned long *) get_free_page())) !(pag = (char *) page[p/PAGE_SIZE] = if (!(pag = (char *) page[p/PAGE_SIZE]) && ‑P)ͱƌाⒸ ‑ɦ ɥ // ΞȘβ̣ūϬՈ)ẜ̵ƅ set_fs(old_fs); if (from_kmem==2) offs et = p % PAGE_SIZE; if (-- offset < 0) { // ǣ4Ǹr p ńͱƌɌP)ՈȻࢿŌŜ -- p; -- tmp; -- len; // ẝPǹËᜐ7Ȓ p ūȕŷȺŌϧ̩:ՈŌŜ tmp ūȕdžϔՈɲᾬ len &džϔ⑃ò while (len) { // º)ɲᾬȕQ̩:džϔ } return 0; set_fs(old_fs); if (p -len < 0) { /* this shouldn't happen - 128kB */ } while (get _fs_byte(tmp++)); len++; do { // Ƌᅆ4 1 tmp ūȕdžϔɲᾬՈ[P // ඣᩥdžϔՈ⑃ò ẝ]ËᜐǀȒ len «džϔՈ⑃ò len=0; /* remember zero -padding */ set_fs(old_fs); if (from_kmem == 1) panic("argc is wrong"); if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc))) // Ñ fs &ɉŌŜºdžϔᜬቻǣdžϔ ϵz«Ƌ৪ॠüǸūϬrƋ৪ū⍌ set_fs(new_fs); if (from_kmem == 1) while (argc-- > 0) { ৰ 134 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ; /* while (get_fs_byte(p++)) /* nothing put_fs_long((unsigned long) p,envp++); while (envc -- >0) { put_fs_long(0,argv); } while (get_fs_byte(p++)) /* nothing */ ; put_fs_long((unsigned long) p,argv++); wh ile (argc-- >0) { ‑ՈाⒸ // ȺdžϔՈŊŌŜƌ͑ put_fs_long((unsigned long)argc, -- sp); put_fs_long((unsigned long)argv, -- sp); put_fs_long((unsigned long)envp,-- sp); argv = sp; sp -= argc+1; envp = sp; sp -= envc+1; // Ⓒ╘ PϬzň& ‑ՈrȅĆ̶ɨrⒸdžϔ̶ ‑ाⒸ ń // &ūȕȈdžϔՈū⍌ sp = (unsigned long *) (0xfffffffc & (unsigne d long) p); // ȺƟQՈȻࢿȨň&ʄá µŃƏʄ̱ňņএ௦š4 unsigned long * sp; unsigned long *argv,*envp; { static unsigned long * create_tables(char * p,int argc,int envc) */ * addresses on the "stack", returning the new stack pointer value. * memory and creates the pointer tables from them, and puts their * create_tables() parses the env - and arg -strings in new user /* ɴՈ4 ᡅ&ÂØ ņএPᜬ4 Ởẋẝᜬǡ௦šẝ ‡džϔ ẝ1ň ɥ«ƅϔ create_tables ǡǒ QPϔ±±«Ⱥdžϔ΢͑4ūǎՈͱƌाⒸ &r࿁̻ ȭẝ ‡džϔẟᜐɡ᪦ɥ◄ ϔϔϔϔ create_tables O Ě Ņx.1 džϔń)ᜬՈ Ě ȳ᪂ṗ͑Ոdžϔᜬ& dir 3pan.cɳʟᜬ& /usr/root4ὧ4ËᜐǀȒ )ᜬՈ ̑ΡΞ ৰ 135 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;(put_page(page[i],data_base if (page[i]) data_base -= PAGE_SIZE; for (i=MAX_ARG_PAGES -1 ; i>=0 ; i--) { data_base += data_limit; // Ⱥdžϔ΢4ẝᔞŃाⒸՈɲᾬ ͢ǒɥ«ȺᔞŃाⒸœȸ4rdžϔᜬ) __asm__("pushl $0x17\n\tpop %%fs"::); /* make sure fs points to the NEW data segment */ set_limit(current ->ldt[2],data_limit); set_base(current ->ldt[2],data_base); set_limit(current ->ldt[1],code_limit); set_base(current ->ldt[1],code_base); // ₑ,᪂าɴᾬȳẴ৪ᜬ data_base = code_base; code_base = get_base(current ->l dt[1]); ՈȖŌŜ ɉՈȖŌŜɥ«ƟQẟ࣏Ƅẟ࣏ۅ// ᪂าÏ data_limit = 0x4000000; // ɉՈ⑃ò« 64M // Q☦>ඓ᪸ẋr ȭzɣPẟ࣏ǡ᪸ƷƅPᔞŃՈ 64M ՈाⒸ üǸϔǒ code_limit &= 0xFFFFF000; code_limit = text_size+PAGE_SIZE -1; ɉŤϬՈ⑃ò ẝ«Ñ 4k &ṽАՈ4ۅɉ⑃ò˖ϦÏۅ// ʵǒâÏ int i; unsigned long code_limit,data_limit,code_base ,data_base; { static unsigned long change_ldt(unsigned long text_size,unsigned long * page) ɉ⑃ò a_text ʐdžϔᜬņএ,ՈɴᾬȳẴ৪ᜬ4ۅʵǒâඝϦՈÏ ϔϔϔϔ change_ldt Ě Ņx.2 džϔńʄՈƌʔ OΞĚ ±Ոdžϔņএǀᜬ7ȒՈȭz } return sp; put_fs_long(0,envp); ৰ 136 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;return data_limit // ȺᔞŃाⒸՈɲᾬȨň&ẘúȨ ৰ 137 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;task[i] ->father = 1 if (task[i] && task[i] ->father == current ->pid) { for (i=0 ; iඓ4͍r ü ǸɥȕƷ,Ոúẟ࣏  1 ǻẟ࣏ // TASK_ZOMBIE Ո ɥ᪸Šẝ Ƅẟ࣏>ඓ₎΢r ႮᵯŤϬՈ ᰈļ ◄ᡅϵúẟ࣏ǡ // ໅ࠚNj 1 ǻẟ࣏t&ƷØՈúẟ࣏4Ǫ̲ ΞȘǕɴẝ‡Ƅẟ࣏ƅźɍ« // ƟPẟ࣏4͍r ƷՈƄẟ࣏ɥtrƘ̫ &r࿁̻ණන੥ˊƷØ ɥᩭƷØՈ free_page_tables(get_base(current ->ldt[2]),get_limit(0x17)); free_page_tables(get_base(current ->ldt[1]),get_limit(0x0f)); // úẟ࣏ᯣᯧ₎΢4 // ₎΢ẟ࣏¤ŤϬՈͱƌाⒸ ẝₐ̵ƅĉŐ PCB ŤϬՈ 1 )ाⒸ ẝ 1 )ाⒸϵ int i; { int do_exit(long code) ϔż'ᡅՈ£࿁ɥ«₎΢ẟ࣏¤ŤϬՈᰈļĉŐrͱƌՈ âՈ਍਍4 ȺႮᵯՈźɍ᪂า& TASK_ZOMBIE ǜtẝźɍՈẟ࣏ɥˌẠ]Ć͹ᝯ᫇Ϭr4ẝ ϔ do_exit ͢ǒ«P]dz ࿁ẘúՈϔ ƷĆ᫇Ϭẟ࣏᫇òϔ Âńẝ7QĆ do_exit } return do_exit((error_code&0xff)<<8); // ቻǚdžϔżĺՈPƋᅆ { int sys_exit(int error_code) ňϵϔ do_exit ǀt4 Ʒ◄ᡅPẘúඝúẟ࣏ՈȨɆdžϔ úẟ࣏±±ȉΚdžϔ żĺՈPƋᅆ4ͣĿՈ̱ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_exit ǀt IJ«ƷՈͣĿǒɴẜ«-Ϭr sys_exit Ոƶ:4 ẟ࣏┨rႮ=Ƿ„ỄϦ ̲ ẜdz࿁«ᝯ͢Ʒẟ࣏ƆᜐǶ4ẝ̱ň ϵிඣ᫇Ϭ sys_kill /ϵிඣ᫇Ϭ sys_exit ʐ sys_waitpid ǀt4 úẟ࣏ǡǀtmŅՈ1ň4ẝ‡1ňک ʻ4&r࿁̻ᩭ úẟ࣏ ǣ4ẝ‡Ǎʻ Ƅẟ࣏ńỄϦՈrȅĆ̴ ₎΢ ¤þϬՈ ᰈļ ϢȒỞ ඌǶPẟ࣏ ◄ᡅ⓺ɉ ẝ«ü&ẟ࣏ń඗ǛՈr ȅ◄ᡅȕƷՈúẟ࣏ẘúP‡Ǎ ৰŅYতৰŅYতৰŅYতৰŅYত ẟẟẟẟ࣏ՈඌǶ࣏ՈඌǶ࣏ՈඌǶ࣏ՈඌǶ ৰ 138 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;struct task_struct **p = NR_TASKS + task { static void kill_session(void) ϬzŦ)ÑƟQẟ࣏&ȭ᪡͐ᾬՈẟ࣏4 kill_session ּ͟ϔּ͟ϔּ͟ϔּ͟ϔ } return (-1); /* just to suppress warnings */ // ˊ᩾Z«]dz࿁Ëᜐ4ẝₐՈ ┨☢ƅ bug schedule(); // ₑ,Ōϧẟ࣏᫇ò Ñūúẟ࣏Ťƅ CPU tell_father(current ->father); úẟ࣏ƿǀt͢ƷՈ1ňک// Ở current ->exit_code = code; // ljƌẟ࣏Ոඝúẟ࣏ՈẘúȨ current ->state = TASK_ZOMBIE; // ẝǮẟ࣏źɍ& TASK_ZOMBIE ᜬ߾ᰈļ>ඓ₎΢ ਍Ǒúẟ࣏ǀtmŅՈç¥ kill_session(); if (current ->leader) // ΞȘẟ࣏«Ć᪡Ո͐ẟ࣏ ẝₐɥᡅ₎΢ÑŦ)͢ƷÑƷ&ŊՈĆ᪡ last_task_used _math = NULL; if (last_task_used_math == current) tty_table[current ->tty].pgrp = 0; if (current ->leader && current ->tty >= 0) // ΞȘŤϬrඌ঳ ẝₐKᡅ₎΢ current ->executable=NULL; iput(current ->executable); current ->root=NULL; iput(current ->root); current ->pwd=NULL; iput(current ->pwd); sys_close(i); if (current ->filp[i]) for (i=0 ; istate == TASK_ZOMBIE) ৰ 139 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ˊ// ΞȘ flag & 1 ɥᜬ߾ȉΚ4rǍǻ ◄ᡅ̠ repeat: verify_area(stat_addr,4); struct task_struct ** p; int flag, code; { int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options) ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_waitpid } release(current); printk("BAD BAD - no father found \n\r"); /* This is not really OK. Must change it to make father 1 */ /* if we don't find any fathers, we jus t release ourselves */ } return; task[i] ->signal |= (1<<(SIGCHLD -1)); continue; if (task[i] ->pid != pid) continue; if (!task[i]) for (i=0;i ẝϔՈ1ň±±«ȕúẟ࣏ǕễPǍǻ Ι̨⁖Ʒǡ̠ˊǶẟ࣏ՈmŅ̱ň4 tell_father } } (*p)->signal |= 1<<(SIGHUP -1); if (*p && (*p)->session == current ->session) while (-- p > &FIRST_TASK) { // ̠ˊẝǍǻՈƉ¥࣏ÛϵிඣƉ¥࣏ÛȴƇ // â4¤ƅÑƟQẟ࣏&ȭ᪡͐Ոẟ࣏ ȕƷØǕễŦ)Ǎǻ SIGHUP 4 ৰ 140 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ // ljƌŭ+ᡅ˖̠ˊẋՈƄẟ࣏ǻ current ->cstime += (*p)->stime; current ->cutime += (*p)->utime; // ᩥਜ਼Ƅẟ࣏¤ŤϬՈȈିrⒸȨ Ϭ›࣏Ûdz࿁◄ᡅƷ case TASK_ZOMBIE: return (*p)->pid; // ẘúŭ+ᡅ˖̠ˊẋՈƄẟ࣏ úẟ࣏Ć-ϬՈẝȨՈ4 put_fs_long(0x7f,stat_addr) ; // Ոǜₓ stat_addr4 // ΞȘ̵ƅɉЩ TASK_STOPPED źɍՈƄẟ࣏ ɥȺ 0x7f ΢͑ŷȺẘúඝ᫇Ϭ࣏Û continue; if (!(options & WUNTRACED)) // ȭz TASK_STOPPED źɍՈƄẟ࣏ ΞȘ options « WUNTRACED ɥɉЩǭ case TASK_STOPPED: switch ((*p)->state) { // ẝźɍ4 // ()ọōϦǡՈẝƄẟ࣏Ոźɍ Ǯdz࿁« TASK_STOPPED z TASK_ZOMBIE } continue; if ((*p)->pgrp != -pid) } else if (pid != -1) { // ȭȨ4 // ΞȘ pid< -1 ᜬ߾ᡅ̠ˊʒzɌPĽǎẟ࣏ ඈՈƄẟ࣏ ẝƄẟ࣏Ոඈǻ« pid Ոඡ continue; if ((*p)->pgrp != current ->pgrp) } else if (!pid) { // ΞȘ pid =0 ᜬ߾ᡅ̠ˊ^úẟ࣏̠zȐPẟ࣏ඈՈƄẟ࣏ continue; if ((*p)->pid != pid) if (pid>0) { // ΞȘ pid>0 ᜬ߾Ƿń਍Ǒ̠ˊẟ࣏ǻ& pid ՈƄẟ࣏ ]«ẝǻՈƄẟ࣏ᝯɉЩ // Ո¤ƅƄẟ࣏4 ȌϦǡ Ξ Ș pid=-14ɥĆºẟ࣏ᜬọōϦ úẟ࣏ȭà // ĆΞŁ̠ˊ4ǒ ┉Z ǭ // Ñ[«ʵǒ pid Ո̑ΡǡΟǎ̠ˊ¬4ʳՈƄẟ࣏4Ʒ̵ƅº߾Ո᪸ŠΞȘ pid=-1 continue; if ((*p)->father != current ->pid) // ΞȘ]«Ⴎ=ՈƄẟ࣏ɥɉЩ ͼ͛ẝϔ±±Ć̠ˊႮᵯՈƄẟ࣏ continue; if (!*p || *p == current) // ɉЩȭႮᵯՈ̠ˊ for(p = &LAST_TASK ; p > &FIRST_TASK ; -- p) { // º task ȯâ◄ᡅ̠ˊẟ࣏ flag=0; ৰ 141 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ * XXX need to check permissions needed to send signals to process /* ̙ẟ࣏ՈňϬ4 ᩨՈ̱ň῁«ỄϦ ü ǸdzÑ᰻44ڌ çŁǍǻ4Ξ Șȭz ┨ SIGCHLD Ñ̲ՈçŁǍǻ ிඣ᫇Ϭ sys_kill ƨᯬZȺਜ਼ň«ǍǻՈČỖ4ƷdzÑ ʵǒdžϔՈ ̑Ρ ȕȈିẟ࣏Ǖễ ிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭிඣ᫇Ϭ sys_kill } return -ECHILD; ۅ// ̵ƅâ4Ƅẟ࣏ẘúϦ⏝ } return -EINTR; else ۅ// ΞȘǕɴẜƅ͢ƷՈǍǻ ɥẘúϦ⏝ goto repeat; if (!(current ->signal &= ~(1<<(SIGCHLD -1)))) // Ɵᆓ⁖7Ȓ Ǖɴ̨⁖ƷՈǍǻ±±« SIGCHLD ɥĆº͐ŌϧËᜐ sched ule(); current ->state=TASK_INTERRUPTIBLE; źɍ ẝʳ͢ƷՈǍǻKdz࿁Ⱥ̨͢⁖פ// ᪂าƟQẟ࣏&dz)ý return 0; if (options & WNOHANG) // ȏǶɳ4ÑႸ࣏ÛŦ᰻4 // ΞȘ option & WNOHONG ᜬ߾̵ƅǕɴƄẟ࣏ỄϦ ɥẘú Ở„ẝ࢑ẘúdz࿁Ụt if (flag) { // ΞȘ flag & 0 ᜬ߾ƟQẟ࣏ẜ̵ƅçŁƄẟ࣏ ẝ«]Ƿ„Ո4 } } continue; flag=1; // ᪂า flag & 1 ᜬ߾â4ẋᡅ˖Ոẟ࣏ IJ«̵ƅ̠ˊ4 default: return flag; put_fs_long(code,stat_addr); // ljƌỄϦẟ࣏ՈẘúȨ ඝ᫇ϬՈẟ࣏ release(*p); // rẝ1 CPU r4ϵz̵ƅΝǜƟQẟ࣏Ոźɍ üǸ]ɥƷẜĆúǡՈ4 // ඝ͢ƷՈẟ࣏̫ͥ1ňՈƶĆ WP͢ƷՈẟ࣏ȉΚ4Ǎǻrɦ,Sys_waitpid njūϬ // ₎΢Ƅẟ࣏Ո PCB ᜬŤϬՈẝ 1 )ाⒸ ẝϔūϬrẟ࣏᫇ò4K᩼«&r code = (*p)->exit_code; // ljƌƄẟ࣏ՈẘúȨ flag = (*p)->pid; ৰ 142 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;return retval retval = err; if (err = send_sig(sig,*p,0)) if (*p && (*p)->pgrp == -pid) else while (-- p > &FIRST_TASK) retval = err; if (err = send_sig(sig,*p,0)) } else if (pid == -1) while (-- p > &F IRST_TASK) retval = err; if (err=send_sig(sig,*p,0)) if (*p && (*p)->pid == pid) } else if (pid>0) while (-- p > &FIRST_TASK) { retval = err; if (err=send_sig(sig,*p,1)) if (*p && (*p)->pgrp == current ->pid) if (!pid) while (-- p > &FIRST_TASK) { int err, retval = 0; struct task_struct **p = NR_TASKS + task; { int sys_kill(int pid,int sig) ẘú 04]ǕễǍǻ IJ¹Ćẟᜐ⏝̼᪳ɡ4ΞȘt£ // ΞȘǍǻ sig & 0 Ǎǻ sig ȺǕễඝẟ࣏ඈ-pid Ո¤ƅẟ࣏4 // ΞȘ pid < -1 Ǎǻ sig ɥĆǕễඝ┨ৰPẟ࣏̲Ո¤ƅẟ࣏4 // ΞȘ pid=-1 // ΞȘ pid=0 ὧ4ǍǻɥĆᝯǕễඝƟQẟ࣏Ոẟ࣏ඈՈ¤ƅẟ࣏4 ǍǻᝯǕễඝ pid 4 // ΞȘ pid Ȩ>0 */ * groups, etc. etc. kill() permissions semantics are tricky! ৰ 143 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ else buffer_memory_end = 2*1024*1024; else if (memory_end > 6*1024*1024) buffer_memory_end = 4*1024*1024; if (memory_end > 12*1024*1024) memory_end = 16*1024*1024; if (memory_end > 16*1024*1024) ɉЩ͢]ᱷ 4k Ƌᅆǣͱƌϔẝʳƫzᩥਜ਼)ϔ memory_end &= 0xfffff000; Ȩ Ñ K &řĹ4üǸẝrȅǣ4ǣͱƌ̓Ƀ«ǒ┉ǣ̓Ƀ PĆ̫ɥĆîƷǜɃr4 ΢4º 0x90000 Ōϧǣͱƌr ͢ 0x90002 ƌ΢ ǣ«ிඣº 1M Ōϧ ǣÍʉͱƌ ǣϔ ǒ(ͼ͛ń VC Ո short ିƧ« 4 Ƌᅆ)4ń setup.s >ඓȺº BIOS Ո ǣ4Ǎʻƌ EXT_MEM_K ᝯǎ5&(*(unsigned short *)0x90002)4ŷǚ 0x90002 ̠ՈƋᅆՈϔ memory_end = (1<<20) + (EXT_MEM_K<<10); ȭzͱƌՈ!ϧĚº main() ϔ(/init/main.c) ɥŌϧr Ōϧr᪂าͱƌՈɲŌŜ4 ‑̑Ρ ͱʴ࣏Û ʌợ෗ƌ 'ͱƌ ᰻ϧŌŜ 0X000000 0X100000 0X400000 ‑ᜬΞ[ ŜाⒸɥඝ'ͱƌr4üǸाⒸ ͱʴ࣏Û ŤϬ 1M ՈŌŜाⒸ ʌ ợ෗ƌŤϬ╓ȒՈ 3M ՈŌŜाⒸ Ņ[Ո 12M Ō Ȑʳ&rᅆׅ࿕ඊྡྷ uɥ]໇ᔕᔞŃ֜r ǑǷK̵ƅ¬4Ϭ☺4 ͱʴ࣏Û ʌợ෗ƌ ᔞŃ֜ 'ͱƌ Ξ[ᜬ Linux0.11 ȭẝ 16M Ոͱƌ Ȍr4 16M ǡ ȌɥƟňͱƌ ῁Ć᱉ ẋ Č ▂ ¤ÑÑȒՈף zֲ Qâ4Pͱƌ Ƀz 16M Ոᩥਜ਼ƶ ń Linux0.11 ±±ūϬ 16M ͱƌ ¤ÑΞȘͱƌ᱉ẋ 16M Ո᪡ɥ ŭ+ 16M ᩥਜ਼4 ϵ !ϧĚ!ϧĚ!ϧĚ!ϧĚ ńͱƌ੥ˊKŤƅǔₑᡅՈŌĹ4ẟ࣏ՈËᜐɥ«Ɖ☤ƷǡǒɴՈ4 Linux ūϬr΅̩:Ո5ͩǡūϬͱƌ ȴʌrͱƌՈ-Ϭɋ4ü Ǹ ͱƌՈŎ„̠ˊ ȐՈᔞŃŌŜœȸ4ȐPųͱƌľǻ4 ẟ࣏Ոr ȅ Ƅẟ࣏◄ᡅ^ úẟ࣏ ͝— ȐPͱƌाⒸ4ẝ̱ň ɥ«-Ϭǜdžƶ: Ⱥ] ņϵzūϬrᔞŃŌŜ ü Ǹ Linux ȴƇrºᔞŃŌŜ4ǒ┉ŌŜՈǜĚՈ̱ň4ń ϬƵϔ4Ɵ& 0 Ոrȅ ᜬ߾ּàՈ)«ाⒶՈ4 ՈɣP-Ïᜬr ͱƌ┨ிඣाⒸ7̲Ոɣ)ͱƌ4ϔ ඈɣP-ՈȨᜬ߾ּàՈ)Ոš &r࿁̻ ƅάՈ੥ˊͱƌՈȈ) Linux ᪂าrPϔඈǯɆ ͱƌ)œȸᜬ4ᜬ 4ljĈµśՈḰdž4 ᢧr dzÑ᪸^ͱƌż'ᡅՈ!ϧĚ« ńšȰՈrȅǀtՈ4ńšȰՈr ȅǀtrºǒµś ᩶ Linux ȭͱƌՈ੥ˊ« ȖzljĈµśՈ)ś੥ˊՈ4͟z)ś੥ˊ>ඓ ńšȰᾬ ৰŅ÷তৰŅ÷তৰŅ÷তৰŅ÷ত ͱƌ੥ˊͱƌ੥ˊͱƌ੥ˊͱƌ੥ˊ ৰ 144 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ àՈ௦šǻ4 I)̓Ƀ4͢ I «ᜬּ ிඣाⒸ̓Ƀ Ⓒ«PඃɳՈǜdž4 ͘ś«)ĭˊŌŜ ‑r^ͱƌ)ՈϔₓּàՈाⒸ ü Ǹᜬ^ͱƌ) 7 Ոͱƌ)4ͱƌ)œȸᜬń࣏Û ɥ «]̭᩼ūϬՈ üǸͱƌ)œȸᜬ±±ȭà؄┨ிඣाⒸÑ̲ ϵzிඣाⒸ1M ͱƌ)œȸᜬͱƌ)œȸᜬͱƌ)œȸᜬͱƌ)œȸᜬ } mem_map[i++]=0; // Ⱥ'ƌẝɉՈ)☦œȸᜬ±► while (end_mem -- >0) end_mem >>= 12; // ᩥਜ਼'ƌՈ)ϔ end_mem -= start_mem; i = MAP_NR(start_mem); // ńẝₐ«&rǣ4'ƌՈ᰻ϧ)ǻ4 // MAP_NR(addr) ǎ5& (((addr) -LOW_MEM)>>12)Ϭǡᩥਜ਼ addr Ո᰻ϧ)ǻ Ϭ mem_map[i] = USED; for (i=0 ; iඓᝯŤϬ4ẝɉÏ // #define PAGING_PAGES (PAGING_MEMORY>>12)dzÑ׏Ϧǡ PAGING_PAGES // ʵǒǃǎ5#define PAGING_MEMORY (15*1024*1024)ʐ HIGH_MEMORY = end_mem; int i; { void mem_init(long start_mem, long end_mem) * / * (C) 1991 Linus Torvalds * * linux/mm/memory.c /* [ Ξۅ) ΢4ͱƌœȸᜬ mem_map[] 4Ï main_memory_start ʐ meory_end 7ⒸՈͱƌ ẝϔՈǒɴ΢ ńr/mm/memory.c  ẝ«ͱƌ!ϧĚՈ 'Ŀ 4ƷՈňϬ«Ⱥ mem_init(main_memory_start,memory_end); ẝrȅɥǣ4rʌợ෗ƌʐ'ͱƌǣ᰻ϧŌŜ ȐrȺͱƌ└:ń 16M Ñͱ4 #endif main_memory_start += rd_init(main_memory_start, RAMDISK*1024); #ifdef RA MDISK main_memory_start = buffer_memory_end; buffer_memory_end = 1*1024*1024; ৰ 145 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ,(:"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES :"=a" (__res) "1:" "movl %%edx,%%eax\n" "rep ; stosl \n\t" "leal 4092(%%edx),%%edi\n\t" "movl $1024,%%ecx \n\t" "movl %%ecx,%%edx\n\t" // ±ा᪩ͱƌ) "addl %2,%%ecx \n\t" "sall $12,%%ecx \n\t" // ͹¤ZϬ›ाⒸՈŊŌŜ // ϵzɣ)ŤϬ 41024 ƋᅆՈͱƌü Ǹȭà᪩)Ոͱƌ& ᪩-ǻ2ࢿ 12 ĹՈȨ "movb $1,1(%%edi) \n\t" // â4Ո᪡ɥ᪂& 1 ᜬ߾ŤϬr,ϵz7Q edi ՈȨႮ¬λ 1 r,üǸẝₐᡅ¤úƿ "jne 1f\n\t" // ΞȘ̵ƅâ4Ո᪡ɥẘú,ẝrȅ eax & 0 __asm__("std ; repne ; scasb \n\t" // dzÑȺϵ get_free_page ϔẘúՈŌŜƟɆͱƌՈ̳PĭˊŌŜǡūϬ4 üǸẝᔞŃŌŜ«ˌẠ^ͱƌĭˊŌŜPPȭàՈ4ɥ«᪸ // ĹzͱʴाⒸ // 4 ֲơ-Ո njϵ zẝ 4 ֲơ-ǎ͢ȭàՈ)ᜬ«ˌẠ]Ćᝯ࣏Û ΝǜՈü& // ʃǻ ϢȒᩥਜ਼ϦǡᔞŃŌŜ4ẝᔞŃŌŜPǎ«ūϬȭàՈ«ֲơᜬՈQ // ϵzẝϔՈǣ4ाⒶ)ՈŌŜՈ5ͩ«º mem_map ϔඈâ4Ʀʃ᪊Ո- // ºżȒP-ŌϧȕQʀ௦ϔඈ mem_map,ɡâֲQ̵ƅūϬՈ-(Ȩ& 0) register unsigned long __res asm("ax"); { unsigned long get_free_page(void) ẘúּà)ՈŊŌŜ// ẘúȨ: ΞȘ̵ƅाⒶՈͱƌ)ɥẘú 0,Ȫ // %4(di=&mem_map[PAGING_PAGES-1]) // džϔ%1(ax=0); %2(LOW_MEM ☢ிඣाⒸՈŊŌŜ; %3(cx=ͱƌ)ϔ); // Ⱥ᪩ͱƌ)ՈŊŌŜẘú // ẝϔºżȒP)ͱƌŌϧȕQʀ௦ ָ4â4P)ֲQ̵ƅūϬẋՈͱƌ */ * used. If no free pages left, return 0. * Get physical address of first (actually last :-) fr ee page, and mark it /* ϔϔϔϔ get_free_page ň͢ǒɥ«ȭͱƌ)œȸᜬՈ̱ň4 ϵzPͱƌ)«ȪdzÑūϬǀ͔ϵͱƌ)œȸᜬ mem_map[] ǡΟǎ üǸȭ)Ո̱ )Ոቻǚ^₎΢)Ոቻǚ^₎΢)Ոቻǚ^₎΢)Ոቻǚ^₎΢ ৰ 146 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ΅Ϧǡ4 ͩuẜ«̿]Ở4ÄΙ Ǯƅ fork ẝϔ᫇ϬrƷ4u̴Ⱥu¤ˊᢧՈᾬ 'copy_page_tables()' 9ϵzuՈͰɞ ̭᪻᩼uȺ bitch ຿᪕t8~Ƅ9 4ֲ QȭzƷՈP ‡Ɇ Linus ń ͼ ₎  ΅ ἗8but the memory ma nagement can be a bitch. See 'mm/mm.c': ǷΞLinusńẝϔQՈͼ₎¤᪸Ո ƷՈ ܲ«uֲ Q¤ᢅ4Ոż&͐ ҟՈPϔ4 ϔϔϔϔ copy_page_tables ]c̩᪻L7Ȓ͹׏4 Ȍ Ȑrẝ ₐ☦5ǎ4rǔ̶^ljĈµś[)ś੥ˊáɶǒɴՈඊᅆ Ξ ȘȭǸ ◄ᡅήή ņʐǶūϬr4Ʒ ØՈǒɴ ɨṇഅ˔₎΢ֲơ -4ȭֲơᜬՈẝ‡̱ň±±ńẟ࣏Ո ȭֲơᜬՈ̱ň^ȭẟ࣏Ո̱ňǔʻ ĉŐrϣt,Ոֲơ-śᯡ>ƅՈֲơ- ȭֲơᜬՈ̱ňȭֲơᜬՈ̱ňȭֲơᜬՈ̱ňȭֲơᜬՈ̱ň } panic("tryi ng to free free page"); mem_map[addr]=0; if (mem_map[addr] --) return; // λɅPƵ᪩)ՈšϬϔ addr >>= 12; addr -= LOW_MEM; // ǣ4᪩ͱƌŌŜȭàՈͱƌ) panic("trying to free nonexistent page"); if (addr >= HIGH_MEMORY) // ᱉ẋrͱƌՈᇇĐ š᰻Ϧ⏝ if (addr < LOW_MEM) return; // 1M P[ūிඣाⒸ]࿁̱ň { void free_page(unsigned long addr) // Ɉƶ4ƷՈǒɴǔ੄ř ɥ«ńͱƌ)œȸᜬȺּà)ՈšϬȨλ 1 ‑Ոͱƌ)ĆȰႸ // Ϭz₎΢>ඓ☢‑ẋՈͱƌ) ΞȘ᪙Ě₎΢ֲQɎƦ */ * 'free_page_tables()' * Free a page of memory at physical address 'addr'. Used by /* ϔϔϔϔ free_page } return __res; :"di","cx","dx"); "D" (mem_map+PAGING_PAGES -1) ৰ 147 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ /* return -1; /* Out of memory, see freeing if (!(to_page_table = (unsigned long *) get_free_page())) // )ᜬՈŊŌŜ4̩:Ո̱ňɥ«ºƷŌϧՈ4)ᜬՈ̓Ƀ« 4k ǷΙP)̓Ƀ // ቻǣPֲQ̵ƅūϬẋՈ)ՈŊŌŜ ẝ)ŌŜɥ«ֲʃֲơ-¤ūȕՈ from_page_table = (unsigned long *) (0xfffff0 00 & *from_dir); // ńֲơ-Ոʌ 20 Ĺƌ΢Ո«ֲơ-ȭàՈ)ᜬՈŊŌŜ continue; if (!(1 & *from_dir)) // ȭz̵ƅ!ϧĚẋՈֲơ-]Ëᜐ̩:̱ň panic("copy_page_tables: already exist"); if (1 & *to_dir) // ֲơ-̩:ՈrȅɥĆϦ⏝ // Ƿ„̑Ρ[Ȉẟ࣏ƅ͢ưƅՈֲơ- üǸΞȘǕϣȕP>ඓƌńՈ for( ; size -- >0 ; from_dir++,to_dir++) { ͢ǒȭz̵ƅ!ϧĚẋՈֲơ-«]Ć̩:Ո4// ɥϦ⏝rț 164ń!ϧĚՈrȅ ிඣ±±ǎ5r 4 ֲơ- ΞȘ̩:r 16 -] // size // ŌϧǶɳՈ̩: ϵzńšȰՈrȅ>ඓȺɉА└᪂า& 16M üǸẝₐ size = ((unsigned) (size+0x3fffff)) >> 22; // ᩥਜ਼ᡅࢿ¬ՈͱƌϔȭàŤϬՈֲơ-ϔₓ ¤Z 0x3fffff «&rẟĹ to_dir = (unsigned long *) ((to>> 20) & 0xffc); from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ // ^Z 0xffc «&rlj᪅ẝŌŜ« 4 Ոǹϔ (addr>>20)// njϵzP-« 4 Ƌᅆ¤ÑȭàՈĭˊŌŜà᪩«(addr>>22)4 // ϵzֲơᜬ-Ո௦šǻĹzඃɳŌŜՈQ 10 Ĺ ¤Ñ௦šǻ« addr>>224 // ºඃɳŌŜǣ4ּàՈֲơᜬ-ՈŌŜ4 panic("copy_page_tables called with wrong ali gnment"); if ((from&0x3fffff) || (to&0x3fffff)) // ẟ࣏ाⒸՈŌŜȑ/«Ñ 4M &ṽА unsigned long nr; unsigned long * from_dir, * to_dir; // ūȕ᰻ϧֲơᜬ-ʐֲʃֲơᜬ-Ոū⍌ unsigned long this_page; unsig ned long * to_page_table; // ūȕֲʃ)ᜬ-Ոū⍌ unsigned long * from_page_table; // ūȕ᰻ϧ)ᜬ-Ոū⍌ { int copy_page_tables(unsigned long from,unsigned long to,long size) ơ-ȭàՈ)̠4 ơ-â4 ϢȒ˖Ϧdžࢿ¬Ոֲơ -ϔₓ4 żȒ.ÛՈȺ᰻ϧֲơ-ȭàՈ) ̩:4ֲʃֲ ẝϔՈǒɴɩ̿͢ǒǔ੄řՈ ὧɥ «̴Ⱥ᰻ϧŌŜȭàՈֲơ-ʐֲ ʃŌŜՈֲ 4G4Intel ̭᩼ūϬՈᔞŃाⒸ̓Ƀ4[ 6464M uᩨ&ẝ4 Ɇ«ǔȌˊՈ ŌdzÑᩥਜ਼P ǡǣ44 nr «᪩ẟ࣏ńẟ࣏ᜬȭàՈĹาǻ 4ẝʳ˖ǣẟ࣏ाⒸՈŊŌŜɥdzÑūϬ nr0x4000000 ⒸⒸ╘« 0x4000000 Ƌᅆ64M Linux0.11 ż̶̭᩼ 64 ẟ࣏ ඝɣ ẟ࣏ՈᔞŃाⒸ« 64M4ü Ǹ Ȉẟ࣏Ոा ৰ 148 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ (if (from & 0x3fffff // ẜ«()«Ȫ«Ñ 4M ṽ͓ unsigned long * dir, nr; unsigned long *pg_table; { int free_page_tables(unsigned long from,unsigned long size) */ * by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks. * This function frees a continuos block of page tables, as needed /* ƅ̩:ႮϢɥƅ₎΢r ₎΢Ոǒɴּȭz̩:ǡ᪸੄ř̶r4 ϔϔϔϔ free_page_tables } return 0; invalidate(); } } } mem_map[this_page]++; this_page >>= 12; this_page -= LOW_MEM; *from_page_table = this_page; if (this_page > LOW_MEM) { // ΞȘ]₎΢Ո᪡ ẝɥȰႸr͹ūϬ fork Ոrȅ\dzϬाⒸՈȳᬥ // ΞȘǕɴᝯ̩:Ո)]ńிඣाⒸ(1M)  ẜᡅʺ¤᪩)ՈšϬƵϔ4 *to_page_table = this_page; this_page &= ~2; continue; if (!(1 & this_page)) „// ᪂าẝ)΅ljĈ ΞȘȕ᪩)ՈाⒸËᜐ΅̱ňɥĆšǕŎ this_page = *from_page_table; // ǚǣļ)-ՈȨ for ( ; nr -- > 0 ; from_page_table++,to_page_table++) { // ]̭᩼Ëᜐ΅̱ň4 // ͱƌ)œȸᜬȺּà)ՈšϬ Ƶϔ¤ 14ϵzǕϣr)Ո͝— ü Ǹẝr ȅ // ΞȘ᰻ϧ)̵ƅūϬɥ]̩: ΞȘ᰻ϧ)̠ńϬ›ाⒸ ẜᡅ4ּàՈ // º᰻ϧ)Ōϧȕֲʃ)ẟᜐ̩: Ở„P͝Ć̩: 1024 )4ֲʃľ nr = (from==0)?0xA0:1024; // ()«Ȫᡅ̩:ͱʴՈाⒸ ȭzͱʴाⒸ±±̩: 160 )640k *to_dir = ((unsigned long) to_page_table) | 7; // ΅3Ëᜐ ʃ᪊&>ඓŤϬ4 ‑Ո)ᜬ Ȑr᪂าƷՈʒɳ&Ϭ›ɍ dzᪿ3 // ᪂าֲʃֲơ-ū͢ūȕ, ৰ 149 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ Ŝ4ǒ┉ŌŜՈǜdž« Ởẋֲơᜬʐ)ᜬǒɴՈ ü Ǹ±±Ởẋ᪂าֲơᜬʐֲơ-ɥdzÑ ĭˊՈͱƌ)^PᔞŃŌŜņ এœȸ͟ி4ẝœȸՈņএrǔ੄řՈ ü&ϵᔞŃŌ ẝϔ«ϬzȺPĭˊՈͱƌ)΢4ūǎՈᔞŃŌŜ ͢ǒβܲՈ᪸à᪩«ȺP ϔϔϔϔ put_page ƮtּàՈœȸ Linux ūϬrϔ4Put_page ʐ get_empty_page ϵzń Linux ūϬՈŌŜ ῁«ᔞŃŌŜ &r࿁̻ūǣPᔞŃŌŜ ࿁̻ ^ĭˊŌŜ ᔞŃŌŜ4ĭˊŌŜՈœȸ̱ňᔞŃŌŜ4ĭˊŌŜՈœȸ̱ňᔞŃŌŜ4ĭˊŌŜՈœȸ̱ňᔞŃŌŜ4ĭˊŌŜՈœȸ̱ň } return 0; invalidate(); } *dir = 0; // Ⱥ᪩ֲơ-±ाᜬŠ᪩ֲơ-̵ƅūϬ free_page(0xfffff000 & *dir); // ₎΢᪩ֲơ-º'ƌǚǣՈὧP)4 } pg_table++; *pg_table = 0; // Ⱥ᪩)±ाᜬŠ>ඓ₎΢ free_page(0xfffff000 & *pg_table); if (1 & *pg_table) // Ƶϔ // ()᪩)«ȪᝯūϬẋ ΞȘūϬẋɥƿ₎΢᪩)͢ǒɥ«λɅ᪩)ȭàՈšϬ for (nr=0 ; nr<1024 ; nr++) { // Ⱥ᪩ֲơ-ȭàՈ 1024 )₎΢ pg_table = (unsigned long *) (0xfffff000 & *dir); // ºֲơ-Ո4ּàՈ)ᜬŌŜ continue; if (!(1 & *dir)) // ΞȘǕɴ᪩ֲơ-̵ƅūϬ ɥ⏝ẋƿ for ( ; size -- >0 ; dir++) { dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ size = (size + 0x3fffff) >> 22; // ǣ4ɉА└ȭàՈֲơ-ϔ à᪩« 4 4ʐֲơ-ՈŊŌŜ panic("Trying to free up swapper memory space"); if (!from) // ºϢẝ«]dzÑՈ4 // ϵzͱʴाⒸȭàՈŌŜ« 0x0000 üǸΞȘǕɴ from & 0 ɥ«ᡅ₎΢ͱʴाⒸ panic("free_page_tables called with wrong alignment"); ৰ 150 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;return page // ẘú)ՈĭˊŌŜ /* no need for invalidate */ page_table[(address>>12) & 0x3ff] = page | 7; // )-ūȕּà)ՈĭˊŌŜ // ẝrȅ page_table >ඓ ūȕrᔞŃŌŜȭàՈ)ᜬŊŌŜ ϢȒᩭᔞŃŌŜȭàՈ } page_table = (unsigned long *) tmp; *page_table = tmp|7; return 0; if (!(tmp=get_free_page())) // ՈͱƌाⒸň&ẝֲơ-ȭàՈ)ᜬ4ϢȒᩭ page_table ūȕẝ)ᜬՈŊŌŜ ‑)ͱƌाⒸ ūϬẝ 4k // ΞȘǕɴẝֲơ-ẜ̵ƅūϬ ɥƦẝֲơ- else { page_table = (unsigned long *) (0xfffff000 & *page_table); // ŊŌŜ // ΞȘǕɴẝֲơ->ඓƅrႮ=Ո)ᜬ ᩭ page_table ūȕֲơ-ȭàՈ)ᜬՈ if ((*page_table)&1) // ()P[ẝֲơ-«Ȫ>ඓūϬẋr ŷ«Ȫ>ඓūȕrPƅάՈ)ᜬŊŌŜ page_table = (unsigned long *) ((address>>20) & 0xffc); // ǚǣɡâᔞŃͱƌr¤ᡅūϬՈֲơ-ŌŜ printk("mem_map disagrees with %p at %p \n",page, address); if (mem_map[(page-LOW_MEM)>>12] != 1) ‑Ոͱƌ)«Ćᝯᡊ֚ǭՈ4 // >ඓᝯ₎΢ǭr ɥᡅඝϦȴ߾Ǎʻ4ü&̵ƅ ‑z؄ // ΞȘǕɴẝĭˊ)ńͱƌ)œȸᜬ̵ƅʃᩴ ^ẝĭˊ)ẜ̵ƅᝯ printk("Trying to put page %p at %p \n",page,address); if (page < LOW_MEM || page >= HIGH_MEMORY) // Ϧȴ߾ // ΞȘǕɴẝͱƌ)ŌŜĹzͱʴाⒸz້>ඓ᱉ẋrż̭̓᩼ͱƌाⒸɥĆඝ /* NOTE !!! This uses the fact that _pg_dir=0 */ unsigned long tmp, *page_table; { unsigned long put_page(unsigned long page,unsigned long address) // ϔȺ page Ȩẘú // page «ƣ)ՈĭˊŌŜ address «džƌ΢᪩)ՈᔞŃŌŜ */ * page.) * out of memory (either when trying to access page-table or * It returns the physical address of the page gotten, 0 if * This function puts a page in memory at the wanted address. /* ǒɴr \◄ẟᜐϘ)Ո̩:4 ৰ 151 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ pushl %edx // ň&džϔƏʄ movl %cr2,%edx  // Ⱥš᰻Ϧ⏝ՈᔞŃŌŜ΢͑ edx mov %dx,%fs mov %dx,%es mov %dx,%ds movl $0x10,%edx push %fs push %es push %ds pushl %edx pushl %ecx xchgl %eax,(%esp)  ΢͑ eaxۅ// ȺϦ⏝ _page_fault: Ոͱǭ^)ிඣ·එՈPʳ dzÑdž໇ὧPত4 ńẟ͑⓺ɉ◄ᡅ()š ǕŎ„Ո᰻ü ẟ ໐Οǎ̠ˊ⓺ɉϵˮPϔǡǀt4ẝᾬ Ŏ„Ոẟ͑^ỄϦ⓺ɉŎ„Ոẟ͑^ỄϦ⓺ɉŎ„Ոẟ͑^ỄϦ⓺ɉŎ„Ոẟ͑^ỄϦ⓺ɉ ࢑̑Ρ4 ᡅ üǸKĆšǕŎ„4ẝr ȅ ̱ňிඣ◄ᡅẟᜐ࣏ÛՈ¤ṁ4ü Ǹ ńŎ„̠ˊՈrȅ◄ ‑ाⒸ4Ǫ̲ ń࣏ÛËᜐՈr ȅ ϵzᡅūϬՈᔞŃͱƌẜ̵ƅ᪂ǎΙ ிඣ±Ć &͢ rȅĆȺ͝—ՈाⒸ᪂า&΅ljĈ ẝ ʳńϦɴ΅̱ňՈr ȅɥĆšǕŎ„4ẝr ȅ̱ň ņՈ4ńẟ࣏܄ Ʒ«ǒɴ΅r̩:ǒɴՈȖ ńͱƌ੥ˊŎ„̠ˊ«ǔₑᡅՈᾬ Ŏ„̠ˊŎ„̠ˊŎ„̠ˊŎ„̠ˊ } } oom(); free_page(tmp); /* 0 is ok - ignored */ if (!(tmp=get_free_page()) || !put_page(tmp,address)) { unsigned long tmp; { void get_empty_page(unsigned long address) ϬzቻǚÑᔞŃŌŜ address &ŊՈP)ͱƌ4 ϔϔϔϔ get_empty_page ৰ 152 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ((if (share_page(tmp // Qẟ࣏^â4Ոẟ࣏͝—ȐPųͱƌाⒸ // &rᅆׅाⒸ ẟ࣏ĆƿȯâPūϬrȐPdzËᜐâՈẟ࣏4ΞȘâ4rƟ } return; get_empty_page(address); if (!current ->executable || tmp >= current ->end_data) { // ȭzÑZ 2 ࢑̑Ρ]◄ᡅ¤ṁâ Ǯ◄ᡅńͱƌቻǚP)ाⒸ ᫇Ϭr fork ẜ̵ƅ᫇Ϭ execve 4// ΞȘ executable & Null ᜬ߾ // ΞȘȻࢿŌŜ᱉ẋr࣏ÛՈϔǒɉ ᜬ߾࣏Û>ඓ͔ᾬ¤ṁrIJ«◄ᡅQ̲ՈाⒸ tmp = address - current ->start_code; // ᩥਜ਼ᔞŃŌŜńẟ࣏ाⒸՈȻࢿŌŜ address &= 0xfffff000; // ቻǚᔞŃŌŜ¤ń)☦ՈŊŌŜ int block,i; unsigned long page; unsigned long tmp; int nr[4]; { void do_no_page(unsigned long error_code,unsigned long address) Ở„«ń◄ᡅ¤ṁ࣏Û4ͱƌՈrȅ±šǕẝ̱ňՈ4 ϔϔϔϔ do_no_page ̠ˊ⓺ɉ̠ˊ⓺ɉ̠ˊ⓺ɉ̠ˊ⓺ɉ iret popl %e ax popl %ecx popl %edx pop %ds pop %es pop %fs 2: addl $8,%esp // ẜƣɳʟǜₓ 1: call _do_wp_page jmp 2f call _do_no_page jne 1f testl $1,%eax „// ΞȘ]« 1 ᜬ߾«ϵz΅ljĈšǕՈŎ „ᜬ߾«ϵz෾)šǕՈŎ 1 »ۅ// ΞȘϦ⏝ pushl %eax ৰ 153 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ (if (!current ->executable —// ΞȘ executable &ा ᜬŠ̵ƅẟ࣏ūϬẝâ üǸ\ͩ͝ struct task_struct ** p; { static int share_page(unsigned long address) */ * It should be >1 if there are other tasks sha ring this inode. * We first check if it is at all feasible by checking executable ->i_count. * * to the current data space. * the current one. Address is the address of the wanted page relative * share_page() tries to find a process that could share a page with /* ϔϔϔϔ share_page ‑ͱƌ4 ͹&ẝâₑ, ƅϬՈ Ξ ȘPdzËᜐâϵ ẟ࣏ǡËᜐ ü&ËᜐՈr ȅ±±« ᪿ̱ň ̵ƅȑᡅ ǮƅPẟ࣏>ඓ ¤ṁrdzËᜐâ4ͱƌ ͢ƷՈẟ࣏ ±dzÑ͝—4ẝ࢑ 5ͩ« ǔ ͝—ͱƌ͝—ͱƌ͝—ͱƌ͝—ͱƌ } oom(); free_page(page); return; if (put_page(page,address)) // ņএᔞŃŌŜ4ĭˊŌŜՈœȸ } *(char *)tmp = 0; tmp --; while (i -- > 0) { tmp = page + 4096; i = tmp + 4096 - current ->end_data; ‑P)ाⒸ7Ȓ dzϬՈͱƌ᱉ẋrâ̓Ƀ4◄ᡅȺ̶ŅՈͱƌ±► // ΞȘ, bread_page(page,current ->executable ->i_dev,nr); nr[i] = bmap(current ->executable,block); for (i=0 ; i<4 ; block++,i++) block = 1 + tmp/BLOCK_SIZE; /* remember that 1 block is used for header */ // ᩥਜ਼◄ᡅ¤ṁՈ̓Ƀ oom(); if (!(page = get_free_page())) ‑P)ĭˊͱƌ // ΞȘ̵ƅâ4dzÑ͝—Ո ɥ&ẝẟ࣏ return; ৰ 154 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ;from = *(unsigned long *) from_page ǚ᪩ֲơ-ȭà)ᜬŌŜẘú4Ȫ // ǚ)ֲơ-ͱǭ4ΞȘ᪩ֲơ-\ά(P=0) /* is there a page-directory at from? */ to_page += ((current ->start_code>>20) & 0xffc); from_page += ((p ->start_code>>20) & 0xffc); ᰻ϧŌŜՈֲơ-ŌŜ ȻࢿŌŜՈֲơ-ŌŜ// ᔞŃŌŜȭàՈֲơ- from_page = to_page = ((address>>20) & 0xffc); // ቻǚͱƌּȭȻࢿŌŜՈֲơ-ŌŜ unsigned long phys_addr; unsigned long to_page; unsigned long from_page; unsigned long to; unsigned long from; { static int try_to_share(unsigned long address, struct task_struct * p) */ * share the same executable. * NOTE! This assumes we have checked that p != current, and that they * * task. * to see if it exists, and if it is clean. If so, share it with the current * try_to_share() checks the page at address "address" in the task "p", /* ϔϔϔϔ try_to_share } return 0; } return 1; if (try_to_share(address,*p)) // ^ẝẟ࣏͝—P)ͱƌ continue; if ((*p)->executable != current ->executable) continue; if (current == *p) co ntinue; if (!*p) for (p = &LAST_TASK ; p > &FIRST_TASK ; -- p) { // ºẟ࣏ඈȺ^ƟQẟ࣏ūϬȐPâՈẟ࣏â4 return 0; if (current ->executable ->i_count < 2) —// ΞȘẝâՈšϬƵϔɃz 2 ᜬ߾ǮƅPẟ࣏ūϬẝâ \ͩ͝ return 0; ৰ 155 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ẝϔϬzËᜐ΅r ̩:ẝ̱ň Ɵƅ ̶ẟ࣏͝—PɉͱƌाⒸՈrȅ ĆȺẝ ϔϔϔϔ do_wp_page } return 1; mem_map[phys_addr]++; phys_addr >>= 12; phys_addr -= LOW_MEM; // ᩥਜ਼¤̱ň)☦Ո)☦ǻ ÂȺȭà)☦œȸϔඈ-ՈšϬỖʺ 1 invalidate(); *(unsigned long *) to_page = *(unsigned long *) from_page; *(unsigned long *) from_page &= ~2; // Ʒ // ȭ p ẟ࣏) ☦า΅ljĈ ʃȣ(า R/W=0 Ǯᪿ )4ÂƟQẟ࣏Ոȭà)ᜬ -ūȕ /* share them: write -protect */ panic("try_to_share: to_page already exists"); if (1 & *(unsigned long *) to_page) to_page = to + ((address>>10) & 0xffc); to &= 0xfffff000; Ϧ⏝ ȏƶ // ǚ)ᜬŌŜ4ΞȘȭàՈ)☦>ඓƌń oom(); else *(unsigned long *) to_page = to | 7; if (to = get_free_page()) if (!(to & 1)) to = *(unsigned long *) to_page; // Ոֲơ- ǚाⒶ)☦ ÂŰ, to_page ¤ū // ǚ)ֲơ-ͱǭ4ΞȘ᪩ֲơ-\ά(P=0) return 0; if (phys_addr >= HIGH_MEMORY || phys_addr < LOW_MEM) phys_addr &= 0xfffff000; // ǚ)☦ՈŌŜ4ΞȘ᪩)☦ŌŜ]ƌńzɃzͱƌĺ঳(1M) KẘúỄϦ return 0 if ((phys_addr & 0x41) != 0x01) ẘú// 0x41 ȭà)ᜬ-Ո Dirty ʐ Present ʃȣ4ΞȘ)☦]¾άz\ά /* is the page clean and pre sent? */ phys_addr = *(unsigned long *) from_page; from_page = from + ((address>>10) & 0xffc); // ᩥਜ਼ŌŜȭàՈ)ᜬ-ū⍌Ȩ ÂǚϦ᪩)ᜬ-ͱǭ from &= 0xfffff000; return 0; if (!(from & 1)) ৰ 156 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ { ;(((((*((unsigned long *) ((address>>20) &0xffc (((address>>10) & 0xffc) + (0xfffff0 00 & un_wp_page((unsigned long *) #endif do_exit(SIGSEGV); if (CODE_SPACE(address)) /* stupid, stupid. I really want the libc.a from GNU */ /* we cannot do this yet: the estdio library writes to code space */ #if 0 { void do_wp_page(unsigned long error_code,unsigned long address ) */ * If it's in code space we exit with a segment error. * * and decrementing the shared -page counter for the old page. * to a shared page. It is done by copying the page to a new address * This routine handles present pages, when users try to write /* } copy_page(old_page,new_page); invalidate(); *table_entry = new_page | 7; mem_map[MAP_NR(old_page)] --; if (old_page >= LOW_MEM) oom(); if (!(new_page=get_free_page())) } return; invalidate(); *table_entry |= 2; if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) { old_page = 0xfffff000 & *table_entry; unsigned long old_page,new_page; { void un_wp_page(unsigned long * table_entry) Ⱥ͝—)Ոϔǒ̩:4,) Ȑr᪂า)ᜬ-ūȕ,)ŌŜ4 ‑P)ाⒸ ϵzẝ ƣüȰႸՈŎ„Ć᫇Ϭẝϔ4ẝϔ Ć&͝—Ոͱƌ)ₑ , ाⒸ᪂า&΅ljĈ4ΞȘçŁPẟ࣏᪙ĚȕẝाⒸËᜐ΅̱ňՈr ȅ῁ĆšǕŎ„4 ৰ 157 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ºâிඣ֜â4â rc ÂÑǮᪿ ՈƮś·ŌƷ4 ȉ؄ƷẔᜐ࣏Û sh ϢȒ 1 ǻẟ࣏ ϔ init Ŋ̴&ʃβṗ͑ṗϦɆP‡β̣1ň ϢȒ“ϣPƄẟ࣏ 2 ẝ Ƅẟ࣏ Ć 0 ǻẟ࣏Ōϧ\└ՈǶɳ਍Ǒ4Ȓ☦Ո1ňɥϵ init ϔǀtr4 ḳȥ4Ɵẝ ‡1ňǀtȒ Ō ȳ) ᪂ǎிඣ̠zϬ›µś4ϣt 1 ǻẟ࣏Ẕᜐ init ϔ ǚᩥਜ਼ƶ^rⒸƅ͟ՈǍʻ !ϧĚẟ࣏ᜬ Ō ȳr⍣) !ϧĚ ෗Ξľ !ϧĚ ܰ֜ ʐ Main ϔ Ŋ̴!ϧĚͱƌ)œȸᜬ ᪂ǎ)ȕₓ !ϧĚáɶՈų᪂̣ʐඌ ঳ ቻ Ո main ϔ̠Ëᜐ4  Ōȳ)ś੥ˊ4ÑȒ ̱ňிඣɥŌϧ ńljĈµś)ś੥ˊ[1ňr4żȒ Ḱ͑ init.c ɆP‡̼ϟ1ň4ϢȒ᪂า)ֲơᜬ )ᜬ ʐ)ȕₓᜬIDT ɴȳẴ৪ᜬ GDT Ո͐ᾬ« head.s ȭàՈ࣏Û z« head.s Ōϧ1ň4Head.s ₑ,᪂า͔ۅிඣͱʴÏ Ëᜐ4ۅĈµś Ōȳɉś੥ˊ4żȒḰ͑ிඣͱʴՈÏ )ቻǚP‡ᩥਜ਼ƶՈdžϔ΢4ūǎՈͱƌ ϢȒ!ϧĚ 8259A ᅳċ Ⱥͱƌ᪂า&lj ȴ߾ ᡅ ˖ȶ͑âிඣ֜4ȶ͑râிඣ֜Ȓ Ḱ͑ setup.s ̠Ëᜐ4Setup.s -ϬBIOS 4ͱƌ ϢȒඝϦۅ4Bootsec ËᜐՈr ȅºிඣᪿ֜ǚ setup.s ʐிඣͱʴȭàՈÏۅ ϢȒËᜐẝ 512 ƋᅆՈÏ ᩥਜ਼ƶȳ¬Ȓ ᪿǚḳȥՈৰP«ľ4ͱƌ bootsec.s Ⱥிඣ֜ȶ͑ḳȥ ń BIOS ȺšȰ֜Ν&ḳ֜ ₑ,ȳ¬ᩥਜ਼ƶ4 ͱʴՈ1ňͱʴՈ1ňͱʴՈ1ňͱʴՈ1ň ɴń ƅrẝŬḳ֜ ɥdzÑrᰴ Linux0.11 ̱ňிඣr4 ˖ȶ͑âிඣ֜ ϢȒ͹ණන1ň4 ɉ ƟȺிඣâ͔ᾬ¤ṁ4ͱƌ 7ȒඝϦȴ߾ ᡅۅ§¤PϬzȭâிඣ֜ϟ᪙ՈÏ  ńâ bootsec.s ۅ&r࿁̻ Ϭẝ Ŭ֜œ᫇1ň◄ᡅǚΝ P[ Linux0.11 ՈšȰÏ âிඣՈœȸâdzѺตZâ4 oldlinux.org 4ÑȒɥǯẝŬ֜&âிඣ֜r4 ◄ᡅ͹β̣P Ŭḳ֜ ë+ிඣ֜Ո̠ˊ5ͩȺâிඣՈœȸâ ̩:4ẝ Ŭḳ֜ Z4 ֜Ǯƅ̱ňிඣ ໐̱ňிඣẜ◄ ᡅᪿǚP ‡ிඣƉ¥࣏Û ẝ ɥᡅϬ4âிඣr4ü Ǹ Ιr ɴ ńẝŬḳ֜ɥ«ிඣ֜r4Ϭẝ Ŭḳ֜ ɥdzÑšȰᩥਜ਼ƶ1ňr4IJ«ẝŬḳ 4 ϔń 2000 []࿁Ϭ rawrite.exerKdzÑႮ=P-Ϭ c Ոßϔ abswrite ń Windows98 [ɥdzÑǀt IJ«ẝ Ŝ4 ͼ͛ ẝ̱ňdz]«PჰՈ ̩:ଡ଼᯸ɥ dzÑǀtՈ ◄ᡅϵּàՈ ḳâǀt ŷΞ ᪊/Ոxẟ:â Ⱥẝâָȉ ΅͑4ḳ֜Ոৰ 0 ☦ৰ 0 ἗ৰ 1 ĭˊ«ľՈ 0 ǻȻࢿŌ ේ᪕tᩥਜ਼ƶdzÑۅLinux0.11 ிඣǔɃ ϬPŬḳ֜ɥdzÑ ញ[4Ⱥ Linux0.11 ՈļÏ β̣1ňβ̣1ňβ̣1ňβ̣1ň ਜ਼ƶ1ňՈ4 ઋ‘ǡȳẴP[ Linux0.11 ̱ňிඣ«ΞŁūȰᩥڱ ṇΒƾ ¤Ñuβ̣ ńẝPতÑɱₓ੄ ΞȘ׏ǀrẟ࣏ிඣdzÑ᪸ȭ̱ňிඣ ɥĆ ƅPּȭǀϘՈˊ ᢧr4 IJ«ϵzͱǭɨ ৰŅ€তৰŅ€তৰŅ€তৰŅ€ত ̱ňிඣՈẔᜐ̱ňிඣՈẔᜐ̱ňிඣՈẔᜐ̱ňிඣՈẔᜐ ৰ 158 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ẟ࣏ 2 ŤƅՈ 1 )ͱƌ4 า&ˡȏ Âȕ 1 ǻẟ࣏ǕễǍǻ4ẟ࣏ 1 ȺẝˡȏՈ 2 ǻẟ࣏â4 ቻǚẘúȨ ±┨ sh ỄϦՈrȅ ᫇Ϭ exit 4Exit Ć₎΢ẟ࣏ 2 ŤƅՈ Ȉ࢑ᰈļᰈļ ȐrĆȺႮᵯՈźɍ᪂ ǕŎ„ ͱƌŎ„̠ˊ࣏Û Ćʵǒ̑Ρ ǡ¤ṁdzËᜐâ4ͱƌ z« sh ŌϧẔᜐ4Ɵ ‑ֲơ-ǎ)ᜬ ü ǸẝᔞŃŌŜ Ćš Ć4 eip ūǎՈĹา4 ϵz̵ƅ&ẝᔞŃŌŜ ᪂าՈֲơ - ᪂ǎ࣏ÛẔᜐ ɳʟ ᪂า EIP 4ẝ ʳ Ɵ execve ẘúՈr ȅŊ̴₎΢r 4ẟ࣏ 2 -Ϭ exe cve Ëᜐâ sh execve ᯡ 4  IJ«ƅ 3 ֲơ-«ाՈ ¤Ñ̵ƅśᯡ ņẟ࣏ 2 ẟ࣏ 2 ̩:r 1 ǻẟ࣏ ŤƅՈ 1 ֲơ -ż̶dzÑś 1 ǻẟ࣏᫇Ϭ fork 4 [ƿ41 ǻẟ࣏ʼnƅՈᔞŃाⒸ« 64M ɉА└« 16M^ 0 ǻẟ࣏]Ȑr ȭz 0 ǻẟ࣏ẘúȨ« 14z« 1 ǻẟ࣏ŌϧËᜐ init ϔ 0 ǻẟ࣏ ĆˌẠՈǶɳ਍ Ǒ 0 ǻẟ࣏ՈPֲơ- Ȑr^ 0 ǻẟ࣏͝ȐËᜐ main ϔ4 ϵzȭz 1 ǻẟ࣏ẘúȨ« 0 ņr 1 ǻẟ࣏4 ϵz 0 ǻẟ࣏¤ȭàՈɉ А└« 640k ü Ǹ 1 ǻẟ࣏Ǯ̩:rϔ4Ʒ ņPẟ࣏Ոrȅ ẝ«ৰPƵ᫇Ϭ forkƟń main ϔ᫇Ϭϔ fork & init ϔ ẟ࣏40 ǻẟ࣏මĈ 4 ֲơ-ȭàz Linux0.11 ¤࿁̻ΓťՈ 16M ͱƌ4 Linux ƅP!ϧẟ࣏ 0 ǻẟ࣏ «΅4࣏ÛՈ main ϔɥּƟzẔᜐ ń 0 ǻ ࣏ÛՈPϣ࣏ÛՈPϣ࣏ÛՈPϣ࣏ÛՈPϣ ņ3Ëᜐ3ȏ4PϬ›࣏Û«ΞŁŌϧՈ u͹᩶P࣏᩶ÛՈYǹŮ ń Linux0.11  ிඣՈ ȳ¬ «]« ǔǭ4̩ƾՈ«ͱᾬᰈļՈ੥ˊ4&r ƫzˊᢧ )±^̱ňிඣϕ4üǸ ிඣ)«࣏ÛՈȉǧ]«Ϭ›Ո̱ňȉǧ4 ‡àϬ࣏Û Ϭ›-Ϭẝ‡àϬ࣏Ûǀtȭ̱ňிඣՈ̱ň4໐ẝ‡àϬ࣏Û ɥ«Ởẋிඣ ̠z਍Ǒָ4ẟ࣏ 2 ỄϦ4ẝ sh ẔᜐȒ ɥ«uØɨṇc˕ՈϬ› А☦ r4ƷȴƇrP ৰ 159 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ ?a`@ ʌࡓࠩ3Ŭȟ ȉǧäƫ ě̓ƚϦČࠂ alll ƚLȉǧrϬՈνnj ?a @ ᫦ Ͷ ̱ňிඣšȰȆऺ bSS  ΞȘּȭிඣՈšȰƅrᢧ ɥ׏Ʒȫ Š @ ǜₕ̣3ǜ࢕ |kãxqI ǒϬ͔̓ ƶ̬ϦČࠂ all? ȌՈrȅẜƞƅz­Ո4 ʌxr\Ո Ñ&̵ƅϬɦ4̵̿4 ń ȣ˾3ʌࡓࠩ ˛ේ᪱ᣄ࣏Û᪂ᩥ ě̓ƚϦČࠂ bSSa܄ @?ab uØՈνnj K«ǔ]⏝Ո ?aa@ joyfire linux ৘ᩴ http://www.joyfire.net/ ȌՈ4 Ȍ:7Q uɥ☤Ʒr4K«ȭ Linux2.*ẟᜐ ἗9Linux0.11 Čƨǀ͔کń  || ˛ේ᪱ᣄ^ }II ͱ΀˛ේ੄· bSS   ?aS@ ẝ«PΙ¦΅Ոত ȭ GCC ^˛ේՈ΀ͳ΅Ոǔ᪪ඊ ņᩲɴ׏׏ ?@ Krishnakumar R. Writi ng Your Own Toy OS 2002 ՈrⒸͱȭ̱ňிඣƅrᢧڱ׏rẝઋত7Ȓ ŌĆńż ?8@ Randall Hyde The Art of Assembly Language Programming No Starch Press ƚL˛ේ᪱ᣄĄࢄR଑ ඓͤ pentium pro ƶ̬1ϦČࠂ 1998 ?d@ Barry B.Brey intel ிǺ̠ˊ„඗Ȁ3ේ࣏ʐȉǧäƫ͔̓ —80x86 3pentium ʐ ᪊῁dzѺẝₐâ4کƅ͟ȉǧʐ)5☦Ո ‰̱ňிඣ᪂ᩥ^ǒɴ ϹƄ1ϦČࠂ all 3κ☖ }᪕؃3ɘÇ̯3ƭ؃?Š@ KsãMhQu|rKMKxrk~3NxMãLhQuqqsykNN ጛ ɏ ăĄาѕẝ«ȑጛ Minix «&r‑ȌƷ໐΅Ո signals 2003 ?5@ John O’Gorman The Linux Process Manager The internals of scheduling, interrupts and ȌǣR ƅ͟ẟ࣏5☦ǣ·එǔ᪪ඊ ẝ«P±±ȭ Linux2.*ǣẟ࣏੥ˊẟᜐ Ȍ ˳̓ƚϦČࠂ 2001 ë̑ۅ?4@ ɯȃ̱3ྥXŠ Linux ͱʴļÏ Ȍ Ĺ໅TՈ৘ǔΙ ΅ǣϣ¬Ʈᬥ4ŭ+£࿁ȭ Linux2.*ẟᜐ 2002 ?æ@ Daniel P. Bovet, Marco Cesati Understanding the Linux Kernel, 2nd Edition O'Reilly Ȍ ń Linux R଑ dzÑ᪸«żඓͤՈ7P ẝ«ȭ Linux2.*ẟᜐՈ ?b@ ɬŠȃ ljĈ5ś[Ո ‰S扊 ǎ͢ේ࣏ ±Œ̓ƚϦČࠂ allæ ȭ 386 [ՈljĈµśẟᜐr᪪ඊՈ᩶ᢧ Ȍ bSSæ ?a@ ᰹͛ ijKkTSuaa Čƨǀ͔ ẝƨRȭ Linux0.11 ẟᜐr☢„᪪ඊՈͼ₎ ̵ƅƷu«\ͩ΅ẝƨRՈ dž໇Dzdž໇Dzdž໇Dzdž໇Dz ৰ 160 ) ͝ 160 ) Ȍ Version 1.0 ۅLinux0.11 ļ
还剩159页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

himalaya

贡献于2011-09-23

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf