Merge branch 'master' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6

This commit is contained in:
Frans Kaashoek 2011-09-27 13:00:20 -04:00
commit 0ca1c0407d
10 changed files with 95 additions and 786 deletions

View File

@ -1,701 +0,0 @@
%!PS-AdobeFont-1.1: LucidaSans-Typewriter83 1.003
%%CreationDate: 1993 Dec 07 10:43:50
% Lucida is a registered trademark of Bigelow & Holmes Inc.
%
% This is a copy of LucidaSans-Typewriter hacked to be a size
% appropriate to typesetting alongside Times-Roman.
% - rsc, 10 jan 2000
%
11 dict begin
/FontInfo 9 dict dup begin
/version (1.003) readonly def
/Notice (Bigelow & Holmes Inc. Pat. Des. 289,422) readonly def
/Notice (Copyright (c) 1991 Bigelow & Holmes Inc. and Y&Y, Inc. (508) 371-3286. All Rights Reserved.) readonly def
/FullName (Lucida Sans Typewriter 83) readonly def
/FamilyName (LucidaSansTypewriter83) readonly def
/Weight (Medium) readonly def
/ItalicAngle 0 def
/isFixedPitch true def
/UnderlinePosition -100 def
/UnderlineThickness 50 def
end readonly def
/FontName /LucidaSans-Typewriter83 def
/PaintType 0 def
/FontType 1 def
% /FontMatrix [0.001 0 0 0.001 0 0] readonly def
/FontMatrix [0.0008333333333 0 0 0.0008333333333 0 0] readonly def
/Encoding StandardEncoding def
/FontBBox{-12 -205 618 928}readonly def
%
% We can't reuse LucidaSans-Typewriter's UniqueID, I don't think.
% (I don't know if the unique ID is for the font before or after
% the FontMatrix is applied.) We could use one of the private ones
% from 4000000 to 4999999, but it's even safer to just leave it out.
%
% /UniqueID 5029009 def
currentdict end
currentfile eexec
80347982AB3942D930E069A70D0D48311D7190FA2D133A583138F76695558E7AE9348D37CAC66518
06D08527C1BB4A062A4835AC37784CC39AD8841404E438B4D52D3901E47A1DE4F7924E0FB3DAF442
499175BAB1226EDF692A4956739F8828E80592F450C5D5C22AC88BCFBE9748F61D18243A16F4A446
7F084E8E2BE46EF47FC51C3A8199E3CDA62FF9C4FB73956DAB8B6683D2156377808CB35026073E80
523F59A30D195FCF9B9FCE4FFAFFF195AA1C31AE164F9B6A929E4FF572FD5D100F7E72C3258853BB
8A8928B38669590B921E9AB5CD4D604AE6C1E4E917CFFB9D25B5FDEC06E29EBCCA01F203B4FFF0D1
5FCC154910C3473B8BB1349848A84948348D5F7D1C8C99677E192540A106C2E5D7C072044B1342A4
A898D0E11A8BB05DF48BC18677E2EAC3D363200A81536405F42A3A155EB2A4CAA64C1087E14DF889
B0131468C586D2061A3BE7853A84DF2A3BF3C832449479673E63BD7E1BB396D69DF396075092908B
4757E7A3705E3CEDC3B5C75FB4F8960016BA8B91F6C9099D05FE6C775BA9FF429651538051F8A1B5
63650D3538B81FE98AD2766390B28CA9871D7F38E207B0D3A1DF48A939FA933463497A4CA8FDEF76
F90C7BC2CB080C5C92F0312F323000741EC1B9F7F969C5FD5A04FE08DAA9270F26ABF908CBF5C1B0
484677CDED8400C34B4EFC4F4C573B39F4B7361ECE30C41AB0ADFF0A721FE2A1379D8A296B17D18B
FF613729B1FB5130CA7E1BF2740A49D5EE61E14DDD9AADA0BD3588F6B87853AC946274DE848F36C6
FCEB6CDC7BE1564677B6B5097E4022077DED0642BCE40B37EF7193B7F185963855392F11614C7FDB
F62DA70A31FE157650A77512879EF2BEAA85E5993194825202238B78BE634DBB292635A47381D836
AD137040CE30F549BD8CE6D91E8DD1E3B9F02ED9072FB585FA32F7CDA45F53651577228A42990D66
835C3BA3B47A7102E94DD8ABC4FFA5877F9707B83D87AEE2F5B83EABB347E8D3167260D31585B4AB
AAAAFB96613347201166512A97137A47FEDF6A1C91350559A6D458112EF1FA850FA4F1BD9D1711E5
680100E99908F7213CD3030B8255F7C59CAE7B32F29E2B53AA4C4E6B228026191AA17F75D36F7194
C37E1B2EDE3B442965666F20F98CD6DD8CC10E1231763E116AC107F38A21A7E646084C54C26ED170
1649C5F3C80FF3CBC419EF43EC22A93679BD2A6D8E70F039BA9D55448135414172CF93B9B43D1EE8
4E77FA872022C9926E6A00C6D1C574F1043E73CB78D50FB37D61B7F461569A6AFBEE3C89C6233A1E
F8D3A2AF4485E2D56F25317C7FBFB9FE6E3EBD443EC5DA4E9885C5DB47923A66962F4AF9B1B62E64
6A5DBAF76F6C7355804E998F6ABA7456AF8458162D424494E8BB2704EB37E84A81B0D976FBEA0272
0F60A740128149645BC6784423AB9BDEA0A77828F74126ABC75A660FEDC531BD75FA864BAA25C90D
E1E6F1EA2C15AB002038DEC79E7271767EDE8532D31B84E6CFC4DB0935DC1CEB13FFACBB1528261D
E12232992976806812CD8F00B8CF4ACD3E62453DCD22155A37BABDE46B405B20ED68EE263AB4CC81
0775F55803AA22E6BD4618D916A30EC708494799F4F226E1361F3621C2537BE50F85CD10CB2240B2
E24C8585F36DE5D296933BABCDAD9841B483FD07F8412DFDB2D0FD2B8A0CDD91E2EB4E4511336EAD
6A049847E3F119914C043DFE6F770C564FD46B7101FFC01CBAD3BFB95517D8A2C45D0D60EA091889
067710EC2A2783CB50C493699F0E68263B143EE2582C96058D2B137DF1776FF22B51E30ADEC17ED5
A614D678D087B231111D2A9DAC0C40AD4881E9A422773DE7329E539CCE3E101BE0FBA4EE2E4B7931
575B1BD754F974A142800F1E823AA68A0F3DC32D9EE21691E324D582A909C79B817AB971AEC21B99
C854DE530EDD047A53B5B5960149F62F8B36645A49F666504F7F96041F93C927144A48493B209B32
0CC4B3F85C31BE5BB72245218ED830ACF5E525C0517C41D87CAEB7165CF35E7C2D23B2F5AFF639A5
1A814A0408391729344BDC01A56736E64D147F54A0A9D2934E3209D4220BFEE5FE2B9D3886D8B455
0D5216A9A531CF62033929A89C9A06EF93B3D5EFEC7979EB05F5DE7AF64EAC98AFF7F36E4A678BD8
857D176C21D12BAFBA4892733F161A4A8960E4D2CDF70E0BC2CB702A2D9CCE6EB457E00D5AD68EEE
1DCC3161BFEB1508B1C760741CAC9A1BE851F740AF041A698E2D65CB581C266CE0F84E6827915092
D08D78DB2A32A8473ED908A1ACBB6A5ECBB2A80903B3EFEA6A43B924922D6E0ADB1F79860696B5C0
E5B08F88C9FF42A83F83EB72A4BD3BA72EAF7BF6A63D7D0904AEA98DF971B5A4D0AC102C2A0A7E77
7E3A9742F8E59F11E158022077EC2068E4CA6309285E6199FA761EFF3FF401566060BC5F4CC83DB3
632F33B5AA4F881B0A885611C75B3B70A3C679036B9FCEC9F2DE7421A9AF6AB9F7B12AF05A133EAB
CFF4B8ACF442FDA230138215D16785341C3038AE36CE13A306E080926688173C86C25B1C1FF05C75
2E150072EAEE9AA8671A3B3CB80BA601DC9F58C02BDB75C68441D7A87716A8DB6D70B1A52B91FB3C
6CE7BCA723C16C70D09C7E8F4576E077BBD5EEBD21F3B395F44297EE74CFC4B5F743C497A77F962C
FA87D31E239067AB6131371CD9722A559F7D50AF53DB5B0568F175FF0A06369E5301A9EE90AE2BA6
F3D440DD7C786912D3EB3FBFA504BFAD15DE908F46B606AB184B74C17AB0AF629CEADE877C33A577
807E96D7DF59BCC4EE3526BB7CA3C763C186578D1281BF558A2461541F1CBB1588430E8470CE5B64
3208DEF67DAFEF78D776AC0FCA3C34259900567CA3BE4149ABA57BBC2A9EF57F22D4ECAEEDA15E4C
0B9522FE08E41E08F97909EFB1115A948327DDAE0466FD76E80E99AA9BC408158271C2C120073EB6
F518818DA9095D6AEF9EDDDFC414C57A0CA9A7343568080DD2588E0AC50B1646A5B53D80A56721E7
C127296A7AE17B804EDA28954F5ED60ED96C42F7C9C1C5150D5FB6515BDBFD0163C0304762A700C0
14F6C4969799FEF3389B792513D0898602104DF32A472D5324A413D49A8806C74B5575D0D919F7CB
F7F9008FEFDF722AAF10D7FB238085D136332060D218DD9D8AE75F89A18C4B23451142DF6F826D66
E131E405FFC3924923D86BBA7879DE3027020E8A8AF733008B2E8088B7B4224B0834B2512919FD99
7FD926D555625AD9B6A5F1C9E9783982B805B71A7E2C5D19FAD2B290714A7C2CE47E02E012059CBD
3F3E47B7FD9AAE535F8CE94B274F684F7A25628B1BD5E021BE984446AB62E018FA4B37A9F14080FA
A03FD51AE522AA36001488008ACCB27474500A2EEBC765A9247D34DAB8DE5C4016018EED9BDB5C5D
446E2482CDD6A3136B2FAB3D7E216F93B237C3725008ED36ED10AAD15BC8FE38CDF68EF5F112CD43
A1F8AED3FF19D582615B432EA4041DC498644FB1EFB012F9B7A24C2F8B4CA02D2A15F9AFE86361B3
981ECC46610BC92E4A55F0BE41EC600009B7DE1444AF1D6B40B11D1E2BB3F6CBF9F5125D501A7DDC
E85B1BDC9AD9BA6BFFC8D0915EEC85F2ADFCAA024EE914B38D84B5BD83C87603CB53975AA2814991
8623FDB154E15A9CB0F2962FCF5CEADD6B6065E2B84E65683B9DA53DF277BD786656A92D57EAB3BA
70F58CBFF25B54B3AC954A61EB3101C8EAF896E0185EF17F073E954324A62F5EA10E8EE17151308D
7F3513C3B977C67A6F1F36D794BFD3619D85AC01958C32B8A88FFCEBCBD888C26DD5D75DD3A221E7
83F104811222B521E0DBB11B2D1048E02928AF1181CA59297ECCED92338B42872374A4C45878CF5A
9718ACFBA4E61A813EB2DF6D3BACAC75EEC2CAE433F045912BE593C8E9A369DE63D518C4661F2C1F
00F5F68C2EF939947D456013DA0D80C5DAE5A460240A59F41143CA2A96BB93742DB47824F8FEA054
84F934FC5F649E81EC405D6BC89199C31592E5D0D73590E6DB20579BC82764F9CF5F5E881B862D51
E77924D071739FD160855B65F2280A4F1D302B9642BE9D08636CECF50EADECDC4AA006369B0894DF
4303C0DAC203E5ABCEE18467015016F20551D6097FBEDAF520E01AB7715786F88E1991B44E283E1C
39F5385F6D1A13C69A8CF941EACE3386CFBB2EE1B776718C67A669C5C0D31AE0B32F3A8098E11597
E73B4175782FB4889329A48FE151588535B7F72D3D8CA7AC85F4BED9CF38D3621169EFFE14A390B4
C0281532239B9036D8871F8D4C9A9DC5204C4B9FC20B045BEFC8FE20A0B7B1C955D00495C15766C2
8D5263EE6311C0BFB769F38FBDA24BE7ADDE053145B44680ABB3AE0B7D4EB860969970B5B519ED5E
42DB7820D6A19F99307BCC946487B5315FCE66BAE2E54BD20610DCA53019DE8B515EFCA0CE4774F5
BC79310AB1A0CA93E74403A389525F00274C5894EB80010FD77EBB734907707E29C1E8ABE7357500
2176C43C345A4CE85BAA397A7BCD51631D606DE89935C103AE7648CB4841905E7282EBA54DC3D0B7
9729709355CED80225E5FEEB82B1DB705C712919055985244E721081E93DD213F7ED93541851852A
26A3AC2C6D9E1B121820B07EC27FF7E9453C0F4BBEEA6B8022E15C1E7FC33C664C84F1D06CF17B36
12B2271775070860D775BDCC65E7DC255DFD7B5A812456A7EB28781609F3372D5B0F0B6D94B78CA7
C62597B48412177C647232859B4A9DA35AFD288E394CB723E9ABBD36D87089888901AF6E8D766008
29725313B117161F269CFBB14A160B46B9DE8FF0761209F7B2DD5F19C6325BECA6FEB7AA638E1FC9
D3AE6177FB0F7C6CADCB89159F718FEABABE586B41CE4DAD020647F744A7F5FF2DAA17C26F0E1301
D083164BE0FEF9D60CC2C66319D4135569113EAE174987C77EC433EA2B7B783D091DBE51DCDC4702
722FC7049B30BEA7D0C1228965E28ECE1609F52157E2FFD2F465B47235257755C3F9A9962D95032B
63E09FB9FD0D523DAA08998FFEF96184271B5329B8C5D047EB5983D50E0068BE0D1DADDC22B8AC96
B7E5E42BA1D12AF80061BD2148AE149C09FD325E3031B1820DBCD170ED3178447D1C351BCCC4B1D6
F3602661A6741AAEE55A15C0949E1DD9C993D0F88CD2DCA25E4981109BDC5A3FD2FA92EA6EED8A32
37EA523E544D09C97D232A6117459097758864DB287ED7C3E9216C6E3FEC4A5C31C04277A591DC85
376693B385737DCE6CFD27CE6E4251CBD7E97E91544738903B27FFC04D5AE20B1012BC6E39249679
3C0113DC8E875EE132E776B339F1FB789B4A1A3EFD177266F9D40E238F474F51FBD5CDF96165BDB5
F673EF193D6421580FF43342309F94A3B516B3DEC92EEABE3A0529846B70B52791E18788899DD29D
CABD656C19EF1102226E146E65D5D4B78B81AB91B8FE016CE87307E5EB7257F45A0C8A40A15AACF4
AF68968FB5B4605D03BCFF286F873666DE682819102296C3000871433CE9DC6334A22708A01655D3
BB91875BB8F23841892935E5CF791E7B65FDBC05771E09B28DFEF457E1A81040DA1301DD1F2FC5F4
17D0715546D5A01E346E319203EFEA677C80132C66E8CE92684C3A2E01605AB7A1F299C5A6082513
A1FBE5830F6C19B94FB2BCC9F93B8144056DFB906628EDA3540C0431EED16991479DF6727B5D4D32
EF563D88555DDE7BDD8B83300D4B3D5D6C81D8CDA03EE2870D1A241E77434B8ADF36E0CE6D830949
6A59475093FFB833F202E6B6DCA3CABBD68C3DC919A3E4EC0DFC31F4F95EED52EB825942D9DC5EF2
0BD9149A2C38A442068581F5DEAE47E806219F20FEB4E228923910739BCBB7B58E32106B706FC526
EAE0E03BC4625BECAF67CC05F3ED092EF69FD4286AF10EC2CA2F5943F58907421D9170DC4C8D7F28
6C846D4C6864F867690DB8A5A6615989B3C2B9C6F6B93BC081E9C5EA2948D98547E31355C541A300
FC983609A56A91CE719F612C1FB9BF360B17F927E9FD488CD86929E61EBBB4CA8E7CE6719DC72AB8
CBAFCF9D503C4083CC9E0123053FBDA18D0C4700263BEEEC6894EA45A20BA47912A67E46C970ED25
77A546DDEDA49774475246CD0E32A0945379F91D65A070E5963E4DED4374268A07F574E7E6E79D73
17353B99CBEBEE9CDBDFEA305C711FB0CF1A48ED66AEC764C3F3F82CCB1E2B0D587590EA1714E787
C743496AC5EFB96CB08B702D0E99395901457687C5485496B5E39996E811BC883383DA4847D0EA69
2AE9FA4966FC70C46133E4A72CAEFEDAC8CF1DC3341F6D85FFAA800607CB8544B9FDE76E33FCC845
73AA68C01B64CD5DE1A5054F11DB94265D6FE331146DD1702D042722B99AF4AC49487135825DFBC3
13C313ECE0138364A7F3D95BEAD409168A040F1AB890DAE0DF0F88CEFF0662802D43AE636D1E05C0
BD477456FAD7E2B067FCA66763DDF2B2F48C35FE6AFBF4FB94C71A090B1B22494C0E40CD02546524
660E5679D22CB569DC1FCF9800865DC4BE8054FF3B7141992CD3C43F4812EE52011BD1495A170AE9
B9C50FF0B3B71A35F0381EDEB68C007BBB36CB9C9D84234580A229205DDDFDF5E64D14C16D40C0ED
D7B1810A488F43C469E927370EFC0670C8BE1AC737464BACDB6B2C731DC8CC153A072E2C908AE987
879C3D6EB1B9938D737F621B539F25F6F6E827382CF7DE633E657C0B728B0ED2F1A6748DA9E4944D
4CD89967D1FA8F4459670FB83B55D35F0B1E252851B97816B116603F8973B569993E907E466A23B6
FB210BAF37818744C23E82F081830259EDE57DDA652167EDFAA46EE27167845EAFA6E2EE049C31CF
C7D3E3CC450CA873634B9F203CE5E3E1CBAF3A233872AE92C8DA42F94D8B3453B4962993C186682F
AE7D3707EC032283DBB107897AC64E7C36CCF0E56FF3BFC4E0A9C65CE4CEA2B42F39A4F6A57C74B4
300577850DF849DF24B0481AE7C76CD43D04B80A7CCCDB8E3600550243C7100237E9AEA0126BD52C
5B1CB73AE45BD48478C6EB2FEFAB9DF9A83C88353695286EA021BABF9B4887F3709A46930FDF8905
651138D70B5A472A67DDBBE343A54960B8F30BE92BF0FEE15CA238961550B391D332809F59E58DFB
2CE34FA60A8AA50B00DA8091362129DDC7735A63926A8F7E97DB69CE55FD928515BD2B49EE44E225
687D167A0C37992C0173DB1A5122D7CF34315C82D9E4CE1231A28EE4ACFEC38C5B0F5F60C94025DA
4114121CF1F54BEB83375C50D77D1B4CA88BE0F359A42A97B1D5CFF7844D33D511A43545D1437EA0
3BBE19D79BE26F65C99044C5321EE327C8B5C18B0A4BB6316426901F9B8EFF2C94E12EEE1DC7DD13
1AD6B5E3CBD5A8715BD08B65A2AB8EDBA47DAA97BB30064F5613C92519E9B6B57AE188A83E5314BC
4B7C8FBB1E65CE75ABA028161B0654763214F8C0517E104C1BA3365A725416392313D023656DF547
E668383E981FE0B47EE47E8AADE05E056E3CE11D8EE4ED6EA75509610E3FA72C8A114C91ED36C8E1
0F49AF79B58CC4DC4C2EE75FC406AB1145133035E272C7DE4702AE746E696FED6CCE73E2D8EB5B2E
5B76571D0EC223870F7F070708C3765504E4DA1FE4F0D265EC038612D0357AA0B7955FDDA48D4836
FEBBBE883CC3ADFEBD9BEBADC1252572B5BDA920AF018FD0F0A4BF1784CF8CD1B3DF93F54EE9670C
B20E15C4E175D0E7B7EDD9A23AEB4CAE31EC62440B1131FBE36CD897F3635575AB613F0681F86BD5
4AA325587335EC4DFE96CBB83125DB1FC22F163248643C9BA4C18D791A6A02E445F0C1EA7A2984FF
F475F77A816FBA783761E3DF373A0D67FBD746F02B28B5FBF9A4111FAA90BF43C4B0CC735576A3A8
0768A37B53EF1C572E4F9E5034AF1D724F7968CB67172C260C0978734894D9FEE4962C0253FF45A1
D430BC811C4B6A3BDB41DBE14E7BF613253455B5CE94D280152ACB404A831686EDA6F73E08D1BD92
3D34015C5F719BF51DDEA94CBF1CDA88A69B428FB80BCE5FBD4883F24D490420FC98AD264135807F
094402DCEF720B3EA1E9DBBABFCC9A8D7AF57B6B2947F7E8B10D3F9651658B7B1EE1894FD8F3E365
A834BBFE1AE0BD7623279BCAEC50F798DF73887F42C53190D650FD1F1C5BD06CD44B48860CD3CDB4
92E0327DD6F862906A05AEA32D0A6353A729DFE4CFD51AF6101972D3005BC698C459CE627692C5B7
742F4022F16939602EDABA26FACB235A1C0EFC9C6950D7011BAE92C78A25865E129D9E81824B18B3
EA9F2CC49D70F99FDBC426090836F7D71384A60657FB7DEE4349CEA8646DC9AA31A76E974D32C325
FDA6B72B3208F01FFCF876FC29D82C552F9B2B1C0A7240BCC2F5B0312AD679DA1DD3B9919629DDEA
D61FBFF78DF1C5DB67E8D113A2AB1B593B853584CACED175084AD759B80082AF87A678FD3FEDA9DF
A1F3BF74DBE41591E038E69AAE06F0A264CD9293B5DFD22BC301145E2AF7024FCD3AE5331C88BDC4
7634D25D072E3CC40F4294CD918344A410F9629D11DF1EF5A2AF06229E7623E22644A504D3DB978B
4AB30D65E8BE2DF68581D03DFDC3592CB062A5DFDEE297CF5FFC53EB1DC823C945741929270938B6
8E1BBBB7CDFA84083496A81E13BFBFCA2499E00D55F76CB8DBAC73F323AFE1FBAD876A9DD5F6B2FB
20F327052CD97B53C402319ABADF7B5C0C25E29BB9948D624056B6C0E1438922E7E4D0FFCDB57C4A
FC712523B1AB8DE52A597C863636AFE60FDEE42E80CB77926FDB919D159E08817292F39F0E70FA81
978FB4A84EDCC17CD081BC0E3B26BFE1A1C90734789D91D298B2F528EBA92EE9B1DC1D872E20E3DB
F2E48C3D102BFC521C5952AFDF8F3B2724636FB948BF5A32A44800CA86728AD6FE3A28E5A8AA88AF
21BCE92824A5FE0C350BC8DD45C179FC99D8EDE7C4E2E540BBECB5D4ECA4FCA61B9EB4931510A022
433F3958913ABB171980B2293A228D39F2F44714C6BC608C74FDC38F30D7BBD035BC0D59DFF95C7E
4DBB7051B624134E94C5256460A8B80B50266D4AE3197C792AC29A17D43687A380CD2C4CE33576F3
54C9249D12B06C6434B7EB010AF6CBC8A996502CD5CEB596B1DB59AEA6E9E574BB75EFB792C68E9A
C4BB33B4CCA25C49E75BE532E70764B7D33815AD2BB426BA9016263DAFE484537D7D3BBDBC8A993D
A7E203796C89A7FB00A1CB1C2E6F20B999FC5B48DE08D7352C779E0BD6E738124508859D6F20FE35
550A1DF28FF2C2B2A0FEECA943F7E82A0E26998FB5F025F0D39BFA2B98503D6D0224C9E7D172D2B5
9B15A1E4EA69E98981A6C78D5BA939D7EB72C26846E1B26CA6BC330678556195F0C274C6813BB44E
9FFFEE955E5C8C6E12EA000D9DC9403A9D27D62B9F08A88D03C328009EB84CB337E9E3CEB50B16BD
5C39A65B39C41EC8AB5BE869BF418C3265D240E692EDE50B6F4ACD86955682E44F22C0BE7C8431A1
400D8DA19CCC022100EE4313D44E310A33369ADDFAABC8A2DC1A8770673E8F0F2D4A7C0645FF518B
6EDF52516AAAF8209539DEFB283EDF8E7A9E37A9F24278740640A031B0D7D7434898AA663FE729A7
E26BB48BCAF3A970ECE76CA17664D78D07B3C3466DDB39D2AF51B7662E1558939DA84CF608FD7C32
FBEC38E8F54896E23CB21CDC8C7923B09EC9640755E713A78F61B4B45A2FC07C1F06F9F4255C91EB
5232A339CD63F75BCDF45EA035E2B96B47E47365245F960581C5D97D51D13B78E3E359091A70747A
F05FB337AF170C90FF30C007B6599C0DB5732CC4303392690CB2FDFE033140604692F0D5A4E365D5
A8EE1FBD32D2A53F446946521955D5DF87AE6E14AC1E8A0693307715C8D894AC2434A96A7A4A9732
46738DE3311497A9B1942513AC5E9471AB02DB7BBA2E74FC7D3E9129C801FDF493FDF1FF022E65AA
75DE37ED4301EEACD5428B0993681BA64A7E36B5C74B38E5423FCD620D2EE4159078E3A58B332EAD
5B9DE338AAD660ACC2B6950AEC2C3BDB289367D8F9F7A9962D9551BD6969FC2553876104BE1BDF57
ADFD6CDE5AD047F832F2F015AA1F99B38216CD8BDDB3AB8183F205F37B97D4035FCAFEF127623159
1B6C82587DAF42D7FBBEE606B6123F25A15442287299DCA7A8A34F15BFCCD296D192CA8FD06C2437
948FFB9C3F25B459EE494D5E546DD9C75DCC0AAF4F4C76289AA899BC162119A7A0EF713217DA826C
B9760C48C2914B98F00886CEA4CC5FC04C587BD2945A227E168B6AD9CE4C1362F852E4AB3F2E8739
D9B79E45649C50FDFA6D65AE7B45A2729DF2CFA6DEBB1C816B7A2065AC59E542F6823AAF429590FA
1862B212CB122651F961F1A356DCBCD1AF549A7751F4DB86A70884C73FA94FB82138308071A253BA
DBAF146BC004141F752F74D44D5D7F55D58AE914F0BD8A2566A65C619F561835D9648BDE284B89AA
8A53023C36389FDB6288FB2FC218ED885306940C52FB774BDA7627AF008A3678B30914997B05B1C4
09C88A985F90F3FF7FE23D1482B58618E5FD7936DBA63CC820650E5412E7D62B45452B3217B713B8
6D51E7446B0FF3469560A28F2820853946F486DD17DFAA17C74003FA12DE3DD305CBA22D9A50EA35
DB906F1A8217FD071AB82458233ECEF214D288374C9BE83B037AD4FB633C634AA9F09B798D21D1B8
DF90054A1B2B885786D77B1192DBE60FD32FF40410AD68539C133C354C6010048EA85BA346CF60EF
F9EEFAD0108AE75BCEED3E10F286DB6FB7869C884E3138445C031743F8F86BEE3918A8A3980E56CA
73608B61A2D98BA969D01049850D5EF412D278962F8C36B27ED6834B94F8EAAD50D7492E60426D47
120B871A54EF9A59EAE00F422682DD8B9A324707273C7F670BF986D3505066380E4475D590744F04
E99E09857AD34EFD29B511EB2C785B20C5A674F7BF2E4ADC21144C4673F4F08155E3455DEB2942D9
B43314CF1061D82D85B3453D1E60DCC00F302E8CCE62EB03E30FFC68C9E35D3B133CF47B4C22357D
66EA9EF24A08E83CD01B49FB4A0F080439EC635FEAC1AAA7EB8F10DBB8F4A9BF589798682CD9C76D
475A83EE38578ED97240ECA8CF3ABC86E9039C0648EDA0AC7A3DF5E9513305DC57E959959A4AB17A
36B2F5AB95ADA16426DBCCBA44222D08CC2D5001C93DA9CC80C4C64704C32723505DD8E010F2105F
71A7624556A5F99036767785D8D6CBE71B618EC534D0E0B6CDA8A05AC3DF8EFF71A34D62B5685A34
7D35069848018BF071990E045DFE4B83B3CCAA03ED98745E79297EEC74FC6105A2BA13BD3C3388F3
1F3D7DD671749538CD1F92D548E1E7A2E060E34D6C77583C6C84CB8D69121DEC579DADA9B4CECD31
983D50A8B43D83DA2EB087322C2F6D63113007E200132028654E7315AA91AE1EB41DAD32B5433D0C
180D728A8E06EF6D743206715208C5A23B3EAB4F2CAE378EC9F3FCD3CF21F1542F7936C6BCCB6C5F
62EE7D20738308410B7CD713B11288B8FD486184CB3E245D760972D1149AAFC0101151590F83A3E0
BA818F8DEE183D44F4B1BA5F1549C42E6F594BB6BD46F781E36195B970AEFB95D97AA3C275F4C61B
106ACF580D39A662FEE59C3928B14FFC8584AF74012EC28F815172B1DD745966AFE1EBC7D006CE7A
DC4A71BB7A2C2EDEF03B3B4A5D261EB60E694DB0161196E3424B1B341076FEB779EA7BD8587DEFF5
5B651240D62C5D9F5A12BB3B67429D7FC20A48F9CDF80750381B9AE9FF392C73C12B85F4821DE8C1
482CB2ED52888CE61A6CF714351718F041C825F4E057345CCD97D54F654627A7EA321C68624C459A
A3E24A44CC4A1888198F48D6A7713226AFE74934C528167BE92DA5DADE309964F41B210EE50599A4
35E2C6B388B927D012700E796F64ED7E6BDAC411CD0E25528A3FC0310AA3E2C2121BC38B1FD73395
3CDB98DD301484E45C9489B9366616817DD8979F9160F1B772A28C3562262BC8B049036D04B95BB5
F1371B51193B752E5DFF1ACFE48A2F2518A45AED8F144592CB31B04FB714847A753C0EC1686981E5
4C960F610F7C33CA71BDA5C9F4DE0C08DC75E01BB4CDF514CE5F2FEECBC7547FB519F5CBC38A9828
8DA77C4E356BBAF79728A13A62DE1C8E615D1D62A0848ECD5DF9DEA921993964B3FDE3B962E55CB5
F3989C5422EDAEA23D7E015828A02AB1E4B5940EC14EBDF382EFA326989E70F9C787EB077BDEE3EC
99D0285E8D773F0756065898A908C01C067C0C35A0D16D4981577527DD768EA39010060BDFB4649B
CCEC6B6180877BE87FE245E5754E59BC6BB1DBBD93B74A96DB6272C25ED551C56CAC3F1F745325DF
82949244F1DBA6B4EBB7610F3579133A755B134BC1B1EE8FBBA2AF5001CF661ECFC2A91373C0F02B
51999C0AA92C2709439B2FCEFB5162F08D15174B2CA3DA9B51912A65E98028B2EFB8A9E10F441BEF
3CB13A09BDDC84533BB4CBA1C206326989C0F2E8930176FAD49C78AAA0525D0E6075A07A3F39D31D
9CD9AEBDA82C14766F19E92C33EFA0EC50FE845BED28EB50F9DBE902DA3B0F74E24916B4215F0D92
6D80C6040804D161CE9A94C2C220FE0BAF924C8C7E058853D2E6010752076C6CE09CEE7D657AD344
2E43A81289BB710D97E29FB63B8E6752B7748BBE757E8B0A3DCD949B6BBE93EF241A001741FD32AD
EDD56CCA2EBAB10F31DDAC909947B298A8DB477CC5BB6BAB746160F0F55AFDB57A5160C84B6BC90A
1406494CACD5C315425D8A109AA335676C6F515DF429789EF40B50623DF66ACE39198F58301BE456
A8B41252446382B835281694605880C8977AFEFDEA4E1F3668004EBF88634D0DC5A432FA8783A815
1BF6C33A2B7EED5A806A4B32BFF45F611FB648547A9E6E6D70444EFC0211A2927672D790CA7284CE
FF818499669D16440134ECAA5D6AAABFA5AFCBC5CEDFBE0C02F6263AF2C3D6EF7209CA72B6814C93
EC17B226D568A2B0DDA5B80038C8CDB3735FE6C331D9010BE8AFF004B255886D2D2288B8C0EFD09A
5F355346FAF07EB49A280EC3825A9AA616B78CBE810D469E896AAFD5F6C067FF30C199A02D1FB433
E2FB007B69FE51F00F455021E4530956B56A334FA16D1C284129EBA2D3017C749552D78ABC252BAE
E36519E72E35E55C1574706E4054FE6144FA5ADD33694633DE2552D2E4F4C4D4116051C8CED1E01D
23F09939226AE71B81C342ADDB52F2B5450F62A4BC7F698CEE716B7074E646C4F5BD3EC2AE6862E9
CE85010F4C0873E5ADD4F6020958BFDD0032DB6A554AB14F85D5E07634D734081993ACDA7077A7CC
8C4176DFC682D58AE0FA8708B6E9EF4813F4145FDD8ADE57AE8F97607B044F88A5F7678E9D457EDC
F479F004AFF3D3C261D453797AB1D678717C0D5F8840DA2B67C0E656D7D07B5245D5FDED44DE63D5
6430DA5D2AF09F428DCADEFEC43718D9A6BDBB3E4192345308B3C816C0CAA79B6A688D15D078D5F8
BFCE1DB975D0B9E30332EA7C6E129C6DC71793D763E2B6B4DD8D4C08F8EDA4D5A130F02DD51553CF
972B0EF9756DB691B6C73447051A7E20E184C86BB15A4F6DFA4B45BCA782F940BDDAD49AD09A5B99
23A0FE8349E48A8BDBFDD87917529AE502C1BC13587B1439BBD6F2A73F09F8934B4E5FB733F0BC07
7781B985D557B97C1437B83D9104024BA8878735F64E3B5538873C51636A658FE150EECB05A43B4A
0113D2C8070A0FEFAF5DDD3DA0906A48CC0B2CD1517E9F586FCF5DD1F8997F1F115B15B10324E054
ABD563B42B1F3A72D56E7245E8A435C3411D06DC0435DD87801566EB6A024BA9EBACB893B85903CE
125FE69740D4F744E61D694E7219DAD84211494D1AB8C8780B10AA90FF4734A9857A254EA9FA9E31
4C36D55458E8183B9BF4B8FB539887B4E010264F9614C82B0B8FDFC3864DC5C0BC6B84E18E19BA44
A8ADF4215F38DCF7F5ADAF8965E2F932A11A367C609733F016220D781E269940327EF297151D63DA
444F604D9F9724D819337F5675D544D2E8E4CDA2346D7D5CAEC7DD343A8C0257CB19837EF8C2E77F
96A3074E657ED05F42D3936829D7796A43E177C2C19F4BF88293821221154909DFCCFE498C9EFB1E
14A9C1F7AD77B96202B092B040D9AE30A87FFAA34F88105EFF846F4F8EF7264DDDCE905EC7C84396
0220F10ADC59119D6D06B9D247C5461F8CBF681178CEFEEE323AE09F613B2522BAB825B333A70B90
1CDF8375C618C83E58B829229C2ABD03BF0AFDBCF8634ACC60DAA587DA70F648D99CCAF73AB7DF09
C537C2D1635C6B5FE35C5DB458FF06C59B644DFE250A12D34DBC6C31BF89A11CE5485A773270859F
3C488F2B60904908130C0A5E2F16CF62DCF3C12BE566E2614237B8A5FAFE0C8AAE18B5184F2D6C98
C1F0F165AE856A1743694C87C84ABD3D0F17B5E4FF8DC1BD2D6CE94E5FB36F2899F1DDC548282992
C3531FC51016C04359C7EFEA514920597EDB0964996215AECC91DB25C3990578FAB7EF75D59BD78D
EDBD06FD1AD8B4F8E575FBA2ED7B0DA4F026BDA03BDF5BA7D8170C06F0EB9BB69AA2DB5783B74538
3F2E3996BCB25F2FD2063E127B75BBDD079B859B37543003D02EE7B95400152A5F303D8363FF2095
EF7CDF4F66AC11B30CDBAFB208B83B6B924371AFCE88290D376CFA4AB9C76D3E5AD057E03DCA5B6E
A54A940F0017577993BC968A0B3527C30B18D027CA61B02E29E6AFC4F749359C7EF508F12461BB50
C01F148A6298B124E77CD3C3BB708555AC18B12A801A74B3A5D1046FF37D7362D2AFB4FD9DE49998
5C375A8BD28F341E2FC27BF18CB3E359B03123D70B74017FF0DBCD3653656570C7B80E515C458F35
3FA8EB9CC191F41E50D5FF59BEEF3164DE3C4AE2799E95DE6B3E6FED2D959433054E64D5FD92D712
CEAFB788B6F5A8DFE7E2A0A6E48CC2F2F69B853EF7A18B42C682909D4E1146A4A7B95116411230D3
0780E2348230325CC710D517CCA422A59077335D45DD6BD5736F4D749BBF4E406452196D47AC032F
6C4FCA712F237C53679163966D9F4F4ADA45F06DA077A06681B8B539CDBC773B810F0E02642F9E49
5520F7950CB9C45C461BF70409FDE1871213CC9F1546C39ACC71E36001F06A2A181CCBA3C2C55DC0
76C493D6FAC14BFBFEC84C3E12C5E198052C2B9A49A66D20457382C89149A598EEF9339FCE2CDBBD
9AF29BAAC264136EE3E44B4EEDC87C881610C05A5582C448FB93CA91712A3076B54257908448CC71
CB7227643A9A96DF4C7D9B8A0D996A19A0E11EF80828A0090BF2654326217B8D7F990EC76CCD6D72
0CBE9FA5E8EAC40E49D43481E6BED53D07FC9A6FAEEE5CC8CE3A0A029E81A98257B6D38E40A3C451
AC155D28A6FDAD25B05BCC64D9FED3C5CA600CEBF0FECA2AD224705F35B178E653420C638CA892AF
01C12A45A1EA9B032E87FAC7A3F8A69958D3F39D90363A846FCB4375A3BF0DEFE9A9672EFD9CFCA3
CC0911E6F06DE7E102BA0A0B8EC32B3EDA3286C24B9DFD7C43844D8D3D0B92115191AFEC6B1BA5FA
21BD14D2280A834DD8A50AB94815712F6D59397F6F8F6D63F2E5B6FB7CEBBCDB865CCF09C372A403
CE102BB0A90859EC9F4AAD5D99C71CC96D71D358EC06FC69CE829469CABBA887A42E46DD7BDB6BE0
E1D67E2E93AA7B4D9FC75AD4EB0765746649DD8B6A3B4FD16E5E2CA44B292BDC69811373F019B85F
2F890240DBC2F791AD2698117D472AB3BD118225B88AA181575F8C1C7E7481279C1107F3254D0798
B31C4EDABF0E432050F7067FE95DDC9DF01E05300BCCA6788A88289D543023A09D020C642D65F22D
1FAD2C14228E0D595227A090B3F82A5CE118F608FD187E5F13B1E9F1CB54CA1341B98292C762EF6E
1E52810AE05E8554B5CA4D87675FD683289CA82B0CBD708C90FD94C8E9B3A3214BC0856C98CAD6F9
F3B56214AD55170C0A3A4219B91B0A0C801E84D5F56B97B853EA74D9B58BD57EECC17FD28FE0AEA9
117AB7D2F1A5FBD75F727A9D100986BCAB0927738CF220F0CE18399A542C56D3C0BD12F8F2460046
18A86E9E18DD7FADCDB8404E02AE6404EF073C1FE34543399F4772CD6E22D5714DB9C2CCE15C2E2C
BCCC9A68265EA3A32721605C53A4C306DBACD8A779D9A0DF8A1926F8E42E2CDB1F46C31FB412F98D
9808972DF4002FD65D7F5B96B314004AE6B6B709EFA2E6A49B1C31BA550A10DD1945B136F921EC17
E21F3C9D6815375925E8EEEFD8FD7C2F15D7194A834DF35A35BE8B24BB45B3952D93235376D10391
D5E58730040D5B253830F3E655222B09C3E3A664D5794B04E635C10BFDD36F18DDEDB17E51F800AC
25F05965C8707D2933403E9FE4AB48360E419002114F9CEF75D3EB54286C7F00B684E5FFA031AD01
2B8E0DAB9447F78BE250CFF72D11E24BFE1264FA4B71D6BA4DF7CB1385BB1D1C6EF00AF8282030AB
FBF29DE78B1916A44717EE583DB2C84059C7CCAAB49BE02C30D53FF768C8F231C9D5C8772E0FBC9A
7A1536D7F5D4888E944D0BCB958DC530FDCD04F2207AE63DF8E6DDFAC7C9D0369F0BEE2F4F9795B4
1D5BD7EC7692EEDA3E1A8A0453A0B40DE0BB9FAA328A73550C63E27D38F64DAA400CA3C81E2578C1
CC3BB055BDD49B22B52B88593497F1B6DBC999CB1C327BE56E059621C8BFD536F310E03873E81B58
95FC68C4A0C72FCB98B8A98CC122635A811306830400547A90A05A7327609240F35D8790B922621B
EFF076D6E647AFC9032EA1953C90A9A9D11BD364E9D87543FF80E34C200820F7F8BB68EAA09B6338
88CC422C929A1FCA49B0C8393BE700519D4665D21D7BCC4EC8510C41F5CC8689A010BD296695A51D
21311DA3870A51495C3D9A13813ABDC18823B1769AF5CFEED3A8392558BEC27D969A221BDA4D144C
C3932A6802BDED7B25CEA53BF95C4A72FCD47372755B37DC6CF5AFD06277E76609AA469DE57D466F
EE4E715D1AC66F64CF9DB8D05BCD1859B5DC1DAF729B383164CB053BF7E4C4D493BCF44D99CF2087
33DBDAE346BA78FEBA77D0B17A2DACC1DE0F39A8775AAAD9801C8418FADA320FED9E65A49C36772B
2DBF7D71CD102746D59E7725D37BEA820C5D6305310C5CD7A50F39E18E137D4B6B1EE220F169C1FC
EF8A98C4CED943B281247AE08D386ADADA8CCE9336D87BC5E7D692C2841AF112286AD49D5EF79B98
6ED45430BC405521BD830FF16615BE70784CD01B0618A1853F5E9A88D04E51D4AC23EAB78BF4F85E
47CD4DB133029413C18644944BCDC34A24640B771499B40638F78E5B623DAC344E749FFFDD9290AD
0F7BE9C685AD0907B6E4AA05F33873352D9DB2EB0915F113725A14BDDA96967C87A23E2A6275B455
F253B97D75C6713CF009F1E418C6E884721FEACD3A6CFE38F0864D679FAA2B2C31709BD0801A9933
4667C825E67660C12BD8CA5C572DC3722824F9E25A1B1812CAB1406325974AF78D670C8F2807103D
541C59C5F2E06234089015F8FD6FBFBEB35D75AE47CB5041AD85E67218D00A8179530FED513183C6
2BCE29DA93F3F3D70B25B14DDCEDEA1F2F48248311955E29412FCAE9DB44E395FF396A7A06D5A943
044618C2842722E872376FB6E4BDE34155096DD1711ECEE313725726D719EF982730D17DA8F26BB1
4DE0384F0FC0D9EE37460BDFB6D9C8386FA60FFD86903F26C397062111986DFFDF147AB56704B467
AC7C7561B372C8ABB68339E951A9E87F8546B221E1246155521FC4A48CE4F84A28072BE14AA4319F
B6423AE21D46E0C186BEE518ED3C1621818C00B20202B177FACA5D2A85BC7447E00332F11260DAB9
CD96BF6A11C5D4A09A9F263C1F6C6699B1CB3CDC59F2F4B2CF6E525F9A010828738C9DF39BDC8599
964AEE155ACE538B8F6BF722EC89DA93206D462D776DF245B3321F89F4E46890C007C7E333AECAF4
DBD225E8FD258A0450837BCEF402753457BCE9067C05185AC346F5E44EDD0B68637C237FB7B1C2F4
C75F507DDCD66E7E101093E44898F41BEEC8B9BC48D0DCEB874C15BED8B25368FD484C5DFB8B6BC4
FA6786945230DF8043EAA343B6BE8FA132D41359B43A4F60F2C983B2B4D906EC2D5ED2C2696C67D0
8E52D0E1798C4AF43B9B2763BC2BF12039F72EF27FD80DE60D92EBE9CBC1A3E8163F5CE2C00915E4
3A5C83496F45615D9381F68DD0D098273BFBFC7629CCD3A4A7AE1D11A486557C9DB608C1782CDF3B
CD87E2EE66F7468F4251692A871F3057E862661E815A6DBDA226985D9FEC11A8591304B1B18DBCC7
4013988E9D3B93D5FFAF27381DDBD216ADF278E5B71575CC2BDD17E907A23E19445A306D30E8FA8C
E1DA8944597EB3950AA88453D3DB6A4CA02A93633AC02FB1A7745EDD01A622AAF9B5415838D133E6
F80163B097AFA4AB0E9182DD78A457566804D399118404EA8A9499FF2CD1EEC42B3F281B15391F3B
310A99F4F9164D622F8842F3F963C5472CFE321717C4D33C2C819951701163CB605B9046561A6FBE
2502527618DB66AF43AC1327ECF117F3E85D6CE81A8DBF43B28B68D745BE0BCE958C004B04F78B82
C480FF101857B92D4B9E9815E7C355E9AA3DE5C39CA54A209C4DCA9C21C9BCBFA0749214787D7C24
7B7FC748959DDAC2F640C24D33BB37EFFB4DF28CD65750C1258E70CAC3B3C36A200899112179C297
B946A568757F36F7CB774570C85B349BB139F784BDD3C920F86E8DA4B788D205772D2B62F7477BE1
3FA0E9610B238335A67954716B4909907D20F0CFE6196D857FDE7A44F39312B316030838D02A36EB
CF8B870391EE40FB292AEDDC9DEED63BCF0C8409E252A173AE07D9A611D4141840CDCA032D6AE8E8
3A820423D15FB4F63998B376B7F50186A4869F8E384B37F73ABD480EFCF4A583F8A5875941602FE5
C7D896777D7A0AF8E3F1C562DF8BC838B7017A6B47E13FB3FBBDBEF6BB53A405F077FF283CEBB694
01B418EE4576D4229329DA34D892A7B79CB6247C3093FF086361A54244449478FD24EDFF75317428
3BD2D23B04A43A539DFDA813783A2673EAD394DC1C7BA99521E111D2E110614CB4BE1239F953ABAA
C0700882F1617E0D489F1CE93F5A48F5E154095EE460866CE774D5814B0A8619DF648F48D47D9BA2
3D38DAB204C1EBDE97B71724A22A7841DB447BE695A3AA9388AE8D1758EB235E941312EEBB7A7C07
D2AB10850A4389BB5545AF0A0DA374DD3C0DD99647805AAD730FBEA3887E926B517134D1080159B4
D8DCAB9C172B56E759EBAE0A46C3BE2FD8F5754D8AB7182A54FBFC44D3584DB57252560FE95BCE46
6B3E218D239C6E06F05DFDF4FE8568EBEF0228FAB2FBC6FD0F8685D229375F308643D36B73A300D7
E8756A1F8AD9472A37C0ACD37E3040A2AFE716C1755407D4B906170C85D489EA734296E0FB7B7ACA
211FA5EAE56B74A41BE5F95997AD6413317C0AAA8D173240D337B32A7135FFD717545238D54ABCD1
F944477CCA6D6028C6FB5A6A737B7C1AAA39C69090BC2A53794D68B4AF866EBF33856ED2E8B0DF3B
A0A09777001F471D7181B05063794FC89EDDAE2A68C085ABD09786DCFD6743F15127B2D5ADEFD7EB
E51E0486F07E9429400955A45929834C76A786E00C04DDEDEB5C1B76128E9068A1AEAE4698BE63C0
E395FD18826E6CCDFB8C213FD1F829314043E93E5651677615C08AC37731FC55C21CD07720D3E121
E909BDC9C4A5EFD4C68372C583F526FB89F9143D19AF9D69053BFD270B8716CAB06174F57A51CADB
B715510C5E044E7E320531505158A5D576E223018D84C3D7269C9938AA60B0D170877A8B40D12EEB
BFA13F176152ED8EF28523FFCDB41B39B5FA1D15ED76CDBE81C4275DD0FCF5ECE65CF6AFF6005357
77C62B44E6EDA97600D0E1BE18AE3E783AC4FDFCAF3E4EDD6F64509C2CC6F52241187836FC6855BA
C1767C17E51846461598E6FF50E5D83B836C045313D0B05D2255030D6D8ACAC59E8D19112ED35D90
907315A4337C24F2B37732DA72E5434213E401D199F6D522B631B2F41A5957A83C1E3AFA22BCAE28
F96E28102CF54473EBE69B91C5AE89FAFC7599357EADE06FBA3FDB22C05585981DB1DE82015B5568
A96CFFB401C19697B7211620097FEDE0ACC60197CE35BBE8F702C237EE6323D8042AB0D6EBCC95D1
5296AE877D4F1381F0F5905FA3E89DD29FAB61F3946922D8B35ED0B4B72E1DD48E10801D824AE57B
A03A658F4884915D0019CC5FEE2CC608AB01148C16CDC9FA5882AAF57683F36B9B5A6DF113405088
DE6103CFE4383EDC9867788BAAF26696F6557A073E3DE77CD28C3E27164EDA87EF315A4F5B7B40FF
D2323928C7D2650BB39A7ADA11DF5939B82835DA765D1B0A748B0EE387DEB549DC867CB2CCDB3280
870BA08E81BF592314B5F82D8546A4034D5640A04743C9161FB84E0CA3BE45833D8944D539D0B36D
279DFC5845C66514D4B2D7D2156A4AF72A091379F3666A93B786DC1BB81C997A34F0299F67EC943D
095FC4C602EE580A4F8911C6E972A70BBFB9BC654F46111333AA1B5C541CD644BA9858AFE25F6209
D3B71A64D9C9B3ECBDC79DC58732FC534C4CF670096D9B093F654B13493F0396E0136837AFCE1483
829B30A1B3C119BB3091E4E22CB40E7E5E80C6A37A33FDE00EC668988A09EF9DE214CB72A03C0518
CD274E694B611C33C0532769C8A54735953514626EF4111E7450461257BA5CE74AA8758F795644DC
7C4824ECE4FF0B04745F72B31B14A999961D6646FEECC62D4CC32E9C829616A5D3E557F3C3BA0C07
C384625B66B28D62465BF56A7361E0136722FA532EFBD55EDABF443FDE0F534897C62F65A7F6072C
C9469CCE92AC1C7A453DECE5D1EC9A49DD9FC3676BCFD905CE7AED294C1628B900D02BFD67FF36F0
F7E093BE743C40851D9F555A4D9769107E9BAA74DD77F49E2F267F3B1CE16365B95ECF58491A78C3
8889D8EA183B2A46B5A5A9F7CB2C92E6853C32814BCBCC87DC59E472A974EAF549841C90A6177120
E9B88BD46619F82888737A264F60F42EB160A9D027695BF7BF633E311B69B953A925277862954881
EF4D2DEF6FEBD17CFF70A22A3E42E9FA7F2488550FA654243BFFCC031BD954905626095855BC4AE6
DADE90AF2D16B9EC3C942428065E707A0EF65C322A03C9AE3AB46DD85938C19D1628F91DD016AE57
4637DCFE1F323ABC2A3810ED8E398C3C7940F136CD20B270F52B94E51631A87C3325857A005BDD3D
60A0D6E7CE191187D6F3E6D1B99F489E800DA18CD5180FA5BA082F71E69F292E870FF74B6228BE9D
F6EE24CF5DA97EFE2DA4B58FB08F5B08D346F34D0996E2C14E991E8312BB9D0839F361C6487E62E4
130912B4E2CC9EF0870E5323E3FD0CC99A89079D2C5A3A13D373DDC02A978CF60F127E4699A465BD
531EBD6CDAE38EF80B06327CD5C6DFEC55D74B38AD5CE7A57BA6944E0B3970ADA9F7C4986BBA65FB
0C65A44E6D46FC7975339273165AC3044B36EA90D02260ABADB4BBC814EE0D790E2D9B3CE1F9DE5F
BD0E919EC87E17CBBE01AE9DBFB229F2FABEF668CC8AA7E603CCEA85CD4EAD276848919BE1FA01AB
638C9E1071DA42CA17BFC2F1887B0E45162F159A6178C4ECDD80D6B44FC6AD617FE55E474677D4F2
CFCBD97917DB0F544E41D2DEC35CAFE5E3595D6B2ED09CDF4B045766BC62EE0EE914F9F2778C152D
23878EC16A4B814DDF4A883818DC1D44FC8973496B6037FCE8E4A731DAC9A4F9268980703296D04A
C9A53EAB3BF5ED7455CC32C6C208DB744089101E0236525E217B70C03705B953F68811D2CB7464D6
165CCE30EA5E767BB3698643F13375A4130BF5E97FCCDF7BFF99CDB4F39CDEEAF81A080C288A2CA5
D361BF168343AB03D36CEBE860841C37EF52DF82A43882C9570256DA290A0CF749C6C7CE93DAB353
1F00E8BEA53E15B1110D5A734B1495D11341B4FD68BA619FFF2DA63C6242DB22560026055DF454C8
A814C039349E525BD852E006B9B7668EEC5F4AEE12B44EB2DC26033B92892DFA7347075BD6056032
8028C9EB6EFB146C4F8196812DEF47353337502C4098B90A3DAD5A280671B6FABC5F65B54DB02D45
D29595778209CEA884D7C56CC028BCFE3C7A3392053D9F063D7D2DF78599329DB13EBA49211D3284
0FF231C379825E3BB9627654DF612A0535CD81498961ADAC6BEC414DCA2E21BBBEB447E5C6B1A157
F285BA680FFC83F042ABF78BB438CC97B3F50A28137C99F5D7BFB0D7479FA9584A90BEC374B5FEA7
AF96B49C5ED5A26E81BFB27F2B4DF36445FE422019BFDA71349B9AF421FE2F682949035999D0796F
FCBA7181C3309059401E011BA660B5680AB60D5D1F7386E10BB72FF3A147AEC947C35872511AE673
BBE88963B56C3C0FA1B0FFE1B8A33D12ED714FD9595481FED55AFFF3057FDADE75E42F3C0079B504
04C980FFD51596795AAD2DAA665E836EA1163031D964B3C118FF934B8987D36F909FF64A2A9A7CEA
E9EE69E17921B77A1494034F3A6840C94957A7C1A7E23F393BE569F8ED7CCC2378112807F23F8CCC
F87B73927D35FD956582CE4CCD1108CC79641822240872F79A115F6D33ABEDE36E285757F0D92163
9A6F24F0206A8382ED126EA7C8979506DD0D1E4514ECF586AF9BF3D5E10E30DEF997429D261204D4
961180FA62EB145C91EBE47EE3F5C884152D1F61F4D70D7CDADE3CECC993000AD523A71BBA4393A0
6C543F12E1156AFD5D65AC954BA9937B87F1F7C9B96C7D4798EDEFDB1FB05BE7FF94F96FE5BE338C
15F9EF6098819CB5802FDB3E72EF67EAEE7856DAC816DB5DBE6BF3FD0111D282428650C5932B10B6
BE12361F69E8F4688193CA93970B92627434422578CC4003F81F5387DD733DBA53AA585E23C7A20F
FE149D68A4D639EA12C831FA47061C1A89384321FF047D3A64A2893323E2D43C6D0416F19A79BE56
DF5C2041C3292F2392399B1DE67A2BDC9028D7671366940D5E5B8B5D007C8B3D53CA44332A2ADFA0
5800A77C0B1DF4BEFCFC874DF5B9D57AE882A4989944C032BA40F2A1D1B9220C6F061075D605EA70
0BD6A891F6BD64230839B355B58A1892641B78DB9E0F1141D42422AA341FB68C7FC90B57695DA8A6
4DDFE8D8B4E44E4CD131279D2E0962D19010BFCBCAC566A08EBDB99E39F64D54C07DABD00F3D328C
C5C65D196A8BC8AD6255DD3A33E1146EDD911C654D3189ACF60C190D1CC5E799D645C774F879BE91
B76508D99197B8A60254054A68353D2893790CE0D11B70F5BDFB0A775CF879AA9EDBDBFAC2131A8D
B2A24C1F3412579A7A37148C97814835B174C92F72AE56EA550DEF367F83FE50EA54CE3A0B5F7B79
B35332D04EA2A94F02D45F5C0B0C76519C25E20EB7E245B71F68B86CCB20B3A6B755AAEB6DB0614D
C6F6A94E94B439D67A6427448C85B336E258C47E26498B1F31EB989BF6562630AF6C6A7E46BB2962
BEAA8E95685BFE76E43050AC70C18521E6803CE9DF184985FADB3DD13BD42769801F43A0DF483F3E
E980569B2806F421455D96E1E6C0191A9392CC3DBAF35615BC2ADDB5359B8326E0704457841C7330
798FF80A756845A729E38E4FF92FE39BD2A5A30D767CE603850474EC24E42E654FDE170686157167
566F4C4371C30C556933CD3591CD03E744829CEE4E16758C4C50A7E9ACA1C415A04247353B89BF66
96AB6ED79C92FA2B8028A3B8D5747F07A38D5AEAF2566266A8D0E14392A61D6590428FAEDE28C9C5
47D29572A5BC0F4DB8AFEB8F645B710B94C1DA6218DE06B2AF35ABA9CD313085AAFE9696029FF621
49AE8B443D7FA405130E407A8E003B4B1E1CCC3601240341AB7DA66FD3980FAB563A511F684F61DF
A210A358E19C644C00BCD219190FB506A069CD49EB4131BC27BFA3D8A1E0B2E5957D84AA0947638F
157DC432ADCF45C9533869455A09B06DC7F5E762FEE8B42F0740B07697CC74E335B7A8E9EAC55A41
34B1EEECE4DEEB00C28534C68F84A99A57AB811A48285556EE8C1CD8E172B6C664474CE910E43160
B5C94B377890FC2F98B3C11A4D610AB6C482662BE303A2CA61B78430040B2BE4FEAC3358EE74FEA1
2A10BF9963013BDC4B9A5EF1D79E6F3B3079D3EE5984098532DDBFD9C8765403B3F470D14025925A
F7429282855562EA17C547699028442CC6FD6527961208438078AEA6C9A2FB733E2C72AFCDA26CFA
1B4CE6E6464BB15A2715CA8F809831A23ABCA866604814525B20AD472111B682078FCB1D960C5E37
5855E9C1D80651D14399737DE2D38F48D09D337A02C64E9EB9A1C0E23D690CE6E9258EE14EFF596A
958699DD810DC8B222883D43F7869A8E213740E162ECC2783904487CBF3A3C97C56C4AEE84E85332
71D02F896B8EB751F542ED1D2983226BB3E57CDEB4AB5567B1432BF7BEA1F8F7894FC682EEF187AD
81B3039FB86F145A50988D4DFEF875B2C5DC4E49482B8EF771EB5BC54851A73D7B56E9DE49ABF01D
583D6ACFF6477AD40F2ACA0FBDBFA6A40067A3222ECCAE1303B4690B5A1407102DE47AF40222AB45
9C4EAC55C9BDEEAC5F8DA0D654BA0A234D3C41154CC17DEA99B5106B0F9AB27B278FF7FDDC96B1F1
68893E2012001B7E593C5AA6D8F3F9D35EED9A5FFDE0020CFE52C05282EF07A948EFCAC9933847F0
9F065CBC2CBE94B941757AA94226BD5A8C91B2EE4D8B3CBADA7218C21F7F729D66C7F5105AE36A75
C545582C25B9B1802CA9B2EA745255B52D47EA2FD9C24FB97A7283BD50A9CC03AA1AD62A8A02765D
74858B964FA2FADC2A2BC486E29644E42D508992CB4E872C6ABF33C64631BD6CF58AC5439124920B
901CC163DB5F612E42B4707869BAD07633538468173D4C9DD48C1AF8C92EE1997BC51A2FAB8FE503
38D4749C4359702692A4AFA55526FD413BEE9DB5AF4CB7D7828A80636F7FA06D29CFFD5B04C977DB
4271B523D1E741CAD63FC362A2202BF69519C4902A8F40C1AB648E17122DC5E03D0BD34E138A7E8E
B55889504CB628B0EB62329CB20BA119F8C17FAED74BA7674E61032B06E0002770A09F752D2E70EA
FF01D45E7C59B21DF3DD19F4118431AF7D25753FC58A03CD1D1EF0FFDD52C3ED6A1D4A0262106CB7
3E68690A0C8E4A8DDAED8B69E2BF4D65BAAA8C0312B6768123B47EB1AC65E4E194695F7BC3BA5149
09848DD02B00401DCBAA5F0F0380874E762BD8DD3ADC9A3C2044B3B67B91FF7E5B1DDD2F6FCD0D34
37B9400602A1767E6E5838592697B146CDE3596DA1FF9DE0B1056B24A875D5BD44A0676B04F32DB3
85EA594FEF43DFA0932B45533DF133ECDB6876F9479A639F6B261727D92074D1394EC144D001187D
EB273A233BF57DC9C85B1E3556E563A42917A501B4471BA87FFF51AA45C839C94840640FEC93C684
0E13598AF12AF9B1A295DDEA337AED3FB0D03FEDAE105E416AF3C492F8BE6991507D0CFEF533F4BC
45ADCF2A5A388546386B0DCFAB9F31146F9A301CBA7BED659E538556D012CE4FED30C1E9104F2363
185AF568D43E9A1943667EB976A20FCBBCA89E3D092D7BE98F9E3DF0D48E09B4E0313450DC13895C
8F513FF1BBAAB38D5381410E9B8F318FFEF7C7C7B2F45426684E5131BA0969E0065113BB6E83DE77
1660C126980B24781516AFB2F0BAC2EB9B702DA33E2820EDDA16A9AD5407DA34D1CB67D793E86369
8942C07B609A8C8B88E231703AA662303101A8673B923CFE67A73593A9BEF84CFFCF53FE3248197B
4ECEA6238A8F92A5131CCA4D64343B69B569603F4DF8D4D1EC5A3B68A7C6CBD8365E56A0A5261080
52824081F0B8D78C69BBA02E8C72EC7EA453D9EA3EE4E9E140918A29643C98422192824F885EBEF7
3E9F33B8F48FE8FD12B1700D2111FDD8882430B6A6EAA914FE4264F95BF77E5E5F710A645F5CB6AF
1CDFD36C59958D13B19986DA56EE816A564E5BEC79CCD7B568040CAF66D37DC5984D674747228AC3
90D5E759103F4C543FDC1EDBE06B7B20861DE6440D00BDC04C64FA797176D3E2B310231430AF9C40
A88ED9F6221218FF9BB415A7A4AB3C4DAA41A0F9E0090BA49DFBD2BCA7ED706126C7213B79CC6C0C
7F8CD21A0C52054F76CA33760CB9B1993DB2FEF43D9238DC3DFEFC4DAED5B2135FA02B2343AAD0B4
ACE70E241DBD27DBC46A56FA1C0195C832594424C7125CC041002BBFF738A4D74D7A1BC221A0B77B
4F96DECEA0D07BE373DEBCE653C06493ABC66E6749738D82C32457D6359D3BA2BAE0D04060401528
A2A21259C75C82DB9E5187EC11D12E588DB76BE357D3156116C9B46A25A5DD03667BF4C43656A1AF
21AF6877B7CFB28E409C664825DB7764C12BF2EB48AC80D24FA2084B29A19690E353058D9511F66E
9FB66F4B02610310E5ED3BC55AAE9E3D6A68FCD22472F51D851D84D4DD2784B8511EF998BAE50FBE
0420A3E2BF0076DEE20166B996310FA532E160392A7721FFBFE25E6A69D6F5B16CD2061A38EA814D
34055FE2CC65A79C6B22F6D2A7776075F84167CAEE14FE886B29B08BB95FECFB4451D774DCD191DD
A8894387910C0BEF73DE1DE664A49191BEB6768BBD92C7E7D5281B1D51E7DC8FCB496D46895D2A14
8B642ED57CDA5664884F6B70CA7A3A091AB3E2339D12EBCE9B47EB1707E48B56BD8F29DAC469F427
025172B67C4937399E7C316954363B69C0EBBCDCEB711309C8EA26E0FD1045A3692C738C31BB97F2
8C777CF1922142F441EEF8E93F02A51935F100FD66626B9C3D3E8C3B83D595282DE70AD3972DA525
6430EC845CDB0BD2734E819BF9E95FAB963DC5B4D4091D2A5E8DE0627CC66E2931F6DA7F71764BE6
3AE929289B110F4A9AFE2C369052D26AB4A96E028C077034D1FF17064AFBB88BE82D89874CB66909
B6C81F18AE0A86789168D9B12B7B7BEA6BEB15A73CC7A005162C1E457AE16A617A1988D3C1473D58
60077D2FF90948B0BD19FD27596F28BA3113491797E84C756DB59E807D488A824067D46640852FFF
E3B7B8FD241D1BAC1BBB32DF42B1B42914E2FA4E12B76EACF42FD8FABEAF5C11A256D26459955C27
E3EB3CFC27C92029EEC69DFCFD57E2AB17B2DF848ACDADFC14DE5FC9CDC11C310BDCA14008FC4152
6FCA4A305194197B3F5663A4F2B167728CA682896732ECA225D6A2D9A5A8DAE07F29B32CA5748FC9
A4769BA800B85177C7232CF9FF4239954B2C9D67793E181F9D1777189107B8CCFB27B78A20A717F8
4026040644ABD08E36FB945379144B7BD28C3C26473D6E1B54F5D9852AA5262EC45F73F77FC1D23D
EED42448109F5B07DCAF7F65B255F91CD1D2803DEC7EB6274A699E70F2085B50833C8739EB175282
318DF6DEFC7EC9BE52C59102C0BCE45605D5106E47D5BC617628A904CD04E8F5B6AFE2D15B708682
51015AF9AA13B02DB03A24D54358886CBCDE6C5F92220DD809577A85AFD0035A393BC25314899EC0
B6BF1877E5B649EFC9A3FB1F1BDFB458573C969961ADD6D584E6EF1EEF516BA2B53EDFBDF7A1D8E7
42311F88275E6414934DAE2C7BAD2536A8B8B6BB636BF9EE59371DDB92BFD229F101F5D1E0016AC7
33CFEC9E4EFE210C75A875860C6B30A0FB4D59A68B45D1F86BCCAEB64069A5B8B74841F9769A5DC4
2D9D9997C3D1C75534081D44B2E866FA168D1C8E99831EEB5E51BDE2A858AF18F34427CC6611EF89
293496FC353C7618F423991EB0C5499B7B5F31F18DECF2C5B58C0DAA57E06BB8CB5F16182E60AD68
D8973C8C88CC5CB0DBF436C7396567DBD8364EF84B8B4255B8A6E078B5F4FE72D5E94711CE14C0AE
6A3FDB7025ECA332E0F0E73AA9A345E0F07405D7DE0E3717DB9C1872BE57604D8CC0B60F5CBAAC2F
D58AADFC97E6E4D20E2B4A2049C64B12F4AFD03E1FB8407F2485C0283A9C9E29C5A469525599A80D
35087150B19A9664E867A3EF85629E27AF8C32522E06EFA204179573A6C8B91C8B2FA87A21A14238
370F8E25F454A84F65D46D6032DF1B80C6C65B11BE58B6857C777EC5F08094FC463D7E2BCA255176
B7181D312602207226A5D645E9050785C2CE0CE541AFF12E72E0885161975974374832D80D66667C
EA20425B951F8B284928D731056736730A601E24C644A57BDFA39C2A47D1374CAC0DFB32B6E8BD03
AD4FB5D65D70A71F61CB60E6D5C543A30B539A55DC0D25DC2B26E89BE4EDAA97725D17E15661520D
B4EC2C91C7DFAA02FEA8E1BEE8FCD1AEE0883CF0D71318E54864DF4D64977CA9EC63B1E80F0DC57B
8F28B0FC1F82F0C65A62597794B3D07F850EE592550DB3316146A637C5374D500E95CDAF32ADBB1C
DBB26AFF2390E6ACA9057CAC94E20BD8594B9D8AFBFB83450F859D8E509CA55C4B0731565B803E6F
4164CB9CDB1A567622621BA8B1ABF656EC9FC8CDEE8462EB1E34FFF1A05981551A4AAB7A2905F1AB
EDD56C7571C71F82CE6A4713F2BB7C962FDC547D57A316FADB15D9A656B2A52713B5D3DC13931D67
2A2CD26AABF8192C63D662CBC09605C13CD361C1985B626401C71F7FC6C95620B390310E404B9821
EDDA0C2252C67558AC71DABD86C60B28ABEFF122D88E4BCBAD706BE21398983BDDA7A0BEE1E5FEE3
B1C43141660F420F6DBC56D20C8C8870B1C8A73E0F6099B5A314B97C04A3633F23A2DCCB0968AE32
B9D00D941C2768A82E59EF75127DE80A548411F7883F556FF356680B109B6365DA4164E558548330
F99856C1FD15DDC164BB77204DEAB3C54F62B2FB464E4E76850AD14886EFD8788EAE3E0DC6F6FA0B
2E304FBA04856033301F8A580055539E14B91C2F7FFE7C34CE3B54A18FDE8538939D38C854C8EDC9
B7DFC61C1D7FD04596E71AA0D3DFD8A5086F5529BC78625E19329EB91D03A510F6D90E6D4A70B6B0
2C999F4ADDF87EB893C120FDAFBF8643074DE177691CF3861C54C5F6479AF71DED476F30164B5437
F75609892F059B79CD8D4DF9DF08FF3D356458587D86EC5B75F4688151E08FF5E3F7E15059B00BF0
2A6071BEC3BFBD09026EE3E44B4EED8B9892C9C4A5996EB8BFD9F2C3F8E120D62B863F65C2912950
355AE8F5F961FF03DA04AC9D172843FD370343932F9089CC1BCC97FD9EA1302B335D328C945F31B6
3E1B11392FDF32DF4982648F4214B8156B9BBD604842E446C5BA91326AE2105FFE6B5D60E8AEB89B
6DA38926742089816CC8D970890D686B593742B7E4ACC4AF5642DB6DE618D35BC777DCB78681BA28
98DF7C8B6599DDB71C4E9767D486976AC0945A093A8921DF989FEE56977435068E5E3B1E777B3101
DE057DE46363ED35F29D1D8BD5607EF3F3F405E7A9CF0FA0F6C75D0E1945B7F115D4F1C3820483E5
91809B24C0FE08DD7BE132DD404ABC80A104CE6F23165094BAA2C6B26F25D9E4E3EEBD280037C981
527A4A92286632B261918293CDDF14FC5AC579ADEE68728DA2D1EB4E7A7CE9F35AA2B553CF88D768
76B7CF669C698FF001F3B74FE5A0F279866E4B1DC74DEB73F20201A5B488B48A4B7134D80A563ADA
5F56D8988F85AA869D898596CB628D342AB3DFB754BADADF20A5F6A7A4A096B5E06A2D529848EB49
3F5C279ACA127B4642CB46FF78F546089D360E2847A64FF3881DB7F5D58A07F5FD3898E7A23C8BA4
3DA812643684AB81B95C78600D58AF3FE1C7215A7F51103081C938EC5C942BE3A349FEDF4A790B60
CD497BFF4995260EB2B03576BE129CD14C8D25425067F49867A320664346BE5ED2714778F69D7E18
237778661F75F00F4FBEED52A4ACEE7D07631084C77D8818AEE151C9EBEEF041DBCB32C5DA35F9C2
F29429C280ADC8B4806333B1A2E1C04DE755D0A6494AC50ACCE092111AE534DE1F1E096E66553D2F
882A7A5C4682B003C5CAC009B9E8CB1DCE098603A0C66DA81CD06F5B6E3F11725A4F8A43D2714318
85826ABA1F5B62F19EBA700201D733D0F485A8C84DD42A3437AF9E4D252958D6EBB5AF05E8327B1E
48CF5E504F63C6A7AE307F9B2FD50823A84CE1BC7FC0D399C7056C69236B54E9AD27B2CBBB65280A
1E92D5D0B1ABE64F9B3F223D1969E095E294D60BF3A7EE0E444DF073EF6DF079659EE7EB96067377
E3A6AC3F716AC6A67D2CF348CE94F4BC7C0567C9A42AE9E6F2C137936A192F04C16264CD6B33E339
F664040772112A5C993DD64E3F4F2EC74E5A920650E5B10427F30D1B47D8F07AFE973DA8125BD040
66C9065F77C733F516A6E04B1E2C77A85EE796C4B255665739396D14691DFE6ACCA718A072D333C7
2FE2F149F7EF0FB8ECB3D8CAA86A59327A244A19F52A73227027F936C828E1A818226FC07DD62047
6324A40C3CF26996B4CC434C6A922DFF3510A2EA7009E7460207E68D3B6E382633059EE70ED6F985
E7BFB9A5EEA5B5649CC54EFC0123B68341BCE62B06A06E7B532118269C6E5329E898DC781D5A3B16
0222D22EA6197FE5E57226BDCB9279AF8B6D4060FFCD523FCDA77372EBAFDD0DE50AF4A02D2AF6CB
1B8AE822AA1FCB9F89D05B67704DD347BC5475A45AE1B1CD1404C4991C3D81B1FD2ED40314F9F6CA
AE0CBF6492523EB48A8AD47D65B906D5E8B9341273D6D2FED1B1DAB8981E7DACC352BD2FAD2E68AE
5640EE8B571E59DA4C79E80CB6FAE9C04545D586D3440B6ACB143C423ACEEDC11362C055ADC4E005
7D01B7248BC1746917A55BA0B6177A12C2CF02CFED592FF6C3517D47293E0A992D6A831BDF5855C6
320BEBD3FBDFC6DB4FE559A6D9807C389B1EE6413071F8E6BC170F246994B1516CCD55C35507ADDB
63038326FD77C6C89800A85C512498C7DB43D3BA4E69BFFC78BA43CB380FB257691289AF0C288E36
690C29C904C79245CBFBA9FF5E949384E075B189C052B0D6FC990ACD232A7470CCF70F4ECA2B1760
1C45EDEDD84AC6C8A27812482BE6276F8004C55B9FFDE8121AB911E56CA1124C963DBA9CD95B169E
A152172DFFFAFEC440727A94FFFB5BE82275E03C59775BABD36C2FA89048152E3AF9CC153B89A5F6
1F350F1DC66200036BF96405E771CB344B52EAC96E23928C3823812E28878CC2078146BD9B9810A6
C41CB6256281EC107760898EC967BBDE56F508F1FDEA0DDBA93FF86EF0E66FB038DCBA58B515BCDF
B290D3B28527AFAF825F1AABE2A385B79892C461A624256B4B959B9F4A7AE9E846A27602932402F0
7E5E360D3ACD0EF2092ACE9C9360E164E92B7EA5FB9701BBA12605501F30B4B2BA357E4D943B3AD3
52C2C3E3B40F3C539AB12994D2DC927567D9ABE7614A73342A679BFDFD3628C08338E9D1767E4964
41F33A6F9DEFAB64B4C442BBE4025B64E8A12F660611DD5D7F5F0E142F9D4EB3F349B9DF32685655
9E27C4FAA8CC210AC101AC6C90F16CDCE70C6CB10160E353269572D13D1F2CF4C76E81022540E91E
C82D673BCD4019BFED28896CDE1B25D69CE7C80C194B5F1D9A4D4C19B7556203E088E55D0EC411D1
ACB8287DA4E128B8AAAB35D0E9D628817ED04BAD8F86872D4253884AE65A16718436F8315E22C943
D093E1EFF6A1D64ADDB89F9F3D6F670043531F1ED5653F45C84513C4B4B5C997DF41E8A831750423
FB403E1542C988F2ECE71C3CB38303B103CDECBB88E009FBAC4B551B80B39AEA6E647504505BB779
55ADDE0931783E2AED5597D0C645B1095E9ED313385D29D279DDDC4AC49B8087B9E50EC103456485
6A231E2F3D3C9A04DBDF6DE8A045A46845EF87E674B8605A097DFB72B12645904D1CFDB0D8CB5BB8
7DBA997F68A6DC62D2E81A42B011BB0D8C7D5D8A5A81AD95E2A7140258AE4ECDBDA30D5AEDE8EFF4
375151A6D408A2C522510CC34DFC2A9EC729505143711BF851E2D7770201B0AE6AB508A9F650A377
D7DD307EAD18A588B2855311C3231BCB25D92A1ABE095A6AE6DB8BBE6C8A7276E5B49C4E0AFE1C51
64A833E6C7C67A19E8269566BC2C1C999A5F012FD42B1C23848E71B5855A0CF6F5F99EF2DA0C0CAF
3ADE979A7A8CD593DB6CC6CA2C4469AE5CF95A1D2E0324CA918B2559D6787571AD08E9C2560C38F6
A4B09EBA079F0A3518E7ECB53AAD8EE37E3F69CD6256F141CA498168425598ECDF2DC6844AC8EA07
293A59C6B3B8B103D8D49A1CCE2023B72EF6AB271A6031CA3F4D10EF334A1C339E3BA3556FFFECDA
64FC49BABF5B1C4A4C1865DCA3788526C09FF0A11BA209B9FE59BD3E4FF0F00083A1C469EDC6D5BE
C739378EB7879ED3C8228046532C32502DD4BC69E418B298A6C43046DD7FD422F914D56471602C28
C7228E713CA64BDFAC11D01F63A648B9CC182C0D09B26C6CE1E0642D689145BB5BECF10491EE137E
E8E6871B8D1411837C2B4D07D8C60E0E6BA8EF39BE53F89E0C7EF30BA237A63D2A860E7D8DEBE935
1298EFABC6909674F9CAE43E608F0C15341252C452C0D0457DE692F825B04EAE56100BD2E224E176
75D938C5948B6310D444D803AD8F2EF6F808529ACE131AB84D81CE168C8331E6F4551FE86AA52C40
28447444BE4E8DB2CF36DE7A106F8C460EFFC56BA0D3B5C6E22E6C0AE54AB480B177FD81BF41F2D3
89BB19E47CE98A1F0E943A1837D29D9E0DB9E49C079DF7D36DE5B253192FCFE6B890CD44C5925069
2602ECB3DA5FBFD8B5C2D174BA46FECFD139111D4B06A5C6E1E977D4E65D2532A9E6BED141D0C7CD
241E02F607E118369CFA5C077D7399EA411B6DF118ACEBD61808E84025F1BD17B1F365FC82B25EC2
92B0BD1453C312DBAEEA075058B7E2A076B773CACA3A367B5E45F53CEB177AE25417BE06DC440786
24E2E871A10F90BC341DA979F2BB7026DA11FFA15352FCA7D6999E111E5BF8BAF04542345DB050BB
5B9EB59812BFBE86C41CBB82931CE69F76D3979CAB2E2F32C21E9708A44C072CB6A2A6FEDACE5A43
6A294C98879DF73C54973A902145FD96A083C5DD25DBFCC41E1E1D738E2290EDB1E424C4017386EB
7828DA15D4AABAD16F6A1946893E0486D738294D4DE535547BB0CB70EE87B8CF7A4067FBDF77E6EB
7505D378FB944D017D3873B1B7C648E57A284B51EC33253D0D300DB5C91D1C0D5BE7A27D1444B1ED
7AAAEA3BF5DC2B3BA22246F2764AC360B1E339F9F62409FB4F059E8BC33DAD0ABCD986BD8D3F9D40
F7726C3F0A019C381152487E4F32CDB0FB1FA225AFF04D68B5BF9D61A0C50E88D4F7B905E46F5A0F
52BF052A6077CB01EBF51ADBBE43B7952839BBCD4DC7BA6CDE368730E772EA68F73F8D088E156C59
5760AAC12D6C196AE8824F90A7E3BEC1E48CD99046CFD36C5F744BAA619BC681152A70BB42CAEF8E
D3B37B713510106C494DE34A682D49011C3A2DE2909FF5E97635831AF676C49268FBEBDA1D877F81
E50BADA456935D7A5F67798D5D90243C62BFB7EA16BD2E0C38773EFBF9B6CE7F8121845330596E92
28EB4570E0FD4563C763B61D2378D15E871DF2C180D371A7E8B522F94447CA5FD631461E4E923307
031D1C7F525FD692D665173F11CB1611C6AA9E2E64CD7E1C0D594C3F81B8A80D88EFA3E8BBA82DBE
99D954DE0D5164D66EACC56E8DB5FABF645EDF69054628AD4C68F02AC935D5FCC1469DE9E33CAD65
74F9E9C1DC6A40EF89D03AD93A3AC47E49347A5207A57946E72686AFC72FA20A43C79E13770502F7
45E2A89E5AE6A534E434FC2FEA7F377FF916E2947B1E8E1B5B53FEB4E5D5067B818198008988331E
7F09AA7720680E694F88F94FC62E82E284A40A01E5C19626218277633B5FDAC33CBD2A89CFE51DF3
CFAF5AD9CA44B333CFC4001649C5E59A7005ACEDE2D21F149CA8AA2FC080047187142878DD224373
E2594B4A6E2EAA6E08CA2FD1BDD079AFC2E9A7CF4FCC57D0CA62D1C43EB402904BE9A5AA2D4B364A
4471A4979EE4A80C2DAE9B944B6362815DFEE4EBA189DE7A0546C6EDEF5BE6AC4A9E87F65770A482
7FD4774E8D97ABDB5DE4FFCFA1A01B92DA3525701700786F3DA6129DEBC1783F3DB14322AB9B30A1
CB2F365F6DB3A7036EE76E3AD0054CF800708F24FC2BA03D3EB297D2001192EF57B84C8F98FA2B84
03F63F3A82220089B8D742FB85B83552A9A58EA1F2E2B22FDF96927306F2F0EF11A9E389F8571BBD
BB948305D11B10FAC6EA68082B7FC210C10E35D138051995D57E45C2356F60EAC7AC895E10C46D35
0194CC8BBD3914694456F216A2BBA872ED26EC0A92CF32FC0C86BF74CA3C679EFA12DF549075B593
E886AA2CC19F112CDEA530727AE6389B8F3D8767C187CC9DEFE73B32F4C6B8B4B190F0D3E3F44CDD
EE0505F0F9A374B3B8146FE5508E4EE41CAF82BAA2013243EF03BD53D67581A1B80B96AEC280A0BF
A45C698CB917D650C31665E3FFA9413A2F901D1FA96945E6628B7479FFBEFD28C1692555C6DEE0F1
CA39D6D2208320F47EA3D7A2F2A6EE8CDC5E84B1E09A3AB908C39D698A684C7A34A671516FD3A82A
378C18012E0407B9024114DBA2DC872EC7700613C068CC520150E71F65C8F68A97692643F708AF39
8D8CE88887C22287A57D5BC3E890ABC2EAC841526C77789E389DD24EA263A9DCBC66775A9BDC13AA
2E59977E90D354309E7BE04F9578E54C99DC68B7C0072AEAE1978458ACFA56A847FFA38C298DCBF8
257826588F9AE94B1996BA7C07D67354A2A57DA5C499E6BA5CB7001A7BF534B3558DC2BFD9AF68EA
2671601BDCF8220CFBEE27122A7CFF01915B2496E00C4D55CBCD80F75547898D0B7D52BCB10B8BE9
FE97120D26ABB67DABE38D5E0A7E11235E3ACE13126DA4296B0A748663A5FF0F784688FD0AD4EF01
D9B6C60BD35D8EF581886235D020C4AE0E4C60C0270F6C80FC59A9A2E93BC26C90D99A293533BB27
6E94BD41E38EBE26E2EE26D4706CB58529CE97A64BF989F83EBA022E660A488B7BFBBB957E946972
570F3524E4AE398AF63E355B7CBED51947D57A0757A6B70DC3E14E489CC3C0A85E1B89D35C37D91C
95D63362541BDB71C719534341A574512A6F3B42040C7F962AA555FBE963FEDFCD9C0C400CBD57BF
D4D8D1639C26427C97CA9A1249202871C127084A1514FF7D10CEECD7B9AD892364EFB929F2D250F7
CC048DD93274A3E5EA5D83FA072FD1C7B6576551E9585C91CF15E72E35E54BE529CF74B0505520D2
2D3F42551C315DE3987DE084973499DD79EB5C3C93BFB65AFFBD531CFFDEC705A9FC1AB99E6D02F6
601107D45CF1B6DAD436767D681FCFAC276C5E12AE94EFFE963C1E06FF39AE292869E6EEFF3DEFAF
0505710F8FFE499C1E087D67C472CBB5DFA62D98D46EDE92910466285AA6C01CF1B7452DFC1E43A9
B8BD6F9DFA036B67361C22BFB630AC0C3A3C5705D70F7CD582349B6F0C03E4A8EBAC31FD1A571A95
93289796D0EDE52B6A2759B8F7C70486CF4E48AE8430D135CBFB84E86BCCAE96E534B59EF8A044BB
6FF7243B2B876D2A60E3F4DFF82DF100F678D87E234408D4A11CD668A49285DC7E76AA5FFD323C98
0FC8A2ED7322B786346E177C097F6949013D146DFE17D0E098B7916E6D182CAB71590A26579FDCEF
AB937BEAB669C7D53E3655B980EEF2F069AC324228533053061C040C80A51C72613498B689EA087F
00517C0433949A9455219AD3BF63716CDC6EAD6950D507F48912C2F81DAFC57DFC55839735080A88
B781AD0F4DD39C3C4F67FB160E0AF9446A5E7BF2FEA8862EADFBE3F848653BF171126EB617DE9637
AA1F2C10CF6DAED1E4B375A1AFED43B0B6184F96423E774D6DFD82AC4CDB7D9B7D5E015647C14126
A7076613CD4BFF90044E63E173F6DDF479C99DED7F4A817E20C8D732F5A6DF24EBC6B0EA562204F4
496C140A6703B102E573FE7143F19A07C8EA08A79CBACD100D1A4F110059E6CC2552F08EA200C9FF
A68A15B27B8E899847AA6C8E5B2147D5CA9A001A49E40E768FA625B0F2FB59C265A82B7DD316E8D2
4DF1C37B43CB06D560A5E098305A0E3BA91E5EE8B15D74E2DE05739D7EC683DE3D040228225D33BA
CA2AEA8941202981495239DB7C7902000743D158AE7B0403525A10C5FB67AC51DEFED5E11DA96325
2EF3E6321D28DDB995E43796C26254789760E23FE91D93112BEF6D7E73B706978F9A3320AE0BAA88
E9E5CE72A173DC9823E3328F2CEB8D54A4194A2EB624BECB042AF35CE8EBE640E6AB7CDCF3977A63
8C120BCC8D3CF16D1E3886260C94787BD81950985FE1585AF56E75A32F72719F933B32B0EFBCDF6F
C9866C1BEF5C1D24D36A44A396E7934DF2893D6FDA7DFE1ED78F1CBB17770465423A1ED92C032743
6F0D3EE716751B00865BE1BC72033D6EF49EEBE9659E5AF17EACA02E2FA65807954AC9A81EBFB397
111C77B5FA4F4883760B80F65DF76FB11AB820E4330BFAF999FA96012C3EF20EC105FF40429C107B
A590499ED9B9F62CB139766987E58E36507C0593F6E20E314EE96C617B04C14C5BC39C38F42B4F9D
DB7BE676820DF530D87C1CAA5C91A35A05E5F565121A1897AD81C878A4F0A051AB24D28A60D09A44
560685EBE9D1A8B6C50C93FB445066B599076AC8B486E174AE265FE494EAC2E381AA48D6BEEBA8AE
DD3140C85246F54123DE9905DCB409CD5B2B4A4AB7043644A945D612DA34C172AE630EC25EFE4BCD
A0A0BA8AA13ABA9044C96F18E2F817876F768B5C843057D382363DF658BE9A11D66AF675130F39EE
DD460F2A2B0AEBEBE81B082B51B4D7222E342DE5DF9011B73444A272C394FB616A01AF6C1057DCD1
9A5CD49191F755327F11FD7E65600EB331394A61B6788558352C9A60809903AE2B4D9C9D2285E10C
69EAAC4DC12AB5BF95EB77C6FC5790122D5C5A4598BFF66CE01BD7190F852B5883891CE5088F19EC
CAA29F88677AD08C1F83AF3EA696B15732EBA4B709EFCAFFC3798C4200F91F70878BBA86641AD7AF
5BEF57F7B217F58E6585A3383808E8552EB377D30E245F9F2BE278B1D0F749E061E40B590E92283F
72D82EFE635E4181755EC8CAFC0D3DF460A2E6E16845F5AEEE149B5854ABF1CD856F517A0538527E
2D2F5A1CE2E3EA151CF77176A50113B54432E5B8B1E983212540F9C7C3FA63CAB53E75B02481E7B9
E725AA51B100C5B0CA251F54132D8BA3AA574B472E4B05FF2A213F6E7AFBFA27F796F5B622338AC7
602CCC54BB721C81E1B931ABBAF0AA1A8C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
cleartomark

View File

@ -12,8 +12,8 @@
start:
cli # BIOS enabled interrupts; disable
# Set up the important data segment registers (DS, ES, SS).
xorw %ax,%ax # Segment number zero
# Zero data segment registers DS, ES, and SS.
xorw %ax,%ax # Set %ax to zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment
@ -37,7 +37,7 @@ seta20.2:
outb %al,$0x60
# Switch from real to protected mode. Use a bootstrap GDT that makes
# virtual addresses map dierctly to physical addresses so that the
# virtual addresses map directly to physical addresses so that the
# effective memory map doesn't change during the transition.
lgdt gdtdesc
movl %cr0, %eax

View File

@ -53,7 +53,7 @@ printint(int xx, int base, int sign)
void
cprintf(char *fmt, ...)
{
int i, c, state, locking;
int i, c, locking;
uint *argp;
char *s;
@ -65,7 +65,6 @@ cprintf(char *fmt, ...)
panic("null fmt");
argp = (uint*)(void*)(&fmt + 1);
state = 0;
for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
if(c != '%'){
consputc(c);

7
defs.h
View File

@ -62,11 +62,10 @@ extern uchar ioapicid;
void ioapicinit(void);
// kalloc.c
char* enter_alloc(void);
char* kalloc(void);
void kfree(char*);
void kinit(void);
uint detect_memory(void);
void kinit1(void*, void*);
void kinit2(void*, void*);
// kbd.c
void kbdintr(void);
@ -165,7 +164,7 @@ void uartputc(int);
void seginit(void);
void kvmalloc(void);
void vmenable(void);
pde_t* setupkvm(char* (*alloc)());
pde_t* setupkvm();
char* uva2ka(pde_t*, char*);
int allocuvm(pde_t*, uint, uint);
int deallocuvm(pde_t*, uint, uint);

View File

@ -36,7 +36,7 @@ multiboot_header:
.globl _start
_start = V2P_WO(entry)
# Entering xv6 on boot processor. Machine is mostly set up.
# Entering xv6 on boot processor, with paging off.
.globl entry
entry:
# Turn on page size extension for 4Mbyte pages

View File

@ -9,42 +9,45 @@
#include "mmu.h"
#include "spinlock.h"
void freerange(void *vstart, void *vend);
extern char end[]; // first address after kernel loaded from ELF file
struct run {
struct run *next;
};
struct {
struct spinlock lock;
int use_lock;
struct run *freelist;
} kmem;
extern char end[]; // first address after kernel loaded from ELF file
static char *newend;
// A simple page allocator to get off the ground during entry
char *
enter_alloc(void)
// Initialization happens in two phases.
// 1. main() calls kinit1() while still using entrypgdir to place just
// the pages mapped by entrypgdir on free list.
// 2. main() calls kinit2() with the rest of the physical pages
// after installing a full page table that maps them on all cores.
void
kinit1(void *vstart, void *vend)
{
if (newend == 0)
newend = end;
if ((uint) newend >= KERNBASE + 0x400000)
panic("only first 4Mbyte are mapped during entry");
void *p = (void*)PGROUNDUP((uint)newend);
memset(p, 0, PGSIZE);
newend = newend + PGSIZE;
return p;
initlock(&kmem.lock, "kmem");
kmem.use_lock = 0;
freerange(vstart, vend);
}
// Initialize free list of physical pages.
void
kinit(void)
kinit2(void *vstart, void *vend)
{
freerange(vstart, vend);
kmem.use_lock = 1;
}
void
freerange(void *vstart, void *vend)
{
char *p;
initlock(&kmem.lock, "kmem");
p = (char*)PGROUNDUP((uint)newend);
for(; p + PGSIZE <= (char*)p2v(PHYSTOP); p += PGSIZE)
p = (char*)PGROUNDUP((uint)vstart);
for(; p + PGSIZE <= (char*)vend; p += PGSIZE)
kfree(p);
}
@ -64,11 +67,13 @@ kfree(char *v)
// Fill with junk to catch dangling refs.
memset(v, 1, PGSIZE);
acquire(&kmem.lock);
if(kmem.use_lock)
acquire(&kmem.lock);
r = (struct run*)v;
r->next = kmem.freelist;
kmem.freelist = r;
release(&kmem.lock);
if(kmem.use_lock)
release(&kmem.lock);
}
// Allocate one 4096-byte page of physical memory.
@ -79,11 +84,13 @@ kalloc(void)
{
struct run *r;
acquire(&kmem.lock);
if(kmem.use_lock)
acquire(&kmem.lock);
r = kmem.freelist;
if(r)
kmem.freelist = r->next;
release(&kmem.lock);
if(kmem.use_lock)
release(&kmem.lock);
return (char*)r;
}

19
main.c
View File

@ -9,6 +9,7 @@
static void startothers(void);
static void mpmain(void) __attribute__((noreturn));
extern pde_t *kpgdir;
extern char end[]; // first address after kernel loaded from ELF file
// Bootstrap processor starts running C code here.
// Allocate a real stack and switch to it, first
@ -16,6 +17,7 @@ extern pde_t *kpgdir;
int
main(void)
{
kinit1(end, P2V(4*1024*1024)); // phys page allocator
kvmalloc(); // kernel page table
mpinit(); // collect info about this machine
lapicinit(mpbcpu());
@ -33,9 +35,9 @@ main(void)
ideinit(); // disk
if(!ismp)
timerinit(); // uniprocessor timer
startothers(); // start other processors (must come before kinit)
kinit(); // initialize memory allocator
userinit(); // first user process (must come after kinit)
startothers(); // start other processors
kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
userinit(); // first user process
// Finish setting up this processor in mpmain.
mpmain();
}
@ -84,12 +86,7 @@ startothers(void)
// Tell entryother.S what stack to use, where to enter, and what
// pgdir to use. We cannot use kpgdir yet, because the AP processor
// is running in low memory, so we use entrypgdir for the APs too.
// kalloc can return addresses above 4Mbyte (the machine may have
// much more physical memory than 4Mbyte), which aren't mapped by
// entrypgdir, so we must allocate a stack using enter_alloc();
// this introduces the constraint that xv6 cannot use kalloc until
// after these last enter_alloc invocations.
stack = enter_alloc();
stack = kalloc();
*(void**)(code-4) = stack + KSTACKSIZE;
*(void**)(code-8) = mpenter;
*(int**)(code-12) = (void *) v2p(entrypgdir);
@ -109,9 +106,9 @@ startothers(void)
__attribute__((__aligned__(PGSIZE)))
pde_t entrypgdir[NPDENTRIES] = {
// Map VA's [0, 4MB) to PA's [0, 4MB)
[0] = (0) + PTE_P + PTE_W + PTE_PS,
[0] = (0) | PTE_P | PTE_W | PTE_PS,
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
[KERNBASE>>PDXSHIFT] = (0) + PTE_P + PTE_W + PTE_PS,
[KERNBASE>>PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS,
};
//PAGEBREAK!

View File

@ -10,13 +10,13 @@
#ifndef __ASSEMBLER__
static inline uint v2p(void *a) { return (uint) a - KERNBASE; }
static inline void *p2v(uint a) { return (void *) a + KERNBASE; }
static inline uint v2p(void *a) { return ((uint) (a)) - KERNBASE; }
static inline void *p2v(uint a) { return (void *) ((a) + KERNBASE); }
#endif
#define V2P(a) ((uint) a - KERNBASE)
#define P2V(a) ((void *) a + KERNBASE)
#define V2P(a) (((uint) (a)) - KERNBASE)
#define P2V(a) (((void *) (a)) + KERNBASE)
#define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts
#define P2V_WO(x) ((x) + KERNBASE) // same as V2P, but without casts

12
runoff
View File

@ -223,11 +223,17 @@ awk '
grep Pages: all.ps
# if we have the nice font, use it
nicefont=../LucidaSans-Typewriter83
if [ -f $nicefont ]
nicefont=LucidaSans-Typewriter83
if [ ! -f ../$nicefont ]
then
if git cat-file blob font:$nicefont > ../$nicefont~; then
mv ../$nicefont~ ../$nicefont
fi
fi
if [ -f ../$nicefont ]
then
echo nicefont
(sed 1q all.ps; cat $nicefont; sed '1d; s/Courier/LucidaSans-Typewriter83/' all.ps) >allf.ps
(sed 1q all.ps; cat ../$nicefont; sed "1d; s/Courier/$nicefont/" all.ps) >allf.ps
else
echo ugly font!
cp all.ps allf.ps

66
vm.c
View File

@ -43,7 +43,7 @@ seginit(void)
// that corresponds to virtual address va. If alloc!=0,
// create any required page table pages.
static pte_t *
walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
walkpgdir(pde_t *pgdir, const void *va, int alloc)
{
pde_t *pde;
pte_t *pgtab;
@ -52,7 +52,7 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
if(*pde & PTE_P){
pgtab = (pte_t*)p2v(PTE_ADDR(*pde));
} else {
if(!alloc || (pgtab = (pte_t*)alloc()) == 0)
if(!alloc || (pgtab = (pte_t*)kalloc()) == 0)
return 0;
// Make sure all those PTE_P bits are zero.
memset(pgtab, 0, PGSIZE);
@ -68,8 +68,7 @@ walkpgdir(pde_t *pgdir, const void *va, char* (*alloc)(void))
// physical addresses starting at pa. va and size might not
// be page-aligned.
static int
mappages(pde_t *pgdir, void *va, uint size, uint pa,
int perm, char* (*alloc)(void))
mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm)
{
char *a, *last;
pte_t *pte;
@ -77,7 +76,7 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa,
a = (char*)PGROUNDDOWN((uint)va);
last = (char*)PGROUNDDOWN(((uint)va) + size - 1);
for(;;){
if((pte = walkpgdir(pgdir, a, alloc)) == 0)
if((pte = walkpgdir(pgdir, a, 1)) == 0)
return -1;
if(*pte & PTE_P)
panic("remap");
@ -90,53 +89,56 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa,
return 0;
}
// The mappings from logical to virtual are one to one (i.e.,
// segmentation doesn't do anything). There is one page table per
// process, plus one that's used when a CPU is not running any process
// (kpgdir). A user process uses the same page table as the kernel; the
// page protection bits prevent it from accessing kernel memory.
// There is one page table per process, plus one that's used when
// a CPU is not running any process (kpgdir). The kernel uses the
// current process's page table during system calls and interrupts;
// page protection bits prevent user code from using the kernel's
// mappings.
//
// setupkvm() and exec() set up every page table like this:
// 0..KERNBASE: user memory (text+data+stack+heap), mapped to some free
// phys memory
//
// 0..KERNBASE: user memory (text+data+stack+heap), mapped to
// phys memory allocated by the kernel
// KERNBASE..KERNBASE+EXTMEM: mapped to 0..EXTMEM (for I/O space)
// KERNBASE+EXTMEM..KERNBASE+end: mapped to EXTMEM..end kernel,
// w. no write permission
// KERNBASE+end..KERBASE+PHYSTOP: mapped to end..PHYSTOP,
// rw data + free memory
// KERNBASE+EXTMEM..data: mapped to EXTMEM..V2P(data)
// for the kernel's instructions and r/o data
// data..KERNBASE+PHYSTOP: mapped to V2P(data)..PHYSTOP,
// rw data + free physical memory
// 0xfe000000..0: mapped direct (devices such as ioapic)
//
// The kernel allocates memory for its heap and for user memory
// between KERNBASE+end and the end of physical memory (PHYSTOP).
// The user program sits in the bottom of the address space, and the
// kernel at the top at KERNBASE.
// The kernel allocates physical memory for its heap and for user memory
// between V2P(end) and the end of physical memory (PHYSTOP)
// (directly addressable from end..P2V(PHYSTOP)).
// This table defines the kernel's mappings, which are present in
// every process's page table.
static struct kmap {
void *virt;
uint phys_start;
uint phys_end;
int perm;
} kmap[] = {
{ P2V(0), 0, 1024*1024, PTE_W}, // I/O space
{ (void*)KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text+rodata
{ data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory
{ (void*)DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices
{ (void*) KERNBASE, 0, EXTMEM, PTE_W}, // I/O space
{ (void*) KERNLINK, V2P(KERNLINK), V2P(data), 0}, // kernel text+rodata
{ (void*) data, V2P(data), PHYSTOP, PTE_W}, // kernel data, memory
{ (void*) DEVSPACE, DEVSPACE, 0, PTE_W}, // more devices
};
// Set up kernel part of a page table.
pde_t*
setupkvm(char* (*alloc)(void))
setupkvm()
{
pde_t *pgdir;
struct kmap *k;
if((pgdir = (pde_t*)alloc()) == 0)
if((pgdir = (pde_t*)kalloc()) == 0)
return 0;
memset(pgdir, 0, PGSIZE);
if (p2v(PHYSTOP) > (void*)DEVSPACE)
panic("PHYSTOP too high");
for(k = kmap; k < &kmap[NELEM(kmap)]; k++)
if(mappages(pgdir, k->virt, k->phys_end - k->phys_start,
(uint)k->phys_start, k->perm, alloc) < 0)
(uint)k->phys_start, k->perm) < 0)
return 0;
return pgdir;
}
@ -146,7 +148,7 @@ setupkvm(char* (*alloc)(void))
void
kvmalloc(void)
{
kpgdir = setupkvm(enter_alloc);
kpgdir = setupkvm();
switchkvm();
}
@ -185,7 +187,7 @@ inituvm(pde_t *pgdir, char *init, uint sz)
panic("inituvm: more than a page");
mem = kalloc();
memset(mem, 0, PGSIZE);
mappages(pgdir, 0, PGSIZE, v2p(mem), PTE_W|PTE_U, kalloc);
mappages(pgdir, 0, PGSIZE, v2p(mem), PTE_W|PTE_U);
memmove(mem, init, sz);
}
@ -235,7 +237,7 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz)
return 0;
}
memset(mem, 0, PGSIZE);
mappages(pgdir, (char*)a, PGSIZE, v2p(mem), PTE_W|PTE_U, kalloc);
mappages(pgdir, (char*)a, PGSIZE, v2p(mem), PTE_W|PTE_U);
}
return newsz;
}
@ -312,7 +314,7 @@ copyuvm(pde_t *pgdir, uint sz)
uint pa, i;
char *mem;
if((d = setupkvm(kalloc)) == 0)
if((d = setupkvm()) == 0)
return 0;
for(i = 0; i < sz; i += PGSIZE){
if((pte = walkpgdir(pgdir, (void *) i, 0)) == 0)
@ -323,7 +325,7 @@ copyuvm(pde_t *pgdir, uint sz)
if((mem = kalloc()) == 0)
goto bad;
memmove(mem, (char*)p2v(pa), PGSIZE);
if(mappages(d, (void*)i, PGSIZE, v2p(mem), PTE_W|PTE_U, kalloc) < 0)
if(mappages(d, (void*)i, PGSIZE, v2p(mem), PTE_W|PTE_U) < 0)
goto bad;
}
return d;