diff --git a/ch6-dev/.lock b/ch6-dev/.lock old mode 100755 new mode 100644 diff --git a/ch6-dev/FiraSans-Medium.woff b/ch6-dev/FiraSans-Medium.woff deleted file mode 100644 index 7d742c5f..00000000 Binary files a/ch6-dev/FiraSans-Medium.woff and /dev/null differ diff --git a/ch6-dev/FiraSans-Regular.woff b/ch6-dev/FiraSans-Regular.woff deleted file mode 100644 index d8e0363f..00000000 Binary files a/ch6-dev/FiraSans-Regular.woff and /dev/null differ diff --git a/ch6-dev/NanumBarunGothic.ttf.woff b/ch6-dev/NanumBarunGothic.ttf.woff deleted file mode 100644 index fb063e8f..00000000 Binary files a/ch6-dev/NanumBarunGothic.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceCodePro-It.ttf.woff b/ch6-dev/SourceCodePro-It.ttf.woff deleted file mode 100644 index 8d68f2fe..00000000 Binary files a/ch6-dev/SourceCodePro-It.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceCodePro-Regular.ttf.woff b/ch6-dev/SourceCodePro-Regular.ttf.woff deleted file mode 100644 index 7be076e1..00000000 Binary files a/ch6-dev/SourceCodePro-Regular.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceCodePro-Semibold.ttf.woff b/ch6-dev/SourceCodePro-Semibold.ttf.woff deleted file mode 100644 index 61bc67b8..00000000 Binary files a/ch6-dev/SourceCodePro-Semibold.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceSerif4-Bold.ttf.woff b/ch6-dev/SourceSerif4-Bold.ttf.woff deleted file mode 100644 index 8ad41888..00000000 Binary files a/ch6-dev/SourceSerif4-Bold.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceSerif4-Bold.ttf.woff2 b/ch6-dev/SourceSerif4-Bold.ttf.woff2 deleted file mode 100644 index db57d214..00000000 Binary files a/ch6-dev/SourceSerif4-Bold.ttf.woff2 and /dev/null differ diff --git a/ch6-dev/SourceSerif4-It.ttf.woff b/ch6-dev/SourceSerif4-It.ttf.woff deleted file mode 100644 index 2a34b5c4..00000000 Binary files a/ch6-dev/SourceSerif4-It.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceSerif4-It.ttf.woff2 b/ch6-dev/SourceSerif4-It.ttf.woff2 deleted file mode 100644 index 1cbc021a..00000000 Binary files a/ch6-dev/SourceSerif4-It.ttf.woff2 and /dev/null differ diff --git a/ch6-dev/SourceSerif4-Regular.ttf.woff b/ch6-dev/SourceSerif4-Regular.ttf.woff deleted file mode 100644 index 45a5521a..00000000 Binary files a/ch6-dev/SourceSerif4-Regular.ttf.woff and /dev/null differ diff --git a/ch6-dev/SourceSerif4-Regular.ttf.woff2 b/ch6-dev/SourceSerif4-Regular.ttf.woff2 deleted file mode 100644 index 2db73fe2..00000000 Binary files a/ch6-dev/SourceSerif4-Regular.ttf.woff2 and /dev/null differ diff --git a/ch6-dev/ayu.css b/ch6-dev/ayu.css deleted file mode 100644 index 50d893e2..00000000 --- a/ch6-dev/ayu.css +++ /dev/null @@ -1 +0,0 @@ - body{background-color:#0f1419;color:#c5c5c5;}h1,h2,h3,h4{color:white;}h1.fqn{border-bottom-color:#5c6773;}h1.fqn a{color:#fff;}h2,h3,h4{border-bottom-color:#5c6773;}h4{border:none;}.in-band{background-color:#0f1419;}.invisible{background:rgba(0,0,0,0);}.docblock code{color:#ffb454;}.code-header{color:#e6e1cf;}.docblock pre>code,pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}.docblock code,.docblock-short code{background-color:#191f26;}pre,.rustdoc.source .example-wrap{color:#e6e1cf;background-color:#191f26;}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:#14191f;}.rust-logo{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);}*{scrollbar-color:#5c6773 #24292f;}.sidebar{scrollbar-color:#5c6773 #24292f;}::-webkit-scrollbar-track{background-color:transparent;}::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar::-webkit-scrollbar-track{background-color:transparent;}.sidebar::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar .current,.sidebar a:hover{background-color:transparent;color:#ffb44c;}.source .sidebar{background-color:#14191f;}.sidebar-elems .location{color:#ff7733;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5,.docblock h6{border-bottom-color:#5c6773;}.docblock table td,.docblock table th{border-color:#5c6773;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#c5c5c5;}.search-results a:hover{background-color:#777;}.search-results a:focus{color:#000 !important;background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.content .item-info::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ffa0a5;}.content span.union,.content a.union{color:#ffa0a5;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#39AFD7;}.content span.primitive,.content a.primitive{color:#ffa0a5;}.content span.traitalias,.content a.traitalias{color:#39AFD7;}.content span.keyword,.content a.keyword{color:#39AFD7;}.content span.externcrate,.content span.mod,.content a.mod{color:#39AFD7;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#ffa0a5;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#39AFD7;}.content span.type,.content a.type,.block a.current.type{color:#39AFD7;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#39AFD7;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}.sidebar a{color:#53b1db;}.sidebar a.current.type{color:#53b1db;}.sidebar a.current.associatedtype{color:#53b1db;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#39AFD7;}a#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,.in-band a{color:#c5c5c5;}.sidebar h2 a,.sidebar h3 a{color:white;}.search-results a{color:#0096cf;}body.source .example-wrap pre.rust a{background:#333;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before,details.undocumented>summary::before{color:#999;}details.rustdoc-toggle>summary::before,details.undocumented>summary::before{filter:invert(100%);}#crate-search,.search-input{background-color:#141920;border-color:#424c57;color:#c5c5c5;}.search-input{color:#ffffff;}.module-item .stab,.import-item .stab{color:#000;}.stab.unstable,.stab.deprecated,.stab.portability{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background:none;}#help>div{background:#14191f;box-shadow:0px 6px 20px 0px black;border:none;border-radius:4px;}#help span.bottom,#help span.top{border-color:#5c6773;}.rightside,.out-of-band{color:grey;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label,.code-attribute{color:#999;}:target{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip::after{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip::before{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}.notable-traits-tooltiptext .notable{border-bottom-color:#5c6773;}#titles>button.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>button:not(.selected){background-color:transparent !important;border:none;}#titles>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>button>div.count{color:#888;}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>button:hover,#titles>button.selected{}.content span.typedef,.content a.typedef,.block a.current.typedef{}.content span.union,.content a.union,.block a.current.union{}pre.rust .lifetime{}.stab.unstable{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content a.attr,.content a.derive,.content a.macro{}.stab.portability{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}.search-results a:focus span{}a.result-trait:focus{}a.result-traitalias:focus{}a.result-mod:focus,a.result-externcrate:focus{}a.result-mod:focus{}a.result-externcrate:focus{}a.result-enum:focus{}a.result-struct:focus{}a.result-union:focus{}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{}a.result-type:focus{}a.result-associatedtype:focus{}a.result-foreigntype:focus{}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{}a.result-constant:focus,a.result-static:focus{}a.result-primitive:focus{}a.result-keyword:focus{}.sidebar a.current.enum{}.sidebar a.current.struct{}.sidebar a.current.foreigntype{}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{}.sidebar a.current.union{}.sidebar a.current.constant .sidebar a.current.static{}.sidebar a.current.primitive{}.sidebar a.current.externcrate .sidebar a.current.mod{}.sidebar a.current.trait{}.sidebar a.current.traitalias{}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{}.sidebar a.current.keyword{}@media (max-width:700px){.sidebar-menu{background-color:#14191f;border-bottom-color:#5c6773;border-right-color:#5c6773;}.sidebar-elems{background-color:#14191f;border-right-color:#5c6773;}#sidebar-filler{background-color:#14191f;border-bottom-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow:inset 0 -1px 0 #5c6773;}#theme-picker,#settings-menu,#help-button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#theme-picker>img,#settings-menu>img{filter:invert(100);}#copy-path{color:#fff;}#copy-path>img{filter:invert(70%);}#copy-path:hover>img{filter:invert(100%);}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,#help-button:hover,#help-button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}@media (max-width:700px){#theme-picker{background:#0f1419;}}.search-results .result-name span.alias{color:#c5c5c5;}.search-results .result-name span.grey{color:#999;}#sidebar-toggle{background-color:#14191f;}#sidebar-toggle:hover{background-color:rgba(70,70,70,0.33);}#source-sidebar{background-color:#14191f;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}div.files>a:hover,div.name:hover{background-color:#14191f;color:#ffb44c;}div.files>.selected{background-color:#14191f;color:#ffb44c;}.setting-line>.title{border-bottom-color:#5c6773;}input:checked+.slider{background-color:#ffb454 !important;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(15,20,25,1),rgba(15,20,25,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(15,20,25,1),rgba(15,20,25,0));}.toggle-line-inner{background:#616161;}.toggle-line:hover .toggle-line-inner{background:#898989;} \ No newline at end of file diff --git a/ch6-dev/brush.svg b/ch6-dev/brush.svg deleted file mode 100644 index ea266e85..00000000 --- a/ch6-dev/brush.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ch6-dev/dark.css b/ch6-dev/dark.css deleted file mode 100644 index a31f453f..00000000 --- a/ch6-dev/dark.css +++ /dev/null @@ -1 +0,0 @@ -body{background-color:#353535;color:#ddd;}h1,h2,h3,h4{color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3,h4{border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre,.rustdoc.source .example-wrap{background-color:#2A2A2A;}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:#505050;}.rust-logo{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff)}*{scrollbar-color:rgb(64,65,67) #717171;}.sidebar{scrollbar-color:rgba(32,34,37,.6) #5a5a5a;}::-webkit-scrollbar-track{background-color:#717171;}::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar::-webkit-scrollbar-track{background-color:#717171;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar .current,.sidebar a:hover{background:#444;}.source .sidebar{background-color:#565656;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5,.docblock h6{border-bottom-color:#DDD;}.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.search-results a:hover{background-color:#777;}.search-results a:focus{color:#eee !important;background-color:#616161;}.search-results a:focus span{color:#eee !important;}a.result-trait:focus{background-color:#013191;}a.result-traitalias:focus{background-color:#013191;}a.result-mod:focus,a.result-externcrate:focus{background-color:#884719;}a.result-enum:focus{background-color:#194e9f;}a.result-struct:focus{background-color:#194e9f;}a.result-union:focus{background-color:#194e9f;}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{background-color:#4950ed;}a.result-type:focus{background-color:#194e9f;}a.result-associatedtype:focus{background-color:#884719;}a.result-foreigntype:focus{background-color:#194e9f;}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{background-color:#217d1c;}a.result-constant:focus,a.result-static:focus{background-color:#884719;}a.result-primitive:focus{background-color:#194e9f;}a.result-keyword:focus{background-color:#884719;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#2dbfb8;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#2dbfb8;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#D2991D;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#2dbfb8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#2dbfb8;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#D2991D;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2dbfb8;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#D2991D;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b78cf2;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#D2991D;}.sidebar a{color:#fdbf35;}.sidebar a.current.enum{color:#12ece2;}.sidebar a.current.struct{color:#12ece2;}.sidebar a.current.type{color:#12ece2;}.sidebar a.current.associatedtype{color:#fdbf35;}.sidebar a.current.foreigntype{color:#12ece2;}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{color:#0be900;}.sidebar a.current.union{color:#12ece2;}.sidebar a.current.constant .sidebar a.current.static{color:#fdbf35;}.sidebar a.current.primitive{color:#12ece2;}.sidebar a.current.externcrate .sidebar a.current.mod{color:#fdbf35;}.sidebar a.current.trait{color:#cca7ff;}.sidebar a.current.traitalias{color:#cca7ff;}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{color:#32d479;}.sidebar a.current.keyword{color:#fdbf35;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#D2991D;}a#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,.in-band a{color:#ddd;}.search-results a{color:#ddd;}a.test-arrow{color:#dedede;}body.source .example-wrap pre.rust a{background:#333;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before,details.undocumented>summary::before{color:#999;}details.rustdoc-toggle>summary::before,details.undocumented>summary::before{filter:invert(100%);}#crate-search,.search-input{color:#111;background-color:#f0f0f0;border-color:#000;}.search-input{border-color:#e0e0e0;}.search-input:focus{border-color:#008dfd;}.module-item .stab,.import-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#ffc4c4;border-color:#db7b7b;color:#2f2f2f;}.stab.portability{background:#F3DFFF;border-color:#b07bdb;color:#2f2f2f;}.stab.portability>code{background:none;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help span.bottom,#help span.top{border-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);}.rightside,.out-of-band{color:grey;}.result-name .primitive>i,.result-name .keyword>i{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label,.code-attribute{color:#999;}:target{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;border-color:#000;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}.notable-traits-tooltiptext .notable{border-bottom-color:#d2d2d2;}#titles>button:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>button:hover,#titles>button.selected{border-top-color:#0089ff;background-color:#353535;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow:inset 0 -1px 0 #c6cbd1;}#theme-picker,#settings-menu,#help-button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,#help-button:hover,#help-button:focus{border-color:#ffb900;}#copy-path{color:#999;}#copy-path>img{filter:invert(50%);}#copy-path:hover>img{filter:invert(65%);}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}.search-results .result-name span.alias{color:#fff;}.search-results .result-name span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(53,53,53,1),rgba(53,53,53,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(53,53,53,1),rgba(53,53,53,0));}.toggle-line-inner{background:#616161;}.toggle-line:hover .toggle-line-inner{background:#898989;} \ No newline at end of file diff --git a/ch6-dev/down-arrow.svg b/ch6-dev/down-arrow.svg deleted file mode 100644 index 35437e77..00000000 --- a/ch6-dev/down-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ch6-dev/help.html b/ch6-dev/help.html new file mode 100644 index 00000000..26794106 --- /dev/null +++ b/ch6-dev/help.html @@ -0,0 +1 @@ +
fn:
) to \
- restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
- enum
, trait
, type
, macro
, \
- and const
.","Search functions by type signature (e.g., vec -> usize
or \
- * -> vec
)","Search multiple things at once by splitting your query with comma (e.g., \
- str,u8
or String,struct:Vec,test
)","You can look for items with an exact name by putting double quotes around \
- your request: \"string\"
","Look for items inside another one by searching for a path: vec::Vec
",].map(function(x){return""+x+"
"}).join("");var div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="pub const CLOCK_FREQ: usize = 12500000;
pub const MEMORY_END: usize = 0x88000000;
RISCV64 configuration
-Encode the exit code using EXIT_FAILURE_FLAG.
-pub struct RISCV64 {
- addr: u64,
-}
RISCV64 configuration
-addr: u64
Address of the sifive_test mapped device.
-Mutably borrows from an owned value. Read more
-pub trait QEMUExit {
- fn exit(&self, code: u32) -> !;
- fn exit_success(&self) -> !;
- fn exit_failure(&self) -> !;
-}
Exit with specified return code.
-Note: For X86
, code is binary-OR’ed with 0x1
inside QEMU.
Exit QEMU using EXIT_SUCCESS
, aka 0
, if possible.
Note: Not possible for X86
.
Exit QEMU using EXIT_FAILURE
, aka 1
.
pub type BlockDeviceImpl = VirtIOBlock;
pub type BlockDeviceImpl = VirtIOBlock;
struct BlockDeviceImpl(UPSafeCell<VirtIOBlk<'static, VirtioHal>>);
0: UPSafeCell<VirtIOBlk<'static, VirtioHal>>
pub const KERNEL_HEAP_SIZE: usize = 0x20_0000;
pub const KERNEL_STACK_SIZE: usize = _; // 8_192usize
pub const PAGE_SIZE_BITS: usize = 0xc;
pub const TRAMPOLINE: usize = _; // 18_446_744_073_709_547_520usize
pub const TRAP_CONTEXT: usize = _; // 18_446_744_073_709_543_424usize
pub const USER_STACK_SIZE: usize = _; // 8_192usize
Constants used in rCore
-Constants used in rCore
+pub use crate::board::CLOCK_FREQ;
pub use crate::board::MEMORY_END;
pub use crate::board::MMIO;
struct Stdout;
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
struct Stdout;
From<T> for U
chooses to do.
+pub fn block_device_test()
pub use sdcard::SDCardWrapper;
pub use virtio_blk::VirtIOBlock;
pub use virtio_blk::VirtIOBlock;
#[repr(u8)]
-pub enum CMD {
-Show 15 variants
CMD0,
- CMD8,
- CMD9,
- CMD10,
- CMD12,
- CMD16,
- CMD17,
- CMD18,
- ACMD23,
- CMD24,
- CMD25,
- ACMD41,
- CMD55,
- CMD58,
- CMD59,
-}
SD commands
-CMD0
Software reset
-CMD8
Check voltage range (SDC V2)
-CMD9
Read CSD register
-CMD10
Read CID register
-CMD12
Stop to read data
-CMD16
Change R/W block size
-CMD17
Read block
-CMD18
Read multiple blocks
-ACMD23
Number of blocks to erase (SDC)
-CMD24
Write a block
-CMD25
Write multiple blocks
-ACMD41
Initiate initialization process (SDC)
-CMD55
Leading command for ACMD*
-CMD58
Read OCR
-CMD59
Enable/disable CRC check
-Mutably borrows from an owned value. Read more
-The resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-pub enum InitError {
- CMDFailed(CMD, u8),
- CardCapacityStatusNotSet([u8; 4]),
- CannotGetCardInfo,
-}
CMDFailed(CMD, u8)
CardCapacityStatusNotSet([u8; 4])
CannotGetCardInfo
Mutably borrows from an owned value. Read more
-The resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-Card Identification Data: CID Register
-Card Specific Data: CSD Register
-Card information
-CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapping to anything -in the FPIOA
-GPIOHS GPIO number to use for controlling the SD card CS pin
-Data token start byte, Start Multiple Block Read
-Data token start byte, Start Multiple Block Write
-Data token start byte, Start Single Block Read
-Data token start byte, Start Single Block Write
-Connect pins to internal functions
-struct PERIPHERALS {
- __private_field: (),
-}
__private_field: ()
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-The resulting type after dereferencing.
-Dereferences the value.
-Mutably borrows from an owned value. Read more
-spi: SPI
spi_cs: u32
cs_gpionum: u8
Mutably borrows from an owned value. Read more
-pub struct SDCardCID {
- pub ManufacturerID: u8,
- pub OEM_AppliID: u16,
- pub ProdName1: u32,
- pub ProdName2: u8,
- pub ProdRev: u8,
- pub ProdSN: u32,
- pub Reserved1: u8,
- pub ManufactDate: u16,
- pub CID_CRC: u8,
- pub Reserved2: u8,
-}
Card Identification Data: CID Register
-ManufacturerID: u8
OEM_AppliID: u16
ProdName1: u32
ProdName2: u8
ProdRev: u8
ProdSN: u32
Reserved1: u8
ManufactDate: u16
CID_CRC: u8
Reserved2: u8
Mutably borrows from an owned value. Read more
-The resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-pub struct SDCardCSD {Show 32 fields
- pub CSDStruct: u8,
- pub SysSpecVersion: u8,
- pub Reserved1: u8,
- pub TAAC: u8,
- pub NSAC: u8,
- pub MaxBusClkFrec: u8,
- pub CardComdClasses: u16,
- pub RdBlockLen: u8,
- pub PartBlockRead: u8,
- pub WrBlockMisalign: u8,
- pub RdBlockMisalign: u8,
- pub DSRImpl: u8,
- pub Reserved2: u8,
- pub DeviceSize: u32,
- pub EraseGrSize: u8,
- pub EraseGrMul: u8,
- pub WrProtectGrSize: u8,
- pub WrProtectGrEnable: u8,
- pub ManDeflECC: u8,
- pub WrSpeedFact: u8,
- pub MaxWrBlockLen: u8,
- pub WriteBlockPaPartial: u8,
- pub Reserved3: u8,
- pub ContentProtectAppli: u8,
- pub FileFormatGroup: u8,
- pub CopyFlag: u8,
- pub PermWrProtect: u8,
- pub TempWrProtect: u8,
- pub FileFormat: u8,
- pub ECC: u8,
- pub CSD_CRC: u8,
- pub Reserved4: u8,
-}
Card Specific Data: CSD Register
-CSDStruct: u8
SysSpecVersion: u8
Reserved1: u8
TAAC: u8
NSAC: u8
MaxBusClkFrec: u8
CardComdClasses: u16
RdBlockLen: u8
PartBlockRead: u8
WrBlockMisalign: u8
RdBlockMisalign: u8
DSRImpl: u8
Reserved2: u8
DeviceSize: u32
EraseGrSize: u8
EraseGrMul: u8
WrProtectGrSize: u8
WrProtectGrEnable: u8
ManDeflECC: u8
WrSpeedFact: u8
MaxWrBlockLen: u8
WriteBlockPaPartial: u8
Reserved3: u8
ContentProtectAppli: u8
FileFormatGroup: u8
CopyFlag: u8
PermWrProtect: u8
TempWrProtect: u8
FileFormat: u8
ECC: u8
CSD_CRC: u8
Reserved4: u8
Mutably borrows from an owned value. Read more
-The resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-pub struct SDCardInfo {
- pub SD_csd: SDCardCSD,
- pub SD_cid: SDCardCID,
- pub CardCapacity: u64,
- pub CardBlockSize: u64,
-}
Card information
-SD_csd: SDCardCSD
SD_cid: SDCardCID
CardCapacity: u64
CardBlockSize: u64
Returns a copy of the value. Read more
-Performs copy-assignment from source
. Read more
Mutably borrows from an owned value. Read more
-The resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-pub struct SDCardWrapper(UPSafeCell<SDCard<SPIImpl<SPI0>>>);
0: UPSafeCell<SDCard<SPIImpl<SPI0>>>
Mutably borrows from an owned value. Read more
-pub struct BLOCK_DEVICE {
+BLOCK_DEVICE in os::drivers::block - Rust Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for BLOCK_DEVICE
sourceimpl LazyStatic for BLOCK_DEVICE
Auto Trait Implementations
impl RefUnwindSafe for BLOCK_DEVICE
impl Send for BLOCK_DEVICE
impl Sync for BLOCK_DEVICE
impl Unpin for BLOCK_DEVICE
impl UnwindSafe for BLOCK_DEVICE
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for BLOCK_DEVICE
source§impl LazyStatic for BLOCK_DEVICE
Auto Trait Implementations§
§impl RefUnwindSafe for BLOCK_DEVICE
§impl Send for BLOCK_DEVICE
§impl Sync for BLOCK_DEVICE
§impl Unpin for BLOCK_DEVICE
§impl UnwindSafe for BLOCK_DEVICE
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
struct QUEUE_FRAMES {
+QUEUE_FRAMES in os::drivers::block::virtio_blk - Rust Struct os::drivers::block::virtio_blk::QUEUE_FRAMES
source · struct QUEUE_FRAMES {
__private_field: (),
-}
Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<Vec<FrameTracker>>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for QUEUE_FRAMES
type Target = UPSafeCell<Vec<FrameTracker>>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<Vec<FrameTracker>>
Dereferences the value.
-sourceimpl LazyStatic for QUEUE_FRAMES
Auto Trait Implementations
impl RefUnwindSafe for QUEUE_FRAMES
impl Send for QUEUE_FRAMES
impl Sync for QUEUE_FRAMES
impl Unpin for QUEUE_FRAMES
impl UnwindSafe for QUEUE_FRAMES
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<Vec<FrameTracker>>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for QUEUE_FRAMES
§type Target = UPSafeCell<Vec<FrameTracker, Global>>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<Vec<FrameTracker>>
Dereferences the value.source§impl LazyStatic for QUEUE_FRAMES
Auto Trait Implementations§
§impl RefUnwindSafe for QUEUE_FRAMES
§impl Send for QUEUE_FRAMES
§impl Sync for QUEUE_FRAMES
§impl Unpin for QUEUE_FRAMES
§impl UnwindSafe for QUEUE_FRAMES
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct VirtIOBlock(UPSafeCell<VirtIOBlk<'static>>);
0: UPSafeCell<VirtIOBlk<'static>>
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct VirtIOBlock(UPSafeCell<VirtIOBlk<'static, VirtioHal>>);
0: UPSafeCell<VirtIOBlk<'static, VirtioHal>>
From<T> for U
chooses to do.
+pub struct VirtioHal;
pub use block::BLOCK_DEVICE;
pub use block::BLOCK_DEVICE;
pub use block::BLOCK_DEVICE;
pub use block::BLOCK_DEVICE;
File system in os
-Arc<Inode>
-> OSInodeInner
: In order to open files concurrently
+
File system in os
+Arc<Inode>
-> OSInodeInner
: In order to open files concurrently
we need to wrap Inode
into Arc
,but Mutex
in Inode
prevents
-file systems from being accessed simultaneously
-Stdin & Stdout
-A wrapper around a filesystem inode -to implement File trait atop
-Open file flags
-Standard input
-Standard output
-File trait
-Arc<Inode>
-> OSInodeInner
: In order to open files concurrently
+
Arc<Inode>
-> OSInodeInner
: In order to open files concurrently
we need to wrap Inode
into Arc
,but Mutex
in Inode
prevents
file systems from being accessed simultaneously
UPSafeCell<OSInodeInner>
-> OSInode
: for static ROOT_INODE
,we
need to wrap OSInodeInner
into UPSafeCell
A wrapper around a filesystem inode -to implement File trait atop
-The OS inode inner in ‘UPSafeCell’
-Open file flags
-pub struct OSInode {
+OSInode in os::fs::inode - Rust pub struct OSInode {
readable: bool,
writable: bool,
inner: UPSafeCell<OSInodeInner>,
-}
Expand description
A wrapper around a filesystem inode
+}Expand description
A wrapper around a filesystem inode
to implement File trait atop
-
Fields
readable: bool
writable: bool
inner: UPSafeCell<OSInodeInner>
Implementations
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for OSInode
impl Send for OSInode
impl Sync for OSInode
impl Unpin for OSInode
impl !UnwindSafe for OSInode
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
Fields§
§readable: bool
§writable: bool
§inner: UPSafeCell<OSInodeInner>
Implementations§
source§impl OSInode
sourcepub fn new(
+ readable: bool,
+ writable: bool,
+ inode: Arc<Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>>
+) -> Self
Construct an OS inode from a inode
+Trait Implementations§
Auto Trait Implementations§
§impl !RefUnwindSafe for OSInode
§impl Send for OSInode
§impl Sync for OSInode
§impl Unpin for OSInode
§impl !UnwindSafe for OSInode
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct OSInodeInner {
+OSInodeInner in os::fs::inode - Rust Struct os::fs::inode::OSInodeInner
source · pub struct OSInodeInner {
offset: usize,
- inode: Arc<Inode>,
-}
Expand description
The OS inode inner in ‘UPSafeCell’
-Fields
offset: usize
inode: Arc<Inode>
Auto Trait Implementations
impl !RefUnwindSafe for OSInodeInner
impl Send for OSInodeInner
impl Sync for OSInodeInner
impl Unpin for OSInodeInner
impl !UnwindSafe for OSInodeInner
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+ inode: Arc<Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>>,
+}Expand description
The OS inode inner in ‘UPSafeCell’
+Fields§
§offset: usize
§inode: Arc<Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>>
Auto Trait Implementations§
§impl !RefUnwindSafe for OSInodeInner
§impl Send for OSInodeInner
§impl Sync for OSInodeInner
§impl Unpin for OSInodeInner
§impl !UnwindSafe for OSInodeInner
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct OpenFlags {
+OpenFlags in os::fs::inode - Rust Expand description
Open file flags
-Fields
bits: u32
Implementations
sourceimpl OpenFlags
sourcepub const fn from_bits(bits: u32) -> Option<Self>
Convert from underlying bit representation, unless that
+}Expand description
Open file flags
+
Fields§
§bits: u32
Implementations§
source§impl OpenFlags
sourcepub const fn from_bits(bits: u32) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u32) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u32) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u32) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u32) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -27,35 +21,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -63,69 +57,42 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl BitAndAssign<OpenFlags> for OpenFlags
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOrAssign<OpenFlags> for OpenFlags
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXorAssign<OpenFlags> for OpenFlags
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Extend<OpenFlags> for OpenFlags
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<OpenFlags> for OpenFlags
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Ord for OpenFlags
sourceimpl PartialOrd<OpenFlags> for OpenFlags
sourcefn partial_cmp(&self, other: &OpenFlags) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl SubAssign<OpenFlags> for OpenFlags
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl Copy for OpenFlags
sourceimpl Eq for OpenFlags
sourceimpl StructuralEq for OpenFlags
sourceimpl StructuralPartialEq for OpenFlags
Auto Trait Implementations
impl RefUnwindSafe for OpenFlags
impl Send for OpenFlags
impl Sync for OpenFlags
impl Unpin for OpenFlags
impl UnwindSafe for OpenFlags
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl BitAndAssign<OpenFlags> for OpenFlags
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOrAssign<OpenFlags> for OpenFlags
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXorAssign<OpenFlags> for OpenFlags
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Extend<OpenFlags> for OpenFlags
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<OpenFlags> for OpenFlags
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Ord for OpenFlags
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<OpenFlags> for OpenFlags
source§impl PartialOrd<OpenFlags> for OpenFlags
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl SubAssign<OpenFlags> for OpenFlags
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl Copy for OpenFlags
source§impl Eq for OpenFlags
source§impl StructuralEq for OpenFlags
source§impl StructuralPartialEq for OpenFlags
Auto Trait Implementations§
§impl RefUnwindSafe for OpenFlags
§impl Send for OpenFlags
§impl Sync for OpenFlags
§impl Unpin for OpenFlags
§impl UnwindSafe for OpenFlags
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct ROOT_INODE {
+ROOT_INODE in os::fs::inode - Rust Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for ROOT_INODE
sourceimpl LazyStatic for ROOT_INODE
Auto Trait Implementations
impl RefUnwindSafe for ROOT_INODE
impl Send for ROOT_INODE
impl Sync for ROOT_INODE
impl Unpin for ROOT_INODE
impl UnwindSafe for ROOT_INODE
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for ROOT_INODE
§type Target = Arc<Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>, Global>
The resulting type after dereferencing.source§fn deref(
+ &self
+) -> &Arc<Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>>
Dereferences the value.source§impl LazyStatic for ROOT_INODE
Auto Trait Implementations§
§impl RefUnwindSafe for ROOT_INODE
§impl Send for ROOT_INODE
§impl Sync for ROOT_INODE
§impl Unpin for ROOT_INODE
§impl UnwindSafe for ROOT_INODE
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
type InodeType = Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>;
struct InodeType {
+ block_id: usize,
+ block_offset: usize,
+ fs: Arc<Mutex<RawExclusiveLock, EasyFileSystem<64, RawExclusiveLock, RawExclusiveLock>>, Global>,
+}
block_id: usize
§block_offset: usize
§fs: Arc<Mutex<RawExclusiveLock, EasyFileSystem<64, RawExclusiveLock, RawExclusiveLock>>, Global>
pub struct Stdin;
Standard input
-Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct Stdin;
Standard input
+From<T> for U
chooses to do.
+pub struct Stdout;
Standard output
-Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct Stdout;
Standard output
+From<T> for U
chooses to do.
+pub struct OSInode {
+OSInode in os::fs - Rust pub struct OSInode {
readable: bool,
writable: bool,
inner: UPSafeCell<OSInodeInner>,
-}
Expand description
A wrapper around a filesystem inode
+}Expand description
A wrapper around a filesystem inode
to implement File trait atop
-
Fields
readable: bool
writable: bool
inner: UPSafeCell<OSInodeInner>
Implementations
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for OSInode
impl Send for OSInode
impl Sync for OSInode
impl Unpin for OSInode
impl !UnwindSafe for OSInode
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
Fields§
§readable: bool
§writable: bool
§inner: UPSafeCell<OSInodeInner>
Implementations§
source§impl OSInode
sourcepub fn new(
+ readable: bool,
+ writable: bool,
+ inode: Arc<Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>>
+) -> Self
Construct an OS inode from a inode
+Trait Implementations§
Auto Trait Implementations§
§impl !RefUnwindSafe for OSInode
§impl Send for OSInode
§impl Sync for OSInode
§impl Unpin for OSInode
§impl !UnwindSafe for OSInode
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct OpenFlags {
+OpenFlags in os::fs - Rust Expand description
Open file flags
-Fields
bits: u32
Implementations
sourceimpl OpenFlags
sourcepub const fn from_bits(bits: u32) -> Option<Self>
Convert from underlying bit representation, unless that
+}Expand description
Open file flags
+
Fields§
§bits: u32
Implementations§
source§impl OpenFlags
sourcepub const fn from_bits(bits: u32) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u32) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u32) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u32) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u32) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -27,35 +21,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -63,69 +57,42 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl BitAndAssign<OpenFlags> for OpenFlags
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOrAssign<OpenFlags> for OpenFlags
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXorAssign<OpenFlags> for OpenFlags
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Extend<OpenFlags> for OpenFlags
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<OpenFlags> for OpenFlags
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Ord for OpenFlags
sourceimpl PartialOrd<OpenFlags> for OpenFlags
sourcefn partial_cmp(&self, other: &OpenFlags) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl SubAssign<OpenFlags> for OpenFlags
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl Copy for OpenFlags
sourceimpl Eq for OpenFlags
sourceimpl StructuralEq for OpenFlags
sourceimpl StructuralPartialEq for OpenFlags
Auto Trait Implementations
impl RefUnwindSafe for OpenFlags
impl Send for OpenFlags
impl Sync for OpenFlags
impl Unpin for OpenFlags
impl UnwindSafe for OpenFlags
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl BitAndAssign<OpenFlags> for OpenFlags
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOrAssign<OpenFlags> for OpenFlags
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXorAssign<OpenFlags> for OpenFlags
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Extend<OpenFlags> for OpenFlags
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<OpenFlags> for OpenFlags
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Ord for OpenFlags
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<OpenFlags> for OpenFlags
source§impl PartialOrd<OpenFlags> for OpenFlags
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl SubAssign<OpenFlags> for OpenFlags
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl Copy for OpenFlags
source§impl Eq for OpenFlags
source§impl StructuralEq for OpenFlags
source§impl StructuralPartialEq for OpenFlags
Auto Trait Implementations§
§impl RefUnwindSafe for OpenFlags
§impl Send for OpenFlags
§impl Sync for OpenFlags
§impl Unpin for OpenFlags
§impl UnwindSafe for OpenFlags
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct Stdin;
Standard input
-Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct Stdin;
Standard input
+From<T> for U
chooses to do.
+pub struct Stdout;
Standard output
-Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct Stdout;
Standard output
+From<T> for U
chooses to do.
+pub trait File: Send + Sync {
- fn readable(&self) -> bool;
- fn writable(&self) -> bool;
- fn read(&self, buf: UserBuffer) -> usize;
- fn write(&self, buf: UserBuffer) -> usize;
-}
File trait
-Read file to UserBuffer
Write UserBuffer
to file
pub trait File: Send + Sync {
+ // Required methods
+ fn readable(&self) -> bool;
+ fn writable(&self) -> bool;
+ fn read(&self, buf: UserBuffer) -> usize;
+ fn write(&self, buf: UserBuffer) -> usize;
+}
File trait
+Read file to UserBuffer
Write UserBuffer
to file
The main module and entrypoint
+The main module and entrypoint
Various facilities of the kernels are implemented as submodules. The most important ones are:
trap
: Handles all cases of switching from userspace to the kerneltask
: Task managementsyscall
: System call handling and implementationmm
: Address map using SV39sync
: Wrap a static data structure inside it so that we are able to access it without any unsafe
.fs
: Separate user from file system with some structurestrap
: Handles all cases of switching from userspace to the kerneltask
: Task managementsyscall
: System call handling and implementationmm
: Address map using SV39sync
: Wrap a static data structure inside it so that we are able to access it without any unsafe
.fs
: Separate user from file system with some structuresThe operating system also starts in this module. Kernel code starts
-executing from entry.asm
, after which rust_main()
is called to
+executing from entry.asm
, after which rust_main()
is called to
initialize various pieces of functionality. (See its source code for
details.)
We then call task::run_tasks()
and for the first time go to
+
We then call task::run_tasks()
and for the first time go to
userspace.
Constants used in rCore
-SBI console driver, for text output
-File system in os
-The panic handler
-Memory management implementation
-SBI call wrappers
-Synchronization and interior mutability primitives
-Implementation of syscalls
-Task management implementation
-RISC-V timer-related functionality
-Trap handling functionality
-The panic handler
+Implementation of physical and virtual address and page number.
-Definitions
-phiscal page number
-a simple range structure for type T
-iterator for the simple range structure
-virtual address
-virtual page number
-Add value by one
-a simple range structure for virtual page number
-Implementation of physical and virtual address and page number.
+#[repr(C)]pub struct PhysAddr(pub usize);
Definitions
-0: usize
PhysAddr
->PhysPageNum
PhysAddr
->PhysPageNum
Get page offset
-Converts to this type from the input type.
-T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum} +
#[repr(C)]pub struct PhysAddr(pub usize);
Definitions
+0: usize
PhysAddr
->PhysPageNum
PhysAddr
->PhysPageNum
Get page offset
+Get reference to PhysAddr
value
Get mutable reference to PhysAddr
value
T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum} T -> usize: T.0 usize -> T: usize.into()
-This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+#[repr(C)]pub struct PhysPageNum(pub usize);
phiscal page number
-0: usize
Get PageTableEntry
on PhysPageNum
Get u8 array on PhysPageNum
Get Get mutable reference to PhysAddr
value on PhysPageNum
Returns a copy of the value. Read more
-Performs copy-assignment from source
. Read more
Converts to this type from the input type.
-Converts to this type from the input type.
-This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
This method tests for !=
.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
#[repr(C)]pub struct PhysPageNum(pub usize);
phiscal page number
+0: usize
Get PageTableEntry
on PhysPageNum
Get u8 array on PhysPageNum
Get Get mutable reference to PhysAddr
value on PhysPageNum
source
. Read moreself
and other
values to be equal, and is used
+by ==
.self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+pub struct SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
+SimpleRange in os::mm::address - Rust Struct os::mm::address::SimpleRange
source · pub struct SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,{
l: T,
r: T,
-}
Expand description
a simple range structure for type T
-Fields
l: T
r: T
Implementations
Trait Implementations
sourceimpl<T: Clone> Clone for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
sourcefn clone(&self) -> SimpleRange<T>
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl<T> IntoIterator for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
sourceimpl<T: Copy> Copy for SimpleRange<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
Auto Trait Implementations
impl<T> RefUnwindSafe for SimpleRange<T> where
T: RefUnwindSafe,
impl<T> Send for SimpleRange<T> where
T: Send,
impl<T> Sync for SimpleRange<T> where
T: Sync,
impl<T> Unpin for SimpleRange<T> where
T: Unpin,
impl<T> UnwindSafe for SimpleRange<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
a simple range structure for type T
+Fields§
§l: T
§r: T
Implementations§
Trait Implementations§
source§impl<T> Clone for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug + Clone,
source§fn clone(&self) -> SimpleRange<T>
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl<T> IntoIterator for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
source§impl<T> Copy for SimpleRange<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug + Copy,
Auto Trait Implementations§
§impl<T> RefUnwindSafe for SimpleRange<T>where
+ T: RefUnwindSafe,
§impl<T> Send for SimpleRange<T>where
+ T: Send,
§impl<T> Sync for SimpleRange<T>where
+ T: Sync,
§impl<T> Unpin for SimpleRange<T>where
+ T: Unpin,
§impl<T> UnwindSafe for SimpleRange<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug, {
+SimpleRangeIterator in os::mm::address - Rust Struct os::mm::address::SimpleRangeIterator
source · pub struct SimpleRangeIterator<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,{
current: T,
end: T,
-}
Expand description
iterator for the simple range structure
-Fields
current: T
end: T
Implementations
sourceimpl<T> SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
Trait Implementations
sourceimpl<T> Iterator for SimpleRangeIterator<T> where
T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
type Item = T
The type of the elements being iterated over.
-sourcefn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read more
-1.0.0 · sourcefn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more
-1.0.0 · sourcefn count(self) -> usize
Consumes the iterator, counting the number of iterations and returning it. Read more
-1.0.0 · sourcefn last(self) -> Option<Self::Item>
Consumes the iterator, returning the last element. Read more
-sourcefn advance_by(&mut self, n: usize) -> Result<(), usize>
🔬 This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more
-1.0.0 · sourcefn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more
-1.28.0 · sourcefn step_by(self, step: usize) -> StepBy<Self>
Creates an iterator starting at the same point, but stepping by
-the given amount at each iteration. Read more
-1.0.0 · sourcefn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more
-1.0.0 · sourcefn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read more
-sourcefn intersperse(self, separator: Self::Item) -> Intersperse<Self> where
Self::Item: Clone,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places a copy of separator
between adjacent
-items of the original iterator. Read more
-sourcefn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where
G: FnMut() -> Self::Item,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
-between adjacent items of the original iterator. Read more
-1.0.0 · sourcefn map<B, F>(self, f: F) -> Map<Self, F> where
F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
-element. Read more
-1.21.0 · sourcefn for_each<F>(self, f: F) where
F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more
-1.0.0 · sourcefn filter<P>(self, predicate: P) -> Filter<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
-should be yielded. Read more
-1.0.0 · sourcefn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more
-1.0.0 · sourcefn enumerate(self) -> Enumerate<Self>
Creates an iterator which gives the current iteration count as well as
-the next value. Read more
-1.0.0 · sourcefn peekable(self) -> Peekable<Self>
Creates an iterator which can use the peek
and peek_mut
methods
+}Expand description
iterator for the simple range structure
+
Fields§
§current: T
§end: T
Implementations§
source§impl<T> SimpleRangeIterator<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
Trait Implementations§
source§impl<T> Iterator for SimpleRangeIterator<T>where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
source§fn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read moresource§fn next_chunk<const N: usize>(
+ &mut self
+) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_next_chunk
)Advances the iterator and returns an array containing the next N
values. Read more1.0.0 · source§fn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more1.0.0 · source§fn count(self) -> usizewhere
+ Self: Sized,
Consumes the iterator, counting the number of iterations and returning it. Read more1.0.0 · source§fn last(self) -> Option<Self::Item>where
+ Self: Sized,
Consumes the iterator, returning the last element. Read moresource§fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>
🔬This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more1.0.0 · source§fn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more1.28.0 · source§fn step_by(self, step: usize) -> StepBy<Self>where
+ Self: Sized,
Creates an iterator starting at the same point, but stepping by
+the given amount at each iteration. Read more1.0.0 · source§fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more1.0.0 · source§fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read moresource§fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where
+ Self: Sized,
+ G: FnMut() -> Self::Item,
🔬This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
+between adjacent items of the original iterator. Read more1.0.0 · source§fn map<B, F>(self, f: F) -> Map<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
+element. Read more1.21.0 · source§fn for_each<F>(self, f: F)where
+ Self: Sized,
+ F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more1.0.0 · source§fn filter<P>(self, predicate: P) -> Filter<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
+should be yielded. Read more1.0.0 · source§fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more1.0.0 · source§fn enumerate(self) -> Enumerate<Self>where
+ Self: Sized,
Creates an iterator which gives the current iteration count as well as
+the next value. Read more1.0.0 · sourcefn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0 · sourcefn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more
-1.57.0 · sourcefn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where
P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more
-1.0.0 · sourcefn skip(self, n: usize) -> Skip<Self>
Creates an iterator that skips the first n
elements. Read more
-1.0.0 · sourcefn take(self, n: usize) -> Take<Self>
Creates an iterator that yields the first n
elements, or fewer
-if the underlying iterator ends sooner. Read more
-1.0.0 · sourcefn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · sourcefn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
U: IntoIterator,
F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read more
-1.29.0 · sourcefn flatten(self) -> Flatten<Self> where
Self::Item: IntoIterator,
Creates an iterator that flattens nested structure. Read more
-1.0.0 · sourcefn inspect<F>(self, f: F) -> Inspect<Self, F> where
F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more
-1.0.0 · sourcefn by_ref(&mut self) -> &mut Self
Borrows an iterator, rather than consuming it. Read more
-1.0.0 · sourcefn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
Transforms an iterator into a collection. Read more
-sourcefn try_collect<B>(
&mut self
) -> <<Self::Item as Try>::Residual as Residual<B>>::TryType where
B: FromIterator<<Self::Item as Try>::Output>,
Self::Item: Try,
<Self::Item as Try>::Residual: Residual<B>,
🔬 This is a nightly-only experimental API. (iterator_try_collect
)Fallibly transforms an iterator into a collection, short circuiting if
-a failure is encountered. Read more
-sourcefn collect_into<E>(self, collection: &mut E) -> &mut E where
E: Extend<Self::Item>,
🔬 This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more
-1.0.0 · sourcefn partition<B, F>(self, f: F) -> (B, B) where
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read more
-sourcefn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
🔬 This is a nightly-only experimental API. (iter_partition_in_place
)Reorders the elements of this iterator in-place according to the given predicate,
-such that all those that return true
precede all those that return false
.
-Returns the number of true
elements found. Read more
-sourcefn is_partitioned<P>(self, predicate: P) -> bool where
P: FnMut(Self::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
-such that all those that return true
precede all those that return false
. Read more
-1.27.0 · sourcefn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
An iterator method that applies a function as long as it returns
-successfully, producing a single, final value. Read more
-1.27.0 · sourcefn try_for_each<F, R>(&mut self, f: F) -> R where
F: FnMut(Self::Item) -> R,
R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
-iterator, stopping at the first error and returning that error. Read more
-1.0.0 · sourcefn fold<B, F>(self, init: B, f: F) -> B where
F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
-returning the final result. Read more
-1.51.0 · sourcefn reduce<F>(self, f: F) -> Option<Self::Item> where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
-operation. Read more
-sourcefn try_reduce<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType where
F: FnMut(Self::Item, Self::Item) -> R,
R: Try<Output = Self::Item>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
-closure returns a failure, the failure is propagated back to the caller immediately. Read more
-1.0.0 · sourcefn all<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn any<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more
-1.30.0 · sourcefn find_map<B, F>(&mut self, f: F) -> Option<B> where
F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
-the first non-none result. Read more
-sourcefn try_find<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType where
F: FnMut(&Self::Item) -> R,
R: Try<Output = bool>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
-the first true result or the first error. Read more
-1.0.0 · sourcefn position<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more
-1.0.0 · sourcefn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
Searches for an element in an iterator from the right, returning its
-index. Read more
-1.0.0 · sourcefn max(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the maximum element of an iterator. Read more
-1.0.0 · sourcefn min(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the minimum element of an iterator. Read more
-1.6.0 · sourcefn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
-specified function. Read more
-1.15.0 · sourcefn max_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
-specified comparison function. Read more
-1.6.0 · sourcefn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
-specified function. Read more
-1.15.0 · sourcefn min_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
-specified comparison function. Read more
-1.0.0 · sourcefn rev(self) -> Rev<Self> where
Self: DoubleEndedIterator,
Reverses an iterator’s direction. Read more
-1.0.0 · sourcefn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more
-1.36.0 · sourcefn copied<'a, T>(self) -> Copied<Self> where
T: 'a + Copy,
Self: Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more
-1.0.0 · sourcefn cloned<'a, T>(self) -> Cloned<Self> where
T: 'a + Clone,
Self: Iterator<Item = &'a T>,
1.0.0 · sourcefn cycle(self) -> Cycle<Self> where
Self: Clone,
Repeats an iterator endlessly. Read more
-1.11.0 · sourcefn sum<S>(self) -> S where
S: Sum<Self::Item>,
Sums the elements of an iterator. Read more
-1.11.0 · sourcefn product<P>(self) -> P where
P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read more
-1.5.0 · sourcefn cmp<I>(self, other: I) -> Ordering where
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
sourcefn eq_by<I, F>(self, other: I, eq: F) -> bool where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_order_by
)1.5.0 · sourcefn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0 · sourcefn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less than those of another. Read more
-1.5.0 · sourcefn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less or equal to those of another. Read more
-1.5.0 · sourcefn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than those of another. Read more
-1.5.0 · sourcefn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than or equal to those of another. Read more
-sourcefn is_sorted(self) -> bool where
Self::Item: PartialOrd<Self::Item>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted. Read more
-sourcefn is_sorted_by<F>(self, compare: F) -> bool where
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read more
-sourcefn is_sorted_by_key<F, K>(self, f: F) -> bool where
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
-function. Read more
-Auto Trait Implementations
impl<T> RefUnwindSafe for SimpleRangeIterator<T> where
T: RefUnwindSafe,
impl<T> Send for SimpleRangeIterator<T> where
T: Send,
impl<T> Sync for SimpleRangeIterator<T> where
T: Sync,
impl<T> Unpin for SimpleRangeIterator<T> where
T: Unpin,
impl<T> UnwindSafe for SimpleRangeIterator<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+their documentation for more information. Read more1.0.0 · source§fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
1.0.0 · source§fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more1.57.0 · source§fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more1.0.0 · source§fn skip(self, n: usize) -> Skip<Self>where
+ Self: Sized,
Creates an iterator that skips the first n
elements. Read more1.0.0 · source§fn take(self, n: usize) -> Take<Self>where
+ Self: Sized,
Creates an iterator that yields the first n
elements, or fewer
+if the underlying iterator ends sooner. Read more1.0.0 · source§fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where
+ Self: Sized,
+ F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · source§fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where
+ Self: Sized,
+ U: IntoIterator,
+ F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read moresource§fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where
+ Self: Sized,
+ F: FnMut(&[Self::Item; N]) -> R,
🔬This is a nightly-only experimental API. (iter_map_windows
)Calls the given function f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read more1.0.0 · source§fn inspect<F>(self, f: F) -> Inspect<Self, F>where
+ Self: Sized,
+ F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more1.0.0 · source§fn by_ref(&mut self) -> &mut Selfwhere
+ Self: Sized,
Borrows an iterator, rather than consuming it. Read more1.0.0 · source§fn collect<B>(self) -> Bwhere
+ B: FromIterator<Self::Item>,
+ Self: Sized,
Transforms an iterator into a collection. Read moresource§fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere
+ E: Extend<Self::Item>,
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more1.0.0 · source§fn partition<B, F>(self, f: F) -> (B, B)where
+ Self: Sized,
+ B: Default + Extend<Self::Item>,
+ F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read moresource§fn is_partitioned<P>(self, predicate: P) -> boolwhere
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
+such that all those that return true
precede all those that return false
. Read more1.27.0 · source§fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
An iterator method that applies a function as long as it returns
+successfully, producing a single, final value. Read more1.27.0 · source§fn try_for_each<F, R>(&mut self, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> R,
+ R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
+iterator, stopping at the first error and returning that error. Read more1.0.0 · source§fn fold<B, F>(self, init: B, f: F) -> Bwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
+returning the final result. Read more1.51.0 · source§fn reduce<F>(self, f: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
+operation. Read moresource§fn try_reduce<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> R,
+ R: Try<Output = Self::Item>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
+closure returns a failure, the failure is propagated back to the caller immediately. Read more1.0.0 · source§fn all<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more1.0.0 · source§fn any<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more1.0.0 · source§fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more1.30.0 · source§fn find_map<B, F>(&mut self, f: F) -> Option<B>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
+the first non-none result. Read moresource§fn try_find<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(&Self::Item) -> R,
+ R: Try<Output = bool>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
+the first true result or the first error. Read more1.0.0 · source§fn position<P>(&mut self, predicate: P) -> Option<usize>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more1.6.0 · source§fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
+specified function. Read more1.15.0 · source§fn max_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
+specified comparison function. Read more1.6.0 · source§fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
+specified function. Read more1.15.0 · source§fn min_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
+specified comparison function. Read more1.0.0 · source§fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where
+ FromA: Default + Extend<A>,
+ FromB: Default + Extend<B>,
+ Self: Sized + Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more1.36.0 · source§fn copied<'a, T>(self) -> Copied<Self>where
+ T: 'a + Copy,
+ Self: Sized + Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more1.0.0 · source§fn cloned<'a, T>(self) -> Cloned<Self>where
+ T: 'a + Clone,
+ Self: Sized + Iterator<Item = &'a T>,
source§fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_array_chunks
)Returns an iterator over N
elements of the iterator at a time. Read more1.11.0 · source§fn sum<S>(self) -> Swhere
+ Self: Sized,
+ S: Sum<Self::Item>,
Sums the elements of an iterator. Read more1.11.0 · source§fn product<P>(self) -> Pwhere
+ Self: Sized,
+ P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read moresource§fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn partial_cmp<I>(self, other: I) -> Option<Ordering>where
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Lexicographically compares the PartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moresource§fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn eq<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
source§fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_order_by
)1.5.0 · source§fn ne<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
1.5.0 · source§fn lt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less than those of another. Read more1.5.0 · source§fn le<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less or equal to those of another. Read more1.5.0 · source§fn gt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than those of another. Read more1.5.0 · source§fn ge<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than or equal to those of another. Read moresource§fn is_sorted_by<F>(self, compare: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read moresource§fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> K,
+ K: PartialOrd<K>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
+function. Read moreAuto Trait Implementations§
§impl<T> RefUnwindSafe for SimpleRangeIterator<T>where
+ T: RefUnwindSafe,
§impl<T> Send for SimpleRangeIterator<T>where
+ T: Send,
§impl<T> Sync for SimpleRangeIterator<T>where
+ T: Sync,
§impl<T> Unpin for SimpleRangeIterator<T>where
+ T: Unpin,
§impl<T> UnwindSafe for SimpleRangeIterator<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<I> IntoIterator for I where
I: Iterator,
-
\ No newline at end of file
+From<T> for U
chooses to do.
+source§impl<I> IntoIterator for Iwhere
+ I: Iterator,
#[repr(C)]pub struct VirtAddr(pub usize);
virtual address
-0: usize
VirtAddr
->VirtPageNum
VirtAddr
->VirtPageNum
Get page offset
-Converts to this type from the input type.
-This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
#[repr(C)]pub struct VirtAddr(pub usize);
virtual address
+0: usize
VirtAddr
->VirtPageNum
VirtAddr
->VirtPageNum
Get page offset
+self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+#[repr(C)]pub struct VirtPageNum(pub usize);
virtual page number
-0: usize
Returns a copy of the value. Read more
-Performs copy-assignment from source
. Read more
Converts to this type from the input type.
-Converts to this type from the input type.
-This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
This method tests for !=
.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
#[repr(C)]pub struct VirtPageNum(pub usize);
virtual page number
+0: usize
source
. Read moreself
and other
values to be equal, and is used
+by ==
.self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+pub type VPNRange = SimpleRange<VirtPageNum>;
a simple range structure for virtual page number
-pub type VPNRange = SimpleRange<VirtPageNum>;
a simple range structure for virtual page number
+struct VPNRange {
+ l: VirtPageNum,
+ r: VirtPageNum,
+}
l: VirtPageNum
§r: VirtPageNum
source
. Read morepub fn frame_alloc() -> Option<FrameTracker>
allocate a frame
-pub fn frame_alloc() -> Option<FrameTracker>
allocate a frame
+pub fn frame_dealloc(ppn: PhysPageNum)
deallocate a frame
-pub fn frame_dealloc(ppn: PhysPageNum)
deallocate a frame
+pub fn kernel_token() -> usize
Get kernelspace root ppn
+pub fn remap_test()
Check PageTable running correctly
-pub fn remap_test()
Check PageTable running correctly
+pub fn translated_ref<T>(token: usize, ptr: *const T) -> &'static T
Translate a generic through page table and return a reference
+pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Translate a generic through page table and return a mutable reference
-pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Translate a generic through page table and return a mutable reference
+pub fn frame_alloc() -> Option<FrameTracker>
allocate a frame
-pub fn frame_alloc() -> Option<FrameTracker>
allocate a frame
+pub fn frame_allocator_test()
a simple test for frame allocator
-pub fn frame_allocator_test()
a simple test for frame allocator
+pub fn frame_dealloc(ppn: PhysPageNum)
deallocate a frame
-pub fn frame_dealloc(ppn: PhysPageNum)
deallocate a frame
+pub fn init_frame_allocator()
initiate the frame allocator using ekernel
and MEMORY_END
pub fn init_frame_allocator()
initiate the frame allocator using ekernel
and MEMORY_END
Implementation of FrameAllocator
which
+
Implementation of FrameAllocator
which
controls all the frames in the operating system.
frame allocator instance through lazy_static!
-manage a frame which has the same lifecycle as the tracker
-an implementation for frame allocator
-allocate a frame
-a simple test for frame allocator
-deallocate a frame
-initiate the frame allocator using ekernel
and MEMORY_END
ekernel
and MEMORY_END
pub struct FRAME_ALLOCATOR {
+FRAME_ALLOCATOR in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::FRAME_ALLOCATOR
source · pub struct FRAME_ALLOCATOR {
__private_field: (),
-}
Expand description
frame allocator instance through lazy_static!
-Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<StackFrameAllocator>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for FRAME_ALLOCATOR
type Target = UPSafeCell<StackFrameAllocator>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<StackFrameAllocator>
Dereferences the value.
-sourceimpl LazyStatic for FRAME_ALLOCATOR
Auto Trait Implementations
impl RefUnwindSafe for FRAME_ALLOCATOR
impl Send for FRAME_ALLOCATOR
impl Sync for FRAME_ALLOCATOR
impl Unpin for FRAME_ALLOCATOR
impl UnwindSafe for FRAME_ALLOCATOR
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
frame allocator instance through lazy_static!
+Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<StackFrameAllocator>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for FRAME_ALLOCATOR
§type Target = UPSafeCell<StackFrameAllocator>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<StackFrameAllocator>
Dereferences the value.source§impl LazyStatic for FRAME_ALLOCATOR
Auto Trait Implementations§
§impl RefUnwindSafe for FRAME_ALLOCATOR
§impl Send for FRAME_ALLOCATOR
§impl Sync for FRAME_ALLOCATOR
§impl Unpin for FRAME_ALLOCATOR
§impl UnwindSafe for FRAME_ALLOCATOR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct FrameTracker {
+FrameTracker in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::FrameTracker
source · pub struct FrameTracker {
pub ppn: PhysPageNum,
-}
Expand description
manage a frame which has the same lifecycle as the tracker
-Fields
ppn: PhysPageNum
Implementations
sourceimpl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
-Trait Implementations
sourceimpl Debug for FrameTracker
Auto Trait Implementations
impl RefUnwindSafe for FrameTracker
impl Send for FrameTracker
impl Sync for FrameTracker
impl Unpin for FrameTracker
impl UnwindSafe for FrameTracker
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
manage a frame which has the same lifecycle as the tracker
+Fields§
§ppn: PhysPageNum
Implementations§
source§impl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
+Trait Implementations§
source§impl Debug for FrameTracker
Auto Trait Implementations§
§impl RefUnwindSafe for FrameTracker
§impl Send for FrameTracker
§impl Sync for FrameTracker
§impl Unpin for FrameTracker
§impl UnwindSafe for FrameTracker
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct StackFrameAllocator {
+StackFrameAllocator in os::mm::frame_allocator - Rust Struct os::mm::frame_allocator::StackFrameAllocator
source · pub struct StackFrameAllocator {
current: usize,
end: usize,
recycled: Vec<usize>,
-}
Expand description
an implementation for frame allocator
-Fields
current: usize
end: usize
recycled: Vec<usize>
Implementations
sourceimpl StackFrameAllocator
sourcepub fn init(&mut self, l: PhysPageNum, r: PhysPageNum)
Trait Implementations
sourceimpl FrameAllocator for StackFrameAllocator
sourcefn new() -> Self
sourcefn alloc(&mut self) -> Option<PhysPageNum>
sourcefn dealloc(&mut self, ppn: PhysPageNum)
Auto Trait Implementations
impl RefUnwindSafe for StackFrameAllocator
impl Send for StackFrameAllocator
impl Sync for StackFrameAllocator
impl Unpin for StackFrameAllocator
impl UnwindSafe for StackFrameAllocator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
an implementation for frame allocator
+Fields§
§current: usize
§end: usize
§recycled: Vec<usize>
Implementations§
source§impl StackFrameAllocator
sourcepub fn init(&mut self, l: PhysPageNum, r: PhysPageNum)
Trait Implementations§
source§impl FrameAllocator for StackFrameAllocator
Auto Trait Implementations§
§impl RefUnwindSafe for StackFrameAllocator
§impl Send for StackFrameAllocator
§impl Sync for StackFrameAllocator
§impl Unpin for StackFrameAllocator
§impl UnwindSafe for StackFrameAllocator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
trait FrameAllocator {
- fn new() -> Self;
- fn alloc(&mut self) -> Option<PhysPageNum>;
- fn dealloc(&mut self, ppn: PhysPageNum);
-}
trait FrameAllocator {
+ // Required methods
+ fn new() -> Self;
+ fn alloc(&mut self) -> Option<PhysPageNum>;
+ fn dealloc(&mut self, ppn: PhysPageNum);
+}
type FrameAllocatorImpl = StackFrameAllocator;
type FrameAllocatorImpl = StackFrameAllocator;
struct FrameAllocatorImpl {
+ current: usize,
+ end: usize,
+ recycled: Vec<usize, Global>,
+}
current: usize
§end: usize
§recycled: Vec<usize, Global>
panic when heap allocation error occurs
-pub fn handle_alloc_error(layout: Layout) -> !
panic when heap allocation error occurs
+pub fn heap_test()
pub fn init_heap()
initiate heap allocator
+static HEAP_ALLOCATOR: LockedHeap
heap allocator instance
-static HEAP_ALLOCATOR: LockedHeap
heap allocator instance
+static mut HEAP_SPACE: [u8; 2097152]
heap space ([u8; KERNEL_HEAP_SIZE])
-static mut HEAP_SPACE: [u8; 2097152]
heap space ([u8; KERNEL_HEAP_SIZE])
+Memory management implementation
+Memory management implementation
SV39 page-based virtual-memory architecture for RV64 systems, and everything about memory management, like frame allocator, page table, map area and memory set, is implemented here.
Every task or process has a memory_set to control its virtual memory.
-Implementation of physical and virtual address and page number.
-Implementation of FrameAllocator
which
-controls all the frames in the operating system.
The global allocator
-Implementation of PageTableEntry
and PageTable
.
manage a frame which has the same lifecycle as the tracker
-a memory set instance through lazy_static! managing kernel space
-map permission corresponding to that in pte: R W X U
memory set structure, controls virtual-memory space
-Record root ppn and has the same lifetime as 1 and 2 level PageTableEntry
page table entry structure
-Definitions
-phiscal page number
-Array of u8 slice that user communicate with os
-Iterator of UserBuffer
virtual address
-virtual page number
-Add value by one
-allocate a frame
-deallocate a frame
-initiate heap allocator, frame allocator and kernel space
-Get kernelspace root ppn
-Check PageTable running correctly
-Translate a pointer to a mutable u8 Vec through page table
-Translate a generic through page table and return a reference
-Translate a generic through page table and return a mutable reference
-Translate a pointer to a mutable u8 Vec end with \0
through page table to a String
pub use memory_set::KERNEL_SPACE;
pub use memory_set::KERNEL_SPACE;
FrameAllocator
which
+controls all the frames in the operating system.PageTableEntry
and PageTable
.R W X U
PageTableEntry
UserBuffer
\0
through page table to a String
pub enum MapType {
+MapType in os::mm::memory_set - Rust Enum os::mm::memory_set::MapType
source · pub enum MapType {
Identical,
Framed,
-}
Expand description
map type for memory set: identical or framed
-Variants
Identical
Framed
Trait Implementations
sourceimpl Copy for MapType
sourceimpl StructuralPartialEq for MapType
Auto Trait Implementations
impl RefUnwindSafe for MapType
impl Send for MapType
impl Sync for MapType
impl Unpin for MapType
impl UnwindSafe for MapType
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
map type for memory set: identical or framed
+Variants§
Trait Implementations§
source§impl PartialEq<MapType> for MapType
source§impl Copy for MapType
source§impl StructuralPartialEq for MapType
Auto Trait Implementations§
§impl RefUnwindSafe for MapType
§impl Send for MapType
§impl Sync for MapType
§impl Unpin for MapType
§impl UnwindSafe for MapType
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
unsafe extern "C" fn ebss()
unsafe extern "C" fn edata()
unsafe extern "C" fn ekernel()
unsafe extern "C" fn erodata()
unsafe extern "C" fn etext()
pub fn kernel_token() -> usize
Get kernelspace root ppn
-pub fn kernel_token() -> usize
Get kernelspace root ppn
+pub fn remap_test()
Check PageTable running correctly
-pub fn remap_test()
Check PageTable running correctly
+unsafe extern "C" fn sbss_with_stack()
unsafe extern "C" fn sbss_with_stack()
unsafe extern "C" fn sdata()
unsafe extern "C" fn srodata()
unsafe extern "C" fn stext()
unsafe extern "C" fn strampoline()
unsafe extern "C" fn strampoline()
a memory set instance through lazy_static! managing kernel space
-map area structure, controls a contiguous piece of virtual memory
-map permission corresponding to that in pte: R W X U
memory set structure, controls virtual-memory space
-map type for memory set: identical or framed
-R W X U
pub struct KERNEL_SPACE {
+KERNEL_SPACE in os::mm::memory_set - Rust Struct os::mm::memory_set::KERNEL_SPACE
source · pub struct KERNEL_SPACE {
__private_field: (),
-}
Expand description
a memory set instance through lazy_static! managing kernel space
-Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for KERNEL_SPACE
type Target = Arc<UPSafeCell<MemorySet>>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &Arc<UPSafeCell<MemorySet>>
Dereferences the value.
-sourceimpl LazyStatic for KERNEL_SPACE
Auto Trait Implementations
impl RefUnwindSafe for KERNEL_SPACE
impl Send for KERNEL_SPACE
impl Sync for KERNEL_SPACE
impl Unpin for KERNEL_SPACE
impl UnwindSafe for KERNEL_SPACE
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
a memory set instance through lazy_static! managing kernel space
+Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for KERNEL_SPACE
source§impl LazyStatic for KERNEL_SPACE
Auto Trait Implementations§
§impl RefUnwindSafe for KERNEL_SPACE
§impl Send for KERNEL_SPACE
§impl Sync for KERNEL_SPACE
§impl Unpin for KERNEL_SPACE
§impl UnwindSafe for KERNEL_SPACE
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct MapArea {
+MapArea in os::mm::memory_set - Rust Struct os::mm::memory_set::MapArea
source · pub struct MapArea {
vpn_range: SimpleRange<VirtPageNum>,
data_frames: BTreeMap<VirtPageNum, FrameTracker>,
map_type: MapType,
map_perm: MapPermission,
-}
Expand description
map area structure, controls a contiguous piece of virtual memory
-Fields
vpn_range: SimpleRange<VirtPageNum>
data_frames: BTreeMap<VirtPageNum, FrameTracker>
map_type: MapType
map_perm: MapPermission
Implementations
sourceimpl MapArea
sourcepub fn new(
start_va: VirtAddr,
end_va: VirtAddr,
map_type: MapType,
map_perm: MapPermission
) -> Self
sourcepub fn from_another(another: &MapArea) -> Self
sourcepub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn map(&mut self, page_table: &mut PageTable)
sourcepub fn unmap(&mut self, page_table: &mut PageTable)
sourcepub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8])
data: start-aligned but maybe with shorter length
+}Expand description
map area structure, controls a contiguous piece of virtual memory
+
Fields§
§vpn_range: SimpleRange<VirtPageNum>
§data_frames: BTreeMap<VirtPageNum, FrameTracker>
§map_type: MapType
§map_perm: MapPermission
Implementations§
source§impl MapArea
sourcepub fn new(
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ map_type: MapType,
+ map_perm: MapPermission
+) -> Self
sourcepub fn from_another(another: &MapArea) -> Self
sourcepub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum)
sourcepub fn map(&mut self, page_table: &mut PageTable)
sourcepub fn unmap(&mut self, page_table: &mut PageTable)
Auto Trait Implementations
impl RefUnwindSafe for MapArea
impl Send for MapArea
impl Sync for MapArea
impl Unpin for MapArea
impl UnwindSafe for MapArea
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Auto Trait Implementations§
§impl RefUnwindSafe for MapArea
§impl Send for MapArea
§impl Sync for MapArea
§impl Unpin for MapArea
§impl UnwindSafe for MapArea
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct MapPermission {
+MapPermission in os::mm::memory_set - Rust Struct os::mm::memory_set::MapPermission
source · pub struct MapPermission {
bits: u8,
-}
Expand description
map permission corresponding to that in pte: R W X U
-Fields
bits: u8
Implementations
sourceimpl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
+}Expand description
map permission corresponding to that in pte: R W X U
+
Fields§
§bits: u8
Implementations§
source§impl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -26,35 +20,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -62,67 +56,40 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl Binary for MapPermission
sourceimpl BitAnd<MapPermission> for MapPermission
sourceimpl BitAndAssign<MapPermission> for MapPermission
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOr<MapPermission> for MapPermission
sourcefn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
-type Output = Self
The resulting type after applying the |
operator.
-sourceimpl BitOrAssign<MapPermission> for MapPermission
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXor<MapPermission> for MapPermission
sourceimpl BitXorAssign<MapPermission> for MapPermission
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Clone for MapPermission
sourcefn clone(&self) -> MapPermission
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for MapPermission
sourceimpl Extend<MapPermission> for MapPermission
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<MapPermission> for MapPermission
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Hash for MapPermission
sourceimpl LowerHex for MapPermission
sourceimpl Not for MapPermission
sourceimpl Octal for MapPermission
sourceimpl Ord for MapPermission
sourceimpl PartialEq<MapPermission> for MapPermission
sourcefn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &MapPermission) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<MapPermission> for MapPermission
sourcefn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Sub<MapPermission> for MapPermission
sourceimpl SubAssign<MapPermission> for MapPermission
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl UpperHex for MapPermission
sourceimpl Copy for MapPermission
sourceimpl Eq for MapPermission
sourceimpl StructuralEq for MapPermission
sourceimpl StructuralPartialEq for MapPermission
Auto Trait Implementations
impl RefUnwindSafe for MapPermission
impl Send for MapPermission
impl Sync for MapPermission
impl Unpin for MapPermission
impl UnwindSafe for MapPermission
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl Binary for MapPermission
source§impl BitAnd<MapPermission> for MapPermission
source§impl BitAndAssign<MapPermission> for MapPermission
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOr<MapPermission> for MapPermission
source§fn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
+§type Output = MapPermission
The resulting type after applying the |
operator.source§impl BitOrAssign<MapPermission> for MapPermission
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXor<MapPermission> for MapPermission
source§impl BitXorAssign<MapPermission> for MapPermission
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Clone for MapPermission
source§fn clone(&self) -> MapPermission
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for MapPermission
source§impl Extend<MapPermission> for MapPermission
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<MapPermission> for MapPermission
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Hash for MapPermission
source§impl LowerHex for MapPermission
source§impl Not for MapPermission
source§impl Octal for MapPermission
source§impl Ord for MapPermission
source§fn cmp(&self, other: &MapPermission) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<MapPermission> for MapPermission
source§fn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<MapPermission> for MapPermission
source§fn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Sub<MapPermission> for MapPermission
source§impl SubAssign<MapPermission> for MapPermission
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl UpperHex for MapPermission
source§impl Copy for MapPermission
source§impl Eq for MapPermission
source§impl StructuralEq for MapPermission
source§impl StructuralPartialEq for MapPermission
Auto Trait Implementations§
§impl RefUnwindSafe for MapPermission
§impl Send for MapPermission
§impl Sync for MapPermission
§impl Unpin for MapPermission
§impl UnwindSafe for MapPermission
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct MemorySet {
+MemorySet in os::mm::memory_set - Rust Struct os::mm::memory_set::MemorySet
source · pub struct MemorySet {
page_table: PageTable,
areas: Vec<MapArea>,
-}
Expand description
memory set structure, controls virtual-memory space
-Fields
page_table: PageTable
areas: Vec<MapArea>
Implementations
sourceimpl MemorySet
sourcepub fn insert_framed_area(
&mut self,
start_va: VirtAddr,
end_va: VirtAddr,
permission: MapPermission
)
Assume that no conflicts.
-sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
-sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
-sourcepub fn new_kernel() -> Self
Without kernel stacks.
-sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
+}Expand description
memory set structure, controls virtual-memory space
+
Fields§
§page_table: PageTable
§areas: Vec<MapArea>
Implementations§
source§impl MemorySet
sourcepub fn insert_framed_area(
+ &mut self,
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ permission: MapPermission
+)
Assume that no conflicts.
+sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
+sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
+sourcepub fn new_kernel() -> Self
Without kernel stacks.
+sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
also returns user_sp and entry point.
-sourcepub fn from_existed_user(user_space: &MemorySet) -> MemorySet
Clone a same MemorySet
-sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
-sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
-Auto Trait Implementations
impl RefUnwindSafe for MemorySet
impl Send for MemorySet
impl Sync for MemorySet
impl Unpin for MemorySet
impl UnwindSafe for MemorySet
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
sourcepub fn from_existed_user(user_space: &MemorySet) -> MemorySet
Clone a same MemorySet
+sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
+sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
+Auto Trait Implementations§
§impl RefUnwindSafe for MemorySet
§impl Send for MemorySet
§impl Sync for MemorySet
§impl Unpin for MemorySet
§impl UnwindSafe for MemorySet
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
Translate a pointer to a mutable u8 Vec through page table
-Translate a generic through page table and return a reference
-pub fn translated_ref<T>(token: usize, ptr: *const T) -> &'static T
Translate a generic through page table and return a reference
+pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Translate a generic through page table and return a mutable reference
-pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T
Translate a generic through page table and return a mutable reference
+Translate a pointer to a mutable u8 Vec end with \0
through page table to a String
pub fn translated_str(token: usize, ptr: *const u8) -> String
Translate a pointer to a mutable u8 Vec end with \0
through page table to a String
Implementation of PageTableEntry
and PageTable
.
Record root ppn and has the same lifetime as 1 and 2 level PageTableEntry
page table entry structure
-Array of u8 slice that user communicate with os
-Iterator of UserBuffer
Translate a pointer to a mutable u8 Vec through page table
-Translate a generic through page table and return a reference
-Translate a generic through page table and return a mutable reference
-Translate a pointer to a mutable u8 Vec end with \0
through page table to a String
Implementation of PageTableEntry
and PageTable
.
PageTableEntry
UserBuffer
\0
through page table to a String
pub struct PTEFlags {
+PTEFlags in os::mm::page_table - Rust Fields
bits: u8
Implementations
sourceimpl PTEFlags
sourcepub const V: Self
sourcepub const R: Self
sourcepub const W: Self
sourcepub const X: Self
sourcepub const U: Self
sourcepub const G: Self
sourcepub const A: Self
sourcepub const D: Self
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
+}
Fields§
§bits: u8
Implementations§
source§impl PTEFlags
sourcepub const V: Self = _
sourcepub const R: Self = _
sourcepub const W: Self = _
sourcepub const X: Self = _
sourcepub const U: Self = _
sourcepub const G: Self = _
sourcepub const A: Self = _
sourcepub const D: Self = _
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -21,35 +15,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -57,67 +51,40 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl BitAndAssign<PTEFlags> for PTEFlags
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOrAssign<PTEFlags> for PTEFlags
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXorAssign<PTEFlags> for PTEFlags
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Extend<PTEFlags> for PTEFlags
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<PTEFlags> for PTEFlags
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Ord for PTEFlags
sourceimpl PartialOrd<PTEFlags> for PTEFlags
sourcefn partial_cmp(&self, other: &PTEFlags) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl SubAssign<PTEFlags> for PTEFlags
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl Copy for PTEFlags
sourceimpl Eq for PTEFlags
sourceimpl StructuralEq for PTEFlags
sourceimpl StructuralPartialEq for PTEFlags
Auto Trait Implementations
impl RefUnwindSafe for PTEFlags
impl Send for PTEFlags
impl Sync for PTEFlags
impl Unpin for PTEFlags
impl UnwindSafe for PTEFlags
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl BitAndAssign<PTEFlags> for PTEFlags
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOrAssign<PTEFlags> for PTEFlags
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXorAssign<PTEFlags> for PTEFlags
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Extend<PTEFlags> for PTEFlags
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<PTEFlags> for PTEFlags
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Ord for PTEFlags
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<PTEFlags> for PTEFlags
source§impl PartialOrd<PTEFlags> for PTEFlags
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl SubAssign<PTEFlags> for PTEFlags
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl Copy for PTEFlags
source§impl Eq for PTEFlags
source§impl StructuralEq for PTEFlags
source§impl StructuralPartialEq for PTEFlags
Auto Trait Implementations§
§impl RefUnwindSafe for PTEFlags
§impl Send for PTEFlags
§impl Sync for PTEFlags
§impl Unpin for PTEFlags
§impl UnwindSafe for PTEFlags
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PageTable {
+PageTable in os::mm::page_table - Rust Struct os::mm::page_table::PageTable
source · pub struct PageTable {
root_ppn: PhysPageNum,
frames: Vec<FrameTracker>,
-}
Expand description
Record root ppn and has the same lifetime as 1 and 2 level PageTableEntry
-Fields
root_ppn: PhysPageNum
frames: Vec<FrameTracker>
Implementations
sourceimpl PageTable
Assume that it won’t oom when creating/mapping.
-sourcepub fn from_token(satp: usize) -> Self
Temporarily used to get arguments from user space.
-sourcefn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address, create a frame if not exist
-sourcefn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address
-sourcepub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags)
Create a mapping form vpn
to ppn
-sourcepub fn unmap(&mut self, vpn: VirtPageNum)
Delete a mapping form vpn
-sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate VirtPageNum
to PageTableEntry
-sourcepub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr>
Translate VirtAddr
to PhysAddr
-Auto Trait Implementations
impl RefUnwindSafe for PageTable
impl Send for PageTable
impl Sync for PageTable
impl Unpin for PageTable
impl UnwindSafe for PageTable
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Record root ppn and has the same lifetime as 1 and 2 level PageTableEntry
+Fields§
§root_ppn: PhysPageNum
§frames: Vec<FrameTracker>
Implementations§
source§impl PageTable
Assume that it won’t oom when creating/mapping.
+sourcepub fn from_token(satp: usize) -> Self
Temporarily used to get arguments from user space.
+sourcefn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address, create a frame if not exist
+sourcefn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address
+sourcepub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags)
Create a mapping form vpn
to ppn
+sourcepub fn unmap(&mut self, vpn: VirtPageNum)
Delete a mapping form vpn
+sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate VirtPageNum
to PageTableEntry
+sourcepub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr>
Translate VirtAddr
to PhysAddr
+Auto Trait Implementations§
§impl RefUnwindSafe for PageTable
§impl Send for PageTable
§impl Sync for PageTable
§impl Unpin for PageTable
§impl UnwindSafe for PageTable
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
#[repr(C)]pub struct PageTableEntry {
+PageTableEntry in os::mm::page_table - Rust Struct os::mm::page_table::PageTableEntry
source · #[repr(C)]pub struct PageTableEntry {
pub bits: usize,
-}
Expand description
page table entry structure
-Fields
bits: usize
PTE
-Implementations
sourceimpl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
-sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
-sourcepub fn executable(&self) -> bool
Check PTE executable
-Trait Implementations
sourceimpl Clone for PageTableEntry
sourcefn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Copy for PageTableEntry
Auto Trait Implementations
impl RefUnwindSafe for PageTableEntry
impl Send for PageTableEntry
impl Sync for PageTableEntry
impl Unpin for PageTableEntry
impl UnwindSafe for PageTableEntry
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
page table entry structure
+Fields§
§bits: usize
PTE
+Implementations§
source§impl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
+sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
+sourcepub fn executable(&self) -> bool
Check PTE executable
+Trait Implementations§
source§impl Clone for PageTableEntry
source§fn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Copy for PageTableEntry
Auto Trait Implementations§
§impl RefUnwindSafe for PageTableEntry
§impl Send for PageTableEntry
§impl Sync for PageTableEntry
§impl Unpin for PageTableEntry
§impl UnwindSafe for PageTableEntry
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct UserBuffer {
- pub buffers: Vec<&'static mut [u8]>,
-}
Array of u8 slice that user communicate with os
-buffers: Vec<&'static mut [u8]>
U8 vec
-Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct UserBuffer {
+ pub buffers: Vec<&'static mut [u8]>,
+}
Array of u8 slice that user communicate with os
+buffers: Vec<&'static mut [u8]>
U8 vec
+From<T> for U
chooses to do.
+pub struct UserBufferIterator {
- buffers: Vec<&'static mut [u8]>,
+UserBufferIterator in os::mm::page_table - Rust Struct os::mm::page_table::UserBufferIterator
source · pub struct UserBufferIterator {
+ buffers: Vec<&'static mut [u8]>,
current_buffer: usize,
current_idx: usize,
-}
Expand description
Iterator of UserBuffer
-Fields
buffers: Vec<&'static mut [u8]>
current_buffer: usize
current_idx: usize
Trait Implementations
sourceimpl Iterator for UserBufferIterator
sourcefn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read more
-1.0.0 · sourcefn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more
-1.0.0 · sourcefn count(self) -> usize
Consumes the iterator, counting the number of iterations and returning it. Read more
-1.0.0 · sourcefn last(self) -> Option<Self::Item>
Consumes the iterator, returning the last element. Read more
-sourcefn advance_by(&mut self, n: usize) -> Result<(), usize>
🔬 This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more
-1.0.0 · sourcefn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more
-1.28.0 · sourcefn step_by(self, step: usize) -> StepBy<Self>
Creates an iterator starting at the same point, but stepping by
-the given amount at each iteration. Read more
-1.0.0 · sourcefn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more
-1.0.0 · sourcefn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read more
-sourcefn intersperse(self, separator: Self::Item) -> Intersperse<Self> where
Self::Item: Clone,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places a copy of separator
between adjacent
-items of the original iterator. Read more
-sourcefn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where
G: FnMut() -> Self::Item,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
-between adjacent items of the original iterator. Read more
-1.0.0 · sourcefn map<B, F>(self, f: F) -> Map<Self, F> where
F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
-element. Read more
-1.21.0 · sourcefn for_each<F>(self, f: F) where
F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more
-1.0.0 · sourcefn filter<P>(self, predicate: P) -> Filter<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
-should be yielded. Read more
-1.0.0 · sourcefn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more
-1.0.0 · sourcefn enumerate(self) -> Enumerate<Self>
Creates an iterator which gives the current iteration count as well as
-the next value. Read more
-1.0.0 · sourcefn peekable(self) -> Peekable<Self>
Creates an iterator which can use the peek
and peek_mut
methods
+}Expand description
Iterator of UserBuffer
+
Fields§
§buffers: Vec<&'static mut [u8]>
§current_buffer: usize
§current_idx: usize
Trait Implementations§
source§impl Iterator for UserBufferIterator
source§fn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read moresource§fn next_chunk<const N: usize>(
+ &mut self
+) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_next_chunk
)Advances the iterator and returns an array containing the next N
values. Read more1.0.0 · source§fn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more1.0.0 · source§fn count(self) -> usizewhere
+ Self: Sized,
Consumes the iterator, counting the number of iterations and returning it. Read more1.0.0 · source§fn last(self) -> Option<Self::Item>where
+ Self: Sized,
Consumes the iterator, returning the last element. Read moresource§fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>
🔬This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more1.0.0 · source§fn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more1.28.0 · source§fn step_by(self, step: usize) -> StepBy<Self>where
+ Self: Sized,
Creates an iterator starting at the same point, but stepping by
+the given amount at each iteration. Read more1.0.0 · source§fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more1.0.0 · source§fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read moresource§fn intersperse(self, separator: Self::Item) -> Intersperse<Self>where
+ Self: Sized,
+ Self::Item: Clone,
🔬This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places a copy of separator
between adjacent
+items of the original iterator. Read moresource§fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where
+ Self: Sized,
+ G: FnMut() -> Self::Item,
🔬This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
+between adjacent items of the original iterator. Read more1.0.0 · source§fn map<B, F>(self, f: F) -> Map<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
+element. Read more1.21.0 · source§fn for_each<F>(self, f: F)where
+ Self: Sized,
+ F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more1.0.0 · source§fn filter<P>(self, predicate: P) -> Filter<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
+should be yielded. Read more1.0.0 · source§fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more1.0.0 · source§fn enumerate(self) -> Enumerate<Self>where
+ Self: Sized,
Creates an iterator which gives the current iteration count as well as
+the next value. Read more1.0.0 · sourcefn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0 · sourcefn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more
-1.57.0 · sourcefn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where
P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more
-1.0.0 · sourcefn skip(self, n: usize) -> Skip<Self>
Creates an iterator that skips the first n
elements. Read more
-1.0.0 · sourcefn take(self, n: usize) -> Take<Self>
Creates an iterator that yields the first n
elements, or fewer
-if the underlying iterator ends sooner. Read more
-1.0.0 · sourcefn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · sourcefn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
U: IntoIterator,
F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read more
-1.29.0 · sourcefn flatten(self) -> Flatten<Self> where
Self::Item: IntoIterator,
Creates an iterator that flattens nested structure. Read more
-1.0.0 · sourcefn inspect<F>(self, f: F) -> Inspect<Self, F> where
F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more
-1.0.0 · sourcefn by_ref(&mut self) -> &mut Self
Borrows an iterator, rather than consuming it. Read more
-1.0.0 · sourcefn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
Transforms an iterator into a collection. Read more
-sourcefn try_collect<B>(
&mut self
) -> <<Self::Item as Try>::Residual as Residual<B>>::TryType where
B: FromIterator<<Self::Item as Try>::Output>,
Self::Item: Try,
<Self::Item as Try>::Residual: Residual<B>,
🔬 This is a nightly-only experimental API. (iterator_try_collect
)Fallibly transforms an iterator into a collection, short circuiting if
-a failure is encountered. Read more
-sourcefn collect_into<E>(self, collection: &mut E) -> &mut E where
E: Extend<Self::Item>,
🔬 This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more
-1.0.0 · sourcefn partition<B, F>(self, f: F) -> (B, B) where
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read more
-sourcefn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
🔬 This is a nightly-only experimental API. (iter_partition_in_place
)Reorders the elements of this iterator in-place according to the given predicate,
-such that all those that return true
precede all those that return false
.
-Returns the number of true
elements found. Read more
-sourcefn is_partitioned<P>(self, predicate: P) -> bool where
P: FnMut(Self::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
-such that all those that return true
precede all those that return false
. Read more
-1.27.0 · sourcefn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
An iterator method that applies a function as long as it returns
-successfully, producing a single, final value. Read more
-1.27.0 · sourcefn try_for_each<F, R>(&mut self, f: F) -> R where
F: FnMut(Self::Item) -> R,
R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
-iterator, stopping at the first error and returning that error. Read more
-1.0.0 · sourcefn fold<B, F>(self, init: B, f: F) -> B where
F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
-returning the final result. Read more
-1.51.0 · sourcefn reduce<F>(self, f: F) -> Option<Self::Item> where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
-operation. Read more
-sourcefn try_reduce<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType where
F: FnMut(Self::Item, Self::Item) -> R,
R: Try<Output = Self::Item>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
-closure returns a failure, the failure is propagated back to the caller immediately. Read more
-1.0.0 · sourcefn all<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn any<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more
-1.30.0 · sourcefn find_map<B, F>(&mut self, f: F) -> Option<B> where
F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
-the first non-none result. Read more
-sourcefn try_find<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType where
F: FnMut(&Self::Item) -> R,
R: Try<Output = bool>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
-the first true result or the first error. Read more
-1.0.0 · sourcefn position<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more
-1.0.0 · sourcefn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
Searches for an element in an iterator from the right, returning its
-index. Read more
-1.0.0 · sourcefn max(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the maximum element of an iterator. Read more
-1.0.0 · sourcefn min(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the minimum element of an iterator. Read more
-1.6.0 · sourcefn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
-specified function. Read more
-1.15.0 · sourcefn max_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
-specified comparison function. Read more
-1.6.0 · sourcefn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
-specified function. Read more
-1.15.0 · sourcefn min_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
-specified comparison function. Read more
-1.0.0 · sourcefn rev(self) -> Rev<Self> where
Self: DoubleEndedIterator,
Reverses an iterator’s direction. Read more
-1.0.0 · sourcefn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more
-1.36.0 · sourcefn copied<'a, T>(self) -> Copied<Self> where
T: 'a + Copy,
Self: Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more
-1.0.0 · sourcefn cloned<'a, T>(self) -> Cloned<Self> where
T: 'a + Clone,
Self: Iterator<Item = &'a T>,
1.0.0 · sourcefn cycle(self) -> Cycle<Self> where
Self: Clone,
Repeats an iterator endlessly. Read more
-1.11.0 · sourcefn sum<S>(self) -> S where
S: Sum<Self::Item>,
Sums the elements of an iterator. Read more
-1.11.0 · sourcefn product<P>(self) -> P where
P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read more
-1.5.0 · sourcefn cmp<I>(self, other: I) -> Ordering where
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
sourcefn eq_by<I, F>(self, other: I, eq: F) -> bool where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_order_by
)1.5.0 · sourcefn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0 · sourcefn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less than those of another. Read more
-1.5.0 · sourcefn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less or equal to those of another. Read more
-1.5.0 · sourcefn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than those of another. Read more
-1.5.0 · sourcefn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than or equal to those of another. Read more
-sourcefn is_sorted(self) -> bool where
Self::Item: PartialOrd<Self::Item>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted. Read more
-sourcefn is_sorted_by<F>(self, compare: F) -> bool where
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read more
-sourcefn is_sorted_by_key<F, K>(self, f: F) -> bool where
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
-function. Read more
-Auto Trait Implementations
impl RefUnwindSafe for UserBufferIterator
impl Send for UserBufferIterator
impl Sync for UserBufferIterator
impl Unpin for UserBufferIterator
impl !UnwindSafe for UserBufferIterator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+their documentation for more information. Read more1.0.0 · source§fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
1.0.0 · source§fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more1.57.0 · source§fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more1.0.0 · source§fn skip(self, n: usize) -> Skip<Self>where
+ Self: Sized,
Creates an iterator that skips the first n
elements. Read more1.0.0 · source§fn take(self, n: usize) -> Take<Self>where
+ Self: Sized,
Creates an iterator that yields the first n
elements, or fewer
+if the underlying iterator ends sooner. Read more1.0.0 · source§fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where
+ Self: Sized,
+ F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · source§fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where
+ Self: Sized,
+ U: IntoIterator,
+ F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read moresource§fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where
+ Self: Sized,
+ F: FnMut(&[Self::Item; N]) -> R,
🔬This is a nightly-only experimental API. (iter_map_windows
)Calls the given function f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read more1.0.0 · source§fn inspect<F>(self, f: F) -> Inspect<Self, F>where
+ Self: Sized,
+ F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more1.0.0 · source§fn by_ref(&mut self) -> &mut Selfwhere
+ Self: Sized,
Borrows an iterator, rather than consuming it. Read more1.0.0 · source§fn collect<B>(self) -> Bwhere
+ B: FromIterator<Self::Item>,
+ Self: Sized,
Transforms an iterator into a collection. Read moresource§fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere
+ E: Extend<Self::Item>,
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more1.0.0 · source§fn partition<B, F>(self, f: F) -> (B, B)where
+ Self: Sized,
+ B: Default + Extend<Self::Item>,
+ F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read moresource§fn is_partitioned<P>(self, predicate: P) -> boolwhere
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
+such that all those that return true
precede all those that return false
. Read more1.27.0 · source§fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
An iterator method that applies a function as long as it returns
+successfully, producing a single, final value. Read more1.27.0 · source§fn try_for_each<F, R>(&mut self, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> R,
+ R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
+iterator, stopping at the first error and returning that error. Read more1.0.0 · source§fn fold<B, F>(self, init: B, f: F) -> Bwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
+returning the final result. Read more1.51.0 · source§fn reduce<F>(self, f: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
+operation. Read moresource§fn try_reduce<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> R,
+ R: Try<Output = Self::Item>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
+closure returns a failure, the failure is propagated back to the caller immediately. Read more1.0.0 · source§fn all<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more1.0.0 · source§fn any<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more1.0.0 · source§fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more1.30.0 · source§fn find_map<B, F>(&mut self, f: F) -> Option<B>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
+the first non-none result. Read moresource§fn try_find<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(&Self::Item) -> R,
+ R: Try<Output = bool>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
+the first true result or the first error. Read more1.0.0 · source§fn position<P>(&mut self, predicate: P) -> Option<usize>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more1.0.0 · source§fn max(self) -> Option<Self::Item>where
+ Self: Sized,
+ Self::Item: Ord,
Returns the maximum element of an iterator. Read more1.0.0 · source§fn min(self) -> Option<Self::Item>where
+ Self: Sized,
+ Self::Item: Ord,
Returns the minimum element of an iterator. Read more1.6.0 · source§fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
+specified function. Read more1.15.0 · source§fn max_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
+specified comparison function. Read more1.6.0 · source§fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
+specified function. Read more1.15.0 · source§fn min_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
+specified comparison function. Read more1.0.0 · source§fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where
+ FromA: Default + Extend<A>,
+ FromB: Default + Extend<B>,
+ Self: Sized + Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more1.36.0 · source§fn copied<'a, T>(self) -> Copied<Self>where
+ T: 'a + Copy,
+ Self: Sized + Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more1.0.0 · source§fn cloned<'a, T>(self) -> Cloned<Self>where
+ T: 'a + Clone,
+ Self: Sized + Iterator<Item = &'a T>,
source§fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_array_chunks
)Returns an iterator over N
elements of the iterator at a time. Read more1.11.0 · source§fn sum<S>(self) -> Swhere
+ Self: Sized,
+ S: Sum<Self::Item>,
Sums the elements of an iterator. Read more1.11.0 · source§fn product<P>(self) -> Pwhere
+ Self: Sized,
+ P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read more1.5.0 · source§fn cmp<I>(self, other: I) -> Orderingwhere
+ I: IntoIterator<Item = Self::Item>,
+ Self::Item: Ord,
+ Self: Sized,
source§fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn partial_cmp<I>(self, other: I) -> Option<Ordering>where
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Lexicographically compares the PartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moresource§fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn eq<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
source§fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_order_by
)1.5.0 · source§fn ne<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
1.5.0 · source§fn lt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less than those of another. Read more1.5.0 · source§fn le<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less or equal to those of another. Read more1.5.0 · source§fn gt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than those of another. Read more1.5.0 · source§fn ge<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than or equal to those of another. Read moresource§fn is_sorted(self) -> boolwhere
+ Self: Sized,
+ Self::Item: PartialOrd<Self::Item>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted. Read moresource§fn is_sorted_by<F>(self, compare: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read moresource§fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> K,
+ K: PartialOrd<K>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
+function. Read moreAuto Trait Implementations§
§impl RefUnwindSafe for UserBufferIterator
§impl Send for UserBufferIterator
§impl Sync for UserBufferIterator
§impl Unpin for UserBufferIterator
§impl !UnwindSafe for UserBufferIterator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<I> IntoIterator for I where
I: Iterator,
-
\ No newline at end of file
+From<T> for U
chooses to do.
+source§impl<I> IntoIterator for Iwhere
+ I: Iterator,
pub struct FrameTracker {
+FrameTracker in os::mm - Rust Struct os::mm::FrameTracker
source · pub struct FrameTracker {
pub ppn: PhysPageNum,
-}
Expand description
manage a frame which has the same lifecycle as the tracker
-Fields
ppn: PhysPageNum
Implementations
sourceimpl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
-Trait Implementations
sourceimpl Debug for FrameTracker
Auto Trait Implementations
impl RefUnwindSafe for FrameTracker
impl Send for FrameTracker
impl Sync for FrameTracker
impl Unpin for FrameTracker
impl UnwindSafe for FrameTracker
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
manage a frame which has the same lifecycle as the tracker
+Fields§
§ppn: PhysPageNum
Implementations§
source§impl FrameTracker
sourcepub fn new(ppn: PhysPageNum) -> Self
Create an empty FrameTracker
+Trait Implementations§
source§impl Debug for FrameTracker
Auto Trait Implementations§
§impl RefUnwindSafe for FrameTracker
§impl Send for FrameTracker
§impl Sync for FrameTracker
§impl Unpin for FrameTracker
§impl UnwindSafe for FrameTracker
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct KERNEL_SPACE {
+KERNEL_SPACE in os::mm - Rust Struct os::mm::KERNEL_SPACE
source · pub struct KERNEL_SPACE {
__private_field: (),
-}
Expand description
a memory set instance through lazy_static! managing kernel space
-Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for KERNEL_SPACE
type Target = Arc<UPSafeCell<MemorySet>>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &Arc<UPSafeCell<MemorySet>>
Dereferences the value.
-sourceimpl LazyStatic for KERNEL_SPACE
Auto Trait Implementations
impl RefUnwindSafe for KERNEL_SPACE
impl Send for KERNEL_SPACE
impl Sync for KERNEL_SPACE
impl Unpin for KERNEL_SPACE
impl UnwindSafe for KERNEL_SPACE
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
a memory set instance through lazy_static! managing kernel space
+Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for KERNEL_SPACE
source§impl LazyStatic for KERNEL_SPACE
Auto Trait Implementations§
§impl RefUnwindSafe for KERNEL_SPACE
§impl Send for KERNEL_SPACE
§impl Sync for KERNEL_SPACE
§impl Unpin for KERNEL_SPACE
§impl UnwindSafe for KERNEL_SPACE
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct MapPermission {
+MapPermission in os::mm - Rust Struct os::mm::MapPermission
source · pub struct MapPermission {
bits: u8,
-}
Expand description
map permission corresponding to that in pte: R W X U
-Fields
bits: u8
Implementations
sourceimpl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
+}Expand description
map permission corresponding to that in pte: R W X U
+
Fields§
§bits: u8
Implementations§
source§impl MapPermission
sourcepub const fn from_bits(bits: u8) -> Option<Self>
Convert from underlying bit representation, unless that
representation contains bits that do not correspond to a flag.
-sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
+
sourcepub const fn from_bits_truncate(bits: u8) -> Self
Convert from underlying bit representation, dropping any bits
that do not correspond to flags.
-sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
+
sourcepub const unsafe fn from_bits_unchecked(bits: u8) -> Self
Convert from underlying bit representation, preserving all
bits (even those not corresponding to a defined flag).
Safety
The caller of the bitflags!
macro can chose to allow or
@@ -26,35 +20,35 @@ disallow extra bits for their bitflags type.
The caller of from_bits_unchecked()
has to ensure that
all bits correspond to a defined flag or that extra bits
are valid for this bitflags type.
-sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
-sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
-sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
-sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
+
sourcepub const fn intersects(&self, other: Self) -> bool
Returns true
if there are flags common to both self
and other
.
+sourcepub const fn contains(&self, other: Self) -> bool
Returns true
if all of the flags in other
are contained within self
.
+sourcepub fn set(&mut self, other: Self, value: bool)
Inserts or removes the specified flags depending on the passed value.
+sourcepub const fn intersection(self, other: Self) -> Self
Returns the intersection between the flags in self
and
other
.
Specifically, the returned set contains only the flags which are
present in both self
and other
.
This is equivalent to using the &
operator (e.g.
ops::BitAnd
), as in flags & other
.
-sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
+sourcepub const fn union(self, other: Self) -> Self
Returns the union of between the flags in self
and other
.
Specifically, the returned set contains all flags which are
present in either self
or other
, including any which are
-present in both (see Self::symmetric_difference
if that
+present in both (see Self::symmetric_difference
if that
is undesirable).
This is equivalent to using the |
operator (e.g.
ops::BitOr
), as in flags | other
.
-sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
+sourcepub const fn difference(self, other: Self) -> Self
Returns the difference between the flags in self
and other
.
Specifically, the returned set contains all flags present in
self
, except for the ones present in other
.
It is also conceptually equivalent to the “bit-clear” operation:
flags & !other
(and this syntax is also supported).
This is equivalent to using the -
operator (e.g.
ops::Sub
), as in flags - other
.
-sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
+
sourcepub const fn symmetric_difference(self, other: Self) -> Self
Returns the symmetric difference between the flags
in self
and other
.
Specifically, the returned set contains the flags present which
are present in self
or other
, but that are not present in
@@ -62,67 +56,40 @@ both. Equivalently, it contains the flags present in exactly
one of the sets self
and other
.
This is equivalent to using the ^
operator (e.g.
ops::BitXor
), as in flags ^ other
.
-sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
+sourcepub const fn complement(self) -> Self
Returns the complement of this set of flags.
Specifically, the returned set contains all the flags which are
not set in self
, but which are allowed for this type.
Alternatively, it can be thought of as the set difference
-between Self::all()
and self
(e.g. Self::all() - self
)
+between Self::all()
and self
(e.g. Self::all() - self
)
This is equivalent to using the !
operator (e.g.
ops::Not
), as in !flags
.
-Trait Implementations
sourceimpl Binary for MapPermission
sourceimpl BitAnd<MapPermission> for MapPermission
sourceimpl BitAndAssign<MapPermission> for MapPermission
sourcefn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
-sourceimpl BitOr<MapPermission> for MapPermission
sourcefn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
-type Output = Self
The resulting type after applying the |
operator.
-sourceimpl BitOrAssign<MapPermission> for MapPermission
sourcefn bitor_assign(&mut self, other: Self)
Adds the set of flags.
-sourceimpl BitXor<MapPermission> for MapPermission
sourceimpl BitXorAssign<MapPermission> for MapPermission
sourcefn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
-sourceimpl Clone for MapPermission
sourcefn clone(&self) -> MapPermission
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Debug for MapPermission
sourceimpl Extend<MapPermission> for MapPermission
sourcefn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read more
-sourcefn extend_one(&mut self, item: A)
🔬 This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.
-sourcefn extend_reserve(&mut self, additional: usize)
🔬 This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
-sourceimpl FromIterator<MapPermission> for MapPermission
sourcefn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read more
-sourceimpl Hash for MapPermission
sourceimpl LowerHex for MapPermission
sourceimpl Not for MapPermission
sourceimpl Octal for MapPermission
sourceimpl Ord for MapPermission
sourceimpl PartialEq<MapPermission> for MapPermission
sourcefn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
-sourcefn ne(&self, other: &MapPermission) -> bool
This method tests for !=
.
-sourceimpl PartialOrd<MapPermission> for MapPermission
sourcefn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
-1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
-1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
-sourceimpl Sub<MapPermission> for MapPermission
sourceimpl SubAssign<MapPermission> for MapPermission
sourcefn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
-sourceimpl UpperHex for MapPermission
sourceimpl Copy for MapPermission
sourceimpl Eq for MapPermission
sourceimpl StructuralEq for MapPermission
sourceimpl StructuralPartialEq for MapPermission
Auto Trait Implementations
impl RefUnwindSafe for MapPermission
impl Send for MapPermission
impl Sync for MapPermission
impl Unpin for MapPermission
impl UnwindSafe for MapPermission
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl Binary for MapPermission
source§impl BitAnd<MapPermission> for MapPermission
source§impl BitAndAssign<MapPermission> for MapPermission
source§fn bitand_assign(&mut self, other: Self)
Disables all flags disabled in the set.
+source§impl BitOr<MapPermission> for MapPermission
source§fn bitor(self, other: MapPermission) -> Self
Returns the union of the two sets of flags.
+§type Output = MapPermission
The resulting type after applying the |
operator.source§impl BitOrAssign<MapPermission> for MapPermission
source§fn bitor_assign(&mut self, other: Self)
Adds the set of flags.
+source§impl BitXor<MapPermission> for MapPermission
source§impl BitXorAssign<MapPermission> for MapPermission
source§fn bitxor_assign(&mut self, other: Self)
Toggles the set of flags.
+source§impl Clone for MapPermission
source§fn clone(&self) -> MapPermission
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Debug for MapPermission
source§impl Extend<MapPermission> for MapPermission
source§fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)
Extends a collection with the contents of an iterator. Read moresource§fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (extend_one
)Extends a collection with exactly one element.source§fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (extend_one
)Reserves capacity in a collection for the given number of additional elements. Read moresource§impl FromIterator<MapPermission> for MapPermission
source§fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self
Creates a value from an iterator. Read moresource§impl Hash for MapPermission
source§impl LowerHex for MapPermission
source§impl Not for MapPermission
source§impl Octal for MapPermission
source§impl Ord for MapPermission
source§fn cmp(&self, other: &MapPermission) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
+ Self: Sized,
Compares and returns the maximum of two values. Read moresource§impl PartialEq<MapPermission> for MapPermission
source§fn eq(&self, other: &MapPermission) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl PartialOrd<MapPermission> for MapPermission
source§fn partial_cmp(&self, other: &MapPermission) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
+operator. Read moresource§impl Sub<MapPermission> for MapPermission
source§impl SubAssign<MapPermission> for MapPermission
source§fn sub_assign(&mut self, other: Self)
Disables all flags enabled in the set.
+source§impl UpperHex for MapPermission
source§impl Copy for MapPermission
source§impl Eq for MapPermission
source§impl StructuralEq for MapPermission
source§impl StructuralPartialEq for MapPermission
Auto Trait Implementations§
§impl RefUnwindSafe for MapPermission
§impl Send for MapPermission
§impl Sync for MapPermission
§impl Unpin for MapPermission
§impl UnwindSafe for MapPermission
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct MemorySet {
+MemorySet in os::mm - Rust Expand description
memory set structure, controls virtual-memory space
-Fields
page_table: PageTable
areas: Vec<MapArea>
Implementations
sourceimpl MemorySet
sourcepub fn insert_framed_area(
&mut self,
start_va: VirtAddr,
end_va: VirtAddr,
permission: MapPermission
)
Assume that no conflicts.
-sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
-sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
-sourcepub fn new_kernel() -> Self
Without kernel stacks.
-sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
+}Expand description
memory set structure, controls virtual-memory space
+
Fields§
§page_table: PageTable
§areas: Vec<MapArea>
Implementations§
source§impl MemorySet
sourcepub fn insert_framed_area(
+ &mut self,
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ permission: MapPermission
+)
Assume that no conflicts.
+sourcepub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum)
Remove MapArea
that starts with start_vpn
+sourcefn push(&mut self, map_area: MapArea, data: Option<&[u8]>)
sourcefn map_trampoline(&mut self)
Mention that trampoline is not collected by areas.
+sourcepub fn new_kernel() -> Self
Without kernel stacks.
+sourcepub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize)
Include sections in elf and trampoline and TrapContext and user stack,
also returns user_sp and entry point.
-sourcepub fn from_existed_user(user_space: &MemorySet) -> MemorySet
Clone a same MemorySet
-sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
-sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
-Auto Trait Implementations
impl RefUnwindSafe for MemorySet
impl Send for MemorySet
impl Sync for MemorySet
impl Unpin for MemorySet
impl UnwindSafe for MemorySet
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
sourcepub fn from_existed_user(user_space: &MemorySet) -> MemorySet
Clone a same MemorySet
+sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate throuth pagetable
+sourcepub fn recycle_data_pages(&mut self)
Remove all MapArea
+Auto Trait Implementations§
§impl RefUnwindSafe for MemorySet
§impl Send for MemorySet
§impl Sync for MemorySet
§impl Unpin for MemorySet
§impl UnwindSafe for MemorySet
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PageTable {
+PageTable in os::mm - Rust pub struct PageTable {
root_ppn: PhysPageNum,
frames: Vec<FrameTracker>,
-}
Expand description
Record root ppn and has the same lifetime as 1 and 2 level PageTableEntry
-Fields
root_ppn: PhysPageNum
frames: Vec<FrameTracker>
Implementations
sourceimpl PageTable
Assume that it won’t oom when creating/mapping.
-sourcepub fn from_token(satp: usize) -> Self
Temporarily used to get arguments from user space.
-sourcefn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address, create a frame if not exist
-sourcefn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address
-sourcepub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags)
Create a mapping form vpn
to ppn
-sourcepub fn unmap(&mut self, vpn: VirtPageNum)
Delete a mapping form vpn
-sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate VirtPageNum
to PageTableEntry
-sourcepub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr>
Translate VirtAddr
to PhysAddr
-Auto Trait Implementations
impl RefUnwindSafe for PageTable
impl Send for PageTable
impl Sync for PageTable
impl Unpin for PageTable
impl UnwindSafe for PageTable
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Record root ppn and has the same lifetime as 1 and 2 level PageTableEntry
+Fields§
§root_ppn: PhysPageNum
§frames: Vec<FrameTracker>
Implementations§
source§impl PageTable
Assume that it won’t oom when creating/mapping.
+sourcepub fn from_token(satp: usize) -> Self
Temporarily used to get arguments from user space.
+sourcefn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address, create a frame if not exist
+sourcefn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry>
Find phsical address by virtual address
+sourcepub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags)
Create a mapping form vpn
to ppn
+sourcepub fn unmap(&mut self, vpn: VirtPageNum)
Delete a mapping form vpn
+sourcepub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry>
Translate VirtPageNum
to PageTableEntry
+sourcepub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr>
Translate VirtAddr
to PhysAddr
+Auto Trait Implementations§
§impl RefUnwindSafe for PageTable
§impl Send for PageTable
§impl Sync for PageTable
§impl Unpin for PageTable
§impl UnwindSafe for PageTable
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
#[repr(C)]pub struct PageTableEntry {
+PageTableEntry in os::mm - Rust Struct os::mm::PageTableEntry
source · #[repr(C)]pub struct PageTableEntry {
pub bits: usize,
-}
Expand description
page table entry structure
-Fields
bits: usize
PTE
-Implementations
sourceimpl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
-sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
-sourcepub fn executable(&self) -> bool
Check PTE executable
-Trait Implementations
sourceimpl Clone for PageTableEntry
sourcefn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl Copy for PageTableEntry
Auto Trait Implementations
impl RefUnwindSafe for PageTableEntry
impl Send for PageTableEntry
impl Sync for PageTableEntry
impl Unpin for PageTableEntry
impl UnwindSafe for PageTableEntry
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
page table entry structure
+Fields§
§bits: usize
PTE
+Implementations§
source§impl PageTableEntry
sourcepub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self
Create a PTE from ppn
+sourcepub fn ppn(&self) -> PhysPageNum
Return 44bit ppn
+sourcepub fn executable(&self) -> bool
Check PTE executable
+Trait Implementations§
source§impl Clone for PageTableEntry
source§fn clone(&self) -> PageTableEntry
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl Copy for PageTableEntry
Auto Trait Implementations§
§impl RefUnwindSafe for PageTableEntry
§impl Send for PageTableEntry
§impl Sync for PageTableEntry
§impl Unpin for PageTableEntry
§impl UnwindSafe for PageTableEntry
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
#[repr(C)]pub struct PhysAddr(pub usize);
Definitions
-0: usize
PhysAddr
->PhysPageNum
PhysAddr
->PhysPageNum
Get page offset
-Converts to this type from the input type.
-T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum} +
#[repr(C)]pub struct PhysAddr(pub usize);
Definitions
+0: usize
PhysAddr
->PhysPageNum
PhysAddr
->PhysPageNum
Get page offset
+Get reference to PhysAddr
value
Get mutable reference to PhysAddr
value
T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum} T -> usize: T.0 usize -> T: usize.into()
-This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+#[repr(C)]pub struct PhysPageNum(pub usize);
phiscal page number
-0: usize
Get PageTableEntry
on PhysPageNum
Get u8 array on PhysPageNum
Get Get mutable reference to PhysAddr
value on PhysPageNum
Returns a copy of the value. Read more
-Performs copy-assignment from source
. Read more
Converts to this type from the input type.
-Converts to this type from the input type.
-This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
This method tests for !=
.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
#[repr(C)]pub struct PhysPageNum(pub usize);
phiscal page number
+0: usize
Get PageTableEntry
on PhysPageNum
Get u8 array on PhysPageNum
Get Get mutable reference to PhysAddr
value on PhysPageNum
source
. Read moreself
and other
values to be equal, and is used
+by ==
.self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+pub struct UserBuffer {
- pub buffers: Vec<&'static mut [u8]>,
-}
Array of u8 slice that user communicate with os
-buffers: Vec<&'static mut [u8]>
U8 vec
-Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct UserBuffer {
+ pub buffers: Vec<&'static mut [u8]>,
+}
Array of u8 slice that user communicate with os
+buffers: Vec<&'static mut [u8]>
U8 vec
+From<T> for U
chooses to do.
+pub struct UserBufferIterator {
- buffers: Vec<&'static mut [u8]>,
+UserBufferIterator in os::mm - Rust Struct os::mm::UserBufferIterator
source · pub struct UserBufferIterator {
+ buffers: Vec<&'static mut [u8]>,
current_buffer: usize,
current_idx: usize,
-}
Expand description
Iterator of UserBuffer
-Fields
buffers: Vec<&'static mut [u8]>
current_buffer: usize
current_idx: usize
Trait Implementations
sourceimpl Iterator for UserBufferIterator
sourcefn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read more
-1.0.0 · sourcefn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more
-1.0.0 · sourcefn count(self) -> usize
Consumes the iterator, counting the number of iterations and returning it. Read more
-1.0.0 · sourcefn last(self) -> Option<Self::Item>
Consumes the iterator, returning the last element. Read more
-sourcefn advance_by(&mut self, n: usize) -> Result<(), usize>
🔬 This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more
-1.0.0 · sourcefn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more
-1.28.0 · sourcefn step_by(self, step: usize) -> StepBy<Self>
Creates an iterator starting at the same point, but stepping by
-the given amount at each iteration. Read more
-1.0.0 · sourcefn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more
-1.0.0 · sourcefn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter> where
U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read more
-sourcefn intersperse(self, separator: Self::Item) -> Intersperse<Self> where
Self::Item: Clone,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places a copy of separator
between adjacent
-items of the original iterator. Read more
-sourcefn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where
G: FnMut() -> Self::Item,
🔬 This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
-between adjacent items of the original iterator. Read more
-1.0.0 · sourcefn map<B, F>(self, f: F) -> Map<Self, F> where
F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
-element. Read more
-1.21.0 · sourcefn for_each<F>(self, f: F) where
F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more
-1.0.0 · sourcefn filter<P>(self, predicate: P) -> Filter<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
-should be yielded. Read more
-1.0.0 · sourcefn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more
-1.0.0 · sourcefn enumerate(self) -> Enumerate<Self>
Creates an iterator which gives the current iteration count as well as
-the next value. Read more
-1.0.0 · sourcefn peekable(self) -> Peekable<Self>
Creates an iterator which can use the peek
and peek_mut
methods
+}Expand description
Iterator of UserBuffer
+
Fields§
§buffers: Vec<&'static mut [u8]>
§current_buffer: usize
§current_idx: usize
Trait Implementations§
source§impl Iterator for UserBufferIterator
source§fn next(&mut self) -> Option<Self::Item>
Advances the iterator and returns the next value. Read moresource§fn next_chunk<const N: usize>(
+ &mut self
+) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_next_chunk
)Advances the iterator and returns an array containing the next N
values. Read more1.0.0 · source§fn size_hint(&self) -> (usize, Option<usize>)
Returns the bounds on the remaining length of the iterator. Read more1.0.0 · source§fn count(self) -> usizewhere
+ Self: Sized,
Consumes the iterator, counting the number of iterations and returning it. Read more1.0.0 · source§fn last(self) -> Option<Self::Item>where
+ Self: Sized,
Consumes the iterator, returning the last element. Read moresource§fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>
🔬This is a nightly-only experimental API. (iter_advance_by
)Advances the iterator by n
elements. Read more1.0.0 · source§fn nth(&mut self, n: usize) -> Option<Self::Item>
Returns the n
th element of the iterator. Read more1.28.0 · source§fn step_by(self, step: usize) -> StepBy<Self>where
+ Self: Sized,
Creates an iterator starting at the same point, but stepping by
+the given amount at each iteration. Read more1.0.0 · source§fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator<Item = Self::Item>,
Takes two iterators and creates a new iterator over both in sequence. Read more1.0.0 · source§fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where
+ Self: Sized,
+ U: IntoIterator,
‘Zips up’ two iterators into a single iterator of pairs. Read moresource§fn intersperse(self, separator: Self::Item) -> Intersperse<Self>where
+ Self: Sized,
+ Self::Item: Clone,
🔬This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places a copy of separator
between adjacent
+items of the original iterator. Read moresource§fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where
+ Self: Sized,
+ G: FnMut() -> Self::Item,
🔬This is a nightly-only experimental API. (iter_intersperse
)Creates a new iterator which places an item generated by separator
+between adjacent items of the original iterator. Read more1.0.0 · source§fn map<B, F>(self, f: F) -> Map<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> B,
Takes a closure and creates an iterator which calls that closure on each
+element. Read more1.21.0 · source§fn for_each<F>(self, f: F)where
+ Self: Sized,
+ F: FnMut(Self::Item),
Calls a closure on each element of an iterator. Read more1.0.0 · source§fn filter<P>(self, predicate: P) -> Filter<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator which uses a closure to determine if an element
+should be yielded. Read more1.0.0 · source§fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both filters and maps. Read more1.0.0 · source§fn enumerate(self) -> Enumerate<Self>where
+ Self: Sized,
Creates an iterator which gives the current iteration count as well as
+the next value. Read more1.0.0 · sourcefn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
1.0.0 · sourcefn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more
-1.57.0 · sourcefn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where
P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more
-1.0.0 · sourcefn skip(self, n: usize) -> Skip<Self>
Creates an iterator that skips the first n
elements. Read more
-1.0.0 · sourcefn take(self, n: usize) -> Take<Self>
Creates an iterator that yields the first n
elements, or fewer
-if the underlying iterator ends sooner. Read more
-1.0.0 · sourcefn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where
F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · sourcefn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where
U: IntoIterator,
F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read more
-1.29.0 · sourcefn flatten(self) -> Flatten<Self> where
Self::Item: IntoIterator,
Creates an iterator that flattens nested structure. Read more
-1.0.0 · sourcefn inspect<F>(self, f: F) -> Inspect<Self, F> where
F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more
-1.0.0 · sourcefn by_ref(&mut self) -> &mut Self
Borrows an iterator, rather than consuming it. Read more
-1.0.0 · sourcefn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
Transforms an iterator into a collection. Read more
-sourcefn try_collect<B>(
&mut self
) -> <<Self::Item as Try>::Residual as Residual<B>>::TryType where
B: FromIterator<<Self::Item as Try>::Output>,
Self::Item: Try,
<Self::Item as Try>::Residual: Residual<B>,
🔬 This is a nightly-only experimental API. (iterator_try_collect
)Fallibly transforms an iterator into a collection, short circuiting if
-a failure is encountered. Read more
-sourcefn collect_into<E>(self, collection: &mut E) -> &mut E where
E: Extend<Self::Item>,
🔬 This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more
-1.0.0 · sourcefn partition<B, F>(self, f: F) -> (B, B) where
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read more
-sourcefn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
🔬 This is a nightly-only experimental API. (iter_partition_in_place
)Reorders the elements of this iterator in-place according to the given predicate,
-such that all those that return true
precede all those that return false
.
-Returns the number of true
elements found. Read more
-sourcefn is_partitioned<P>(self, predicate: P) -> bool where
P: FnMut(Self::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
-such that all those that return true
precede all those that return false
. Read more
-1.27.0 · sourcefn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
An iterator method that applies a function as long as it returns
-successfully, producing a single, final value. Read more
-1.27.0 · sourcefn try_for_each<F, R>(&mut self, f: F) -> R where
F: FnMut(Self::Item) -> R,
R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
-iterator, stopping at the first error and returning that error. Read more
-1.0.0 · sourcefn fold<B, F>(self, init: B, f: F) -> B where
F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
-returning the final result. Read more
-1.51.0 · sourcefn reduce<F>(self, f: F) -> Option<Self::Item> where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
-operation. Read more
-sourcefn try_reduce<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType where
F: FnMut(Self::Item, Self::Item) -> R,
R: Try<Output = Self::Item>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
-closure returns a failure, the failure is propagated back to the caller immediately. Read more
-1.0.0 · sourcefn all<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn any<F>(&mut self, f: F) -> bool where
F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more
-1.0.0 · sourcefn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more
-1.30.0 · sourcefn find_map<B, F>(&mut self, f: F) -> Option<B> where
F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
-the first non-none result. Read more
-sourcefn try_find<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType where
F: FnMut(&Self::Item) -> R,
R: Try<Output = bool>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
🔬 This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
-the first true result or the first error. Read more
-1.0.0 · sourcefn position<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more
-1.0.0 · sourcefn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
Searches for an element in an iterator from the right, returning its
-index. Read more
-1.0.0 · sourcefn max(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the maximum element of an iterator. Read more
-1.0.0 · sourcefn min(self) -> Option<Self::Item> where
Self::Item: Ord,
Returns the minimum element of an iterator. Read more
-1.6.0 · sourcefn max_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
-specified function. Read more
-1.15.0 · sourcefn max_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
-specified comparison function. Read more
-1.6.0 · sourcefn min_by_key<B, F>(self, f: F) -> Option<Self::Item> where
B: Ord,
F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
-specified function. Read more
-1.15.0 · sourcefn min_by<F>(self, compare: F) -> Option<Self::Item> where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
-specified comparison function. Read more
-1.0.0 · sourcefn rev(self) -> Rev<Self> where
Self: DoubleEndedIterator,
Reverses an iterator’s direction. Read more
-1.0.0 · sourcefn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more
-1.36.0 · sourcefn copied<'a, T>(self) -> Copied<Self> where
T: 'a + Copy,
Self: Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more
-1.0.0 · sourcefn cloned<'a, T>(self) -> Cloned<Self> where
T: 'a + Clone,
Self: Iterator<Item = &'a T>,
1.0.0 · sourcefn cycle(self) -> Cycle<Self> where
Self: Clone,
Repeats an iterator endlessly. Read more
-1.11.0 · sourcefn sum<S>(self) -> S where
S: Sum<Self::Item>,
Sums the elements of an iterator. Read more
-1.11.0 · sourcefn product<P>(self) -> P where
P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read more
-1.5.0 · sourcefn cmp<I>(self, other: I) -> Ordering where
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Lexicographically compares the elements of this Iterator
with those
-of another. Read more
-sourcefn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
-of another with respect to the specified comparison function. Read more
-1.5.0 · sourcefn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
sourcefn eq_by<I, F>(self, other: I, eq: F) -> bool where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬 This is a nightly-only experimental API. (iter_order_by
)1.5.0 · sourcefn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0 · sourcefn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less than those of another. Read more
-1.5.0 · sourcefn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-less or equal to those of another. Read more
-1.5.0 · sourcefn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than those of another. Read more
-1.5.0 · sourcefn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
Determines if the elements of this Iterator
are lexicographically
-greater than or equal to those of another. Read more
-sourcefn is_sorted(self) -> bool where
Self::Item: PartialOrd<Self::Item>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted. Read more
-sourcefn is_sorted_by<F>(self, compare: F) -> bool where
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read more
-sourcefn is_sorted_by_key<F, K>(self, f: F) -> bool where
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
🔬 This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
-function. Read more
-Auto Trait Implementations
impl RefUnwindSafe for UserBufferIterator
impl Send for UserBufferIterator
impl Sync for UserBufferIterator
impl Unpin for UserBufferIterator
impl !UnwindSafe for UserBufferIterator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+their documentation for more information. Read more1.0.0 · source§fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
1.0.0 · source§fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Creates an iterator that yields elements based on a predicate. Read more1.57.0 · source§fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> Option<B>,
Creates an iterator that both yields elements based on a predicate and maps. Read more1.0.0 · source§fn skip(self, n: usize) -> Skip<Self>where
+ Self: Sized,
Creates an iterator that skips the first n
elements. Read more1.0.0 · source§fn take(self, n: usize) -> Take<Self>where
+ Self: Sized,
Creates an iterator that yields the first n
elements, or fewer
+if the underlying iterator ends sooner. Read more1.0.0 · source§fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where
+ Self: Sized,
+ F: FnMut(&mut St, Self::Item) -> Option<B>,
1.0.0 · source§fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where
+ Self: Sized,
+ U: IntoIterator,
+ F: FnMut(Self::Item) -> U,
Creates an iterator that works like map, but flattens nested structure. Read moresource§fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where
+ Self: Sized,
+ F: FnMut(&[Self::Item; N]) -> R,
🔬This is a nightly-only experimental API. (iter_map_windows
)Calls the given function f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read more1.0.0 · source§fn inspect<F>(self, f: F) -> Inspect<Self, F>where
+ Self: Sized,
+ F: FnMut(&Self::Item),
Does something with each element of an iterator, passing the value on. Read more1.0.0 · source§fn by_ref(&mut self) -> &mut Selfwhere
+ Self: Sized,
Borrows an iterator, rather than consuming it. Read more1.0.0 · source§fn collect<B>(self) -> Bwhere
+ B: FromIterator<Self::Item>,
+ Self: Sized,
Transforms an iterator into a collection. Read moresource§fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere
+ E: Extend<Self::Item>,
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_collect_into
)Collects all the items from an iterator into a collection. Read more1.0.0 · source§fn partition<B, F>(self, f: F) -> (B, B)where
+ Self: Sized,
+ B: Default + Extend<Self::Item>,
+ F: FnMut(&Self::Item) -> bool,
Consumes an iterator, creating two collections from it. Read moresource§fn is_partitioned<P>(self, predicate: P) -> boolwhere
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_is_partitioned
)Checks if the elements of this iterator are partitioned according to the given predicate,
+such that all those that return true
precede all those that return false
. Read more1.27.0 · source§fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> R,
+ R: Try<Output = B>,
An iterator method that applies a function as long as it returns
+successfully, producing a single, final value. Read more1.27.0 · source§fn try_for_each<F, R>(&mut self, f: F) -> Rwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> R,
+ R: Try<Output = ()>,
An iterator method that applies a fallible function to each item in the
+iterator, stopping at the first error and returning that error. Read more1.0.0 · source§fn fold<B, F>(self, init: B, f: F) -> Bwhere
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
Folds every element into an accumulator by applying an operation,
+returning the final result. Read more1.51.0 · source§fn reduce<F>(self, f: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> Self::Item,
Reduces the elements to a single one, by repeatedly applying a reducing
+operation. Read moresource§fn try_reduce<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> R,
+ R: Try<Output = Self::Item>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (iterator_try_reduce
)Reduces the elements to a single one by repeatedly applying a reducing operation. If the
+closure returns a failure, the failure is propagated back to the caller immediately. Read more1.0.0 · source§fn all<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if every element of the iterator matches a predicate. Read more1.0.0 · source§fn any<F>(&mut self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> bool,
Tests if any element of the iterator matches a predicate. Read more1.0.0 · source§fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
Searches for an element of an iterator that satisfies a predicate. Read more1.30.0 · source§fn find_map<B, F>(&mut self, f: F) -> Option<B>where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Option<B>,
Applies function to the elements of iterator and returns
+the first non-none result. Read moresource§fn try_find<F, R>(
+ &mut self,
+ f: F
+) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere
+ Self: Sized,
+ F: FnMut(&Self::Item) -> R,
+ R: Try<Output = bool>,
+ <R as Try>::Residual: Residual<Option<Self::Item>>,
🔬This is a nightly-only experimental API. (try_find
)Applies function to the elements of iterator and returns
+the first true result or the first error. Read more1.0.0 · source§fn position<P>(&mut self, predicate: P) -> Option<usize>where
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
Searches for an element in an iterator, returning its index. Read more1.0.0 · source§fn max(self) -> Option<Self::Item>where
+ Self: Sized,
+ Self::Item: Ord,
Returns the maximum element of an iterator. Read more1.0.0 · source§fn min(self) -> Option<Self::Item>where
+ Self: Sized,
+ Self::Item: Ord,
Returns the minimum element of an iterator. Read more1.6.0 · source§fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the maximum value from the
+specified function. Read more1.15.0 · source§fn max_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the maximum value with respect to the
+specified comparison function. Read more1.6.0 · source§fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where
+ B: Ord,
+ Self: Sized,
+ F: FnMut(&Self::Item) -> B,
Returns the element that gives the minimum value from the
+specified function. Read more1.15.0 · source§fn min_by<F>(self, compare: F) -> Option<Self::Item>where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Returns the element that gives the minimum value with respect to the
+specified comparison function. Read more1.0.0 · source§fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where
+ FromA: Default + Extend<A>,
+ FromB: Default + Extend<B>,
+ Self: Sized + Iterator<Item = (A, B)>,
Converts an iterator of pairs into a pair of containers. Read more1.36.0 · source§fn copied<'a, T>(self) -> Copied<Self>where
+ T: 'a + Copy,
+ Self: Sized + Iterator<Item = &'a T>,
Creates an iterator which copies all of its elements. Read more1.0.0 · source§fn cloned<'a, T>(self) -> Cloned<Self>where
+ T: 'a + Clone,
+ Self: Sized + Iterator<Item = &'a T>,
source§fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where
+ Self: Sized,
🔬This is a nightly-only experimental API. (iter_array_chunks
)Returns an iterator over N
elements of the iterator at a time. Read more1.11.0 · source§fn sum<S>(self) -> Swhere
+ Self: Sized,
+ S: Sum<Self::Item>,
Sums the elements of an iterator. Read more1.11.0 · source§fn product<P>(self) -> Pwhere
+ Self: Sized,
+ P: Product<Self::Item>,
Iterates over the entire iterator, multiplying all the elements Read more1.5.0 · source§fn cmp<I>(self, other: I) -> Orderingwhere
+ I: IntoIterator<Item = Self::Item>,
+ Self::Item: Ord,
+ Self: Sized,
source§fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn partial_cmp<I>(self, other: I) -> Option<Ordering>where
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Lexicographically compares the PartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moresource§fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (iter_order_by
)Lexicographically compares the elements of this Iterator
with those
+of another with respect to the specified comparison function. Read more1.5.0 · source§fn eq<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
source§fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere
+ Self: Sized,
+ I: IntoIterator,
+ F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
🔬This is a nightly-only experimental API. (iter_order_by
)1.5.0 · source§fn ne<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialEq<<I as IntoIterator>::Item>,
+ Self: Sized,
1.5.0 · source§fn lt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less than those of another. Read more1.5.0 · source§fn le<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+less or equal to those of another. Read more1.5.0 · source§fn gt<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than those of another. Read more1.5.0 · source§fn ge<I>(self, other: I) -> boolwhere
+ I: IntoIterator,
+ Self::Item: PartialOrd<<I as IntoIterator>::Item>,
+ Self: Sized,
Determines if the elements of this Iterator
are lexicographically
+greater than or equal to those of another. Read moresource§fn is_sorted(self) -> boolwhere
+ Self: Sized,
+ Self::Item: PartialOrd<Self::Item>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted. Read moresource§fn is_sorted_by<F>(self, compare: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given comparator function. Read moresource§fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere
+ Self: Sized,
+ F: FnMut(Self::Item) -> K,
+ K: PartialOrd<K>,
🔬This is a nightly-only experimental API. (is_sorted
)Checks if the elements of this iterator are sorted using the given key extraction
+function. Read moreAuto Trait Implementations§
§impl RefUnwindSafe for UserBufferIterator
§impl Send for UserBufferIterator
§impl Sync for UserBufferIterator
§impl Unpin for UserBufferIterator
§impl !UnwindSafe for UserBufferIterator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<I> IntoIterator for I where
I: Iterator,
-
\ No newline at end of file
+From<T> for U
chooses to do.
+source§impl<I> IntoIterator for Iwhere
+ I: Iterator,
#[repr(C)]pub struct VirtAddr(pub usize);
virtual address
-0: usize
VirtAddr
->VirtPageNum
VirtAddr
->VirtPageNum
Get page offset
-Converts to this type from the input type.
-This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
#[repr(C)]pub struct VirtAddr(pub usize);
virtual address
+0: usize
VirtAddr
->VirtPageNum
VirtAddr
->VirtPageNum
Get page offset
+self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+#[repr(C)]pub struct VirtPageNum(pub usize);
virtual page number
-0: usize
Returns a copy of the value. Read more
-Performs copy-assignment from source
. Read more
Converts to this type from the input type.
-Converts to this type from the input type.
-This method tests for self
and other
values to be equal, and is used
-by ==
. Read more
This method tests for !=
.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
-operator. Read more
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
#[repr(C)]pub struct VirtPageNum(pub usize);
virtual page number
+0: usize
source
. Read moreself
and other
values to be equal, and is used
+by ==
.self
and other
) and is used by the <=
+operator. Read moreThe resulting type after obtaining ownership.
-toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-From<T> for U
chooses to do.
+pub fn console_getchar() -> usize
use sbi call to getchar from console (qemu uart handler)
+pub fn console_putchar(c: usize)
use sbi call to putchar in console (qemu uart handler)
+SBI call wrappers
+pub struct RawExclusiveLock(AtomicBool);
The sync primitive used by easy-fs.
+0: AtomicBool
Send
. Use
+one of the GuardSend
or GuardNoSend
helper types here.pub struct UPSafeCell<T> {
+UPSafeCell in os::sync - Rust Struct os::sync::UPSafeCell
source · pub struct UPSafeCell<T> {
inner: RefCell<T>,
-}
Expand description
Wrap a static data structure inside it so that we are
+}Expand description
Wrap a static data structure inside it so that we are
able to access it without any unsafe
.
We should only use it in uniprocessor.
In order to get mutable reference of inner data, call
exclusive_access
.
-
Fields
inner: RefCell<T>
inner data
-Implementations
sourceimpl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
+
Fields§
§inner: RefCell<T>
inner data
+Implementations§
source§impl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
uniprocessor.
-sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl<T> Sync for UPSafeCell<T>
Auto Trait Implementations
impl<T> !RefUnwindSafe for UPSafeCell<T>
impl<T> Send for UPSafeCell<T> where
T: Send,
impl<T> Unpin for UPSafeCell<T> where
T: Unpin,
impl<T> UnwindSafe for UPSafeCell<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl<T> Sync for UPSafeCell<T>
Auto Trait Implementations§
§impl<T> !RefUnwindSafe for UPSafeCell<T>
§impl<T> Send for UPSafeCell<T>where
+ T: Send,
§impl<T> Unpin for UPSafeCell<T>where
+ T: Unpin,
§impl<T> UnwindSafe for UPSafeCell<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
Uniprocessor interior mutability primitives
+unsafe
.pub struct RawExclusiveLock(AtomicBool);
The sync primitive used by easy-fs.
+0: AtomicBool
Send
. Use
+one of the GuardSend
or GuardNoSend
helper types here.pub struct UPSafeCell<T> {
+UPSafeCell in os::sync::up - Rust Expand description
Wrap a static data structure inside it so that we are
+}Expand description
Wrap a static data structure inside it so that we are
able to access it without any unsafe
.
We should only use it in uniprocessor.
In order to get mutable reference of inner data, call
exclusive_access
.
-
Fields
inner: RefCell<T>
inner data
-Implementations
sourceimpl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
+
Fields§
§inner: RefCell<T>
inner data
+Implementations§
source§impl<T> UPSafeCell<T>
sourcepub unsafe fn new(value: T) -> Self
User is responsible to guarantee that inner struct is only used in
uniprocessor.
-sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl<T> Sync for UPSafeCell<T>
Auto Trait Implementations
impl<T> !RefUnwindSafe for UPSafeCell<T>
impl<T> Send for UPSafeCell<T> where
T: Send,
impl<T> Unpin for UPSafeCell<T> where
T: Unpin,
impl<T> UnwindSafe for UPSafeCell<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-Trait Implementations§
source§impl<T> Sync for UPSafeCell<T>
Auto Trait Implementations§
§impl<T> !RefUnwindSafe for UPSafeCell<T>
§impl<T> Send for UPSafeCell<T>where
+ T: Send,
§impl<T> Unpin for UPSafeCell<T>where
+ T: Unpin,
§impl<T> UnwindSafe for UPSafeCell<T>where
+ T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
const SYSCALL_CLOSE: usize = 57;
const SYSCALL_EXEC: usize = 221;
const SYSCALL_EXIT: usize = 93;
const SYSCALL_FORK: usize = 220;
const SYSCALL_GETPID: usize = 172;
const SYSCALL_GET_TIME: usize = 169;
const SYSCALL_OPEN: usize = 56;
const SYSCALL_READ: usize = 63;
const SYSCALL_WAITPID: usize = 260;
const SYSCALL_WRITE: usize = 64;
const SYSCALL_YIELD: usize = 124;
Implementation of syscalls
-The single entry point to all system calls, syscall()
, is called
+
Implementation of syscalls
+The single entry point to all system calls, syscall()
, is called
whenever userspace wishes to perform a system call using the ecall
instruction. In this case, the processor raises an ‘Environment call from
U-mode’ exception, which is handled as one of the cases in
-crate::trap::trap_handler
.
crate::trap::trap_handler
.
For clarity, each single syscall is implemented as its own function, named
sys_
then the name of the syscall. You can find functions like this in
submodules, and you should also implement syscalls this way.
handle syscall exception with syscall_id
and other arguments
syscall_id
and other argumentsIf there is not a child process whose pid is same as given, return -1. +
If there is not a child process whose pid is same as given, return -1. -Else if there is a child process but it is still running, return -2.
-Implementation of TaskContext
task context structure containing some registers
-Implementation of TaskContext
#[repr(C)]pub struct TaskContext {
+TaskContext in os::task::context - Rust Struct os::task::context::TaskContext
source · #[repr(C)]pub struct TaskContext {
ra: usize,
sp: usize,
- s: [usize; 12],
-}
Expand description
task context structure containing some registers
-Fields
ra: usize
return address ( e.g. __restore ) of __switch ASM function
-sp: usize
kernel stack pointer of app
-s: [usize; 12]
s0-11 register, callee saved
-Implementations
sourceimpl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
-Auto Trait Implementations
impl RefUnwindSafe for TaskContext
impl Send for TaskContext
impl Sync for TaskContext
impl Unpin for TaskContext
impl UnwindSafe for TaskContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+ s: [usize; 12],
+}Expand description
task context structure containing some registers
+Fields§
§ra: usize
return address ( e.g. __restore ) of __switch ASM function
+§sp: usize
kernel stack pointer of app
+§s: [usize; 12]
s0-11 register, callee saved
+Implementations§
source§impl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
+Auto Trait Implementations§
§impl RefUnwindSafe for TaskContext
§impl Send for TaskContext
§impl Sync for TaskContext
§impl Unpin for TaskContext
§impl UnwindSafe for TaskContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub fn add_initproc()
Add init process to the manager
-pub fn add_initproc()
Add init process to the manager
+pub fn current_task() -> Option<Arc<TaskControlBlock>>
Get running task
-pub fn current_task() -> Option<Arc<TaskControlBlock>>
Get running task
+pub fn current_trap_cx() -> &'static mut TrapContext
Get the mutable reference to trap context of current task
-pub fn current_trap_cx() -> &'static mut TrapContext
Get the mutable reference to trap context of current task
+pub fn current_user_token() -> usize
Get token of the address space of current task
+pub fn exit_current_and_run_next(exit_code: i32)
Exit the current ‘Running’ task and run the next task in task list.
+pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Interface offered to pop the first task
-pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Interface offered to pop the first task
+pub fn run_tasks()
The main part of process execution and scheduling +
pub fn suspend_current_and_run_next()
Suspend the current ‘Running’ task and run the next task in task list.
-pub fn suspend_current_and_run_next()
Suspend the current ‘Running’ task and run the next task in task list.
+pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Take the current task,leaving a None in its place
-pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Take the current task,leaving a None in its place
+Task management implementation
+Task management implementation
Everything about task management, like starting and switching tasks is implemented here.
-A single global instance of TaskManager
called TASK_MANAGER
controls
+
A single global instance of TaskManager
called TASK_MANAGER
controls
all the tasks in the whole operating system.
A single global instance of Processor
called PROCESSOR
monitors running
+
A single global instance of Processor
called PROCESSOR
monitors running
task(s) for each core.
A single global instance of PidAllocator
called PID_ALLOCATOR
allocates
+
A single global instance of PidAllocator
called PID_ALLOCATOR
allocates
pid for user apps.
Be careful when you see __switch
ASM function in switch.S
. Control flow around this function
might not be what you expect.
Implementation of TaskContext
Implementation of TaskManager
Implementation of PidAllocator
Wrap switch.S
as a function
Implementation of TaskControlBlock
Globle process that init user shell
-Kernelstack for app
-Pid Allocator struct
-Bind pid lifetime to PidHandle
Processor management structure
-task context structure containing some registers
-A array of TaskControlBlock
that is thread-safe
pid of usertests app in make run TEST=1
-Add init process to the manager
-Interface offered to add task
-Get running task
-Get the mutable reference to trap context of current task
-Get token of the address space of current task
-Exit the current ‘Running’ task and run the next task in task list.
-Interface offered to pop the first task
-Allocate a pid from PID_ALLOCATOR
-The main part of process execution and scheduling
-Loop fetch_task
to get the process that needs to run, and switch the process through __switch
Return to idle control flow for new scheduling
-Suspend the current ‘Running’ task and run the next task in task list.
-Take the current task,leaving a None in its place
-TaskContext
TaskManager
PidAllocator
Processor
and Intersection of control flowswitch.S
as a functionTaskControlBlock
PidHandle
TaskControlBlock
that is thread-safefetch_task
to get the process that needs to run, and switch the process through __switch
pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Interface offered to pop the first task
-pub fn fetch_task() -> Option<Arc<TaskControlBlock>>
Interface offered to pop the first task
+Implementation of TaskManager
A array of TaskControlBlock
that is thread-safe
Interface offered to add task
-Interface offered to pop the first task
-Implementation of TaskManager
TaskControlBlock
that is thread-safepub struct TASK_MANAGER {
+TASK_MANAGER in os::task::manager - Rust Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<TaskManager>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for TASK_MANAGER
type Target = UPSafeCell<TaskManager>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<TaskManager>
Dereferences the value.
-sourceimpl LazyStatic for TASK_MANAGER
Auto Trait Implementations
impl RefUnwindSafe for TASK_MANAGER
impl Send for TASK_MANAGER
impl Sync for TASK_MANAGER
impl Unpin for TASK_MANAGER
impl UnwindSafe for TASK_MANAGER
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<TaskManager>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for TASK_MANAGER
§type Target = UPSafeCell<TaskManager>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<TaskManager>
Dereferences the value.source§impl LazyStatic for TASK_MANAGER
Auto Trait Implementations§
§impl RefUnwindSafe for TASK_MANAGER
§impl Send for TASK_MANAGER
§impl Sync for TASK_MANAGER
§impl Unpin for TASK_MANAGER
§impl UnwindSafe for TASK_MANAGER
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct TaskManager {
+TaskManager in os::task::manager - Rust Struct os::task::manager::TaskManager
source · pub struct TaskManager {
ready_queue: VecDeque<Arc<TaskControlBlock>>,
-}
Expand description
A array of TaskControlBlock
that is thread-safe
-Fields
ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations
sourceimpl TaskManager
A simple FIFO scheduler.
-Auto Trait Implementations
impl !RefUnwindSafe for TaskManager
impl Send for TaskManager
impl Sync for TaskManager
impl Unpin for TaskManager
impl !UnwindSafe for TaskManager
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
A array of TaskControlBlock
that is thread-safe
+Fields§
§ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations§
source§impl TaskManager
A simple FIFO scheduler.
+Auto Trait Implementations§
§impl !RefUnwindSafe for TaskManager
§impl Send for TaskManager
§impl Sync for TaskManager
§impl Unpin for TaskManager
§impl !UnwindSafe for TaskManager
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
Implementation of PidAllocator
Kernelstack for app
-Pid Allocator struct
-Bind pid lifetime to PidHandle
Return (bottom, top) of a kernel stack in kernel space.
-Allocate a pid from PID_ALLOCATOR
-Implementation of PidAllocator
PidHandle
pub struct KernelStack {
+KernelStack in os::task::pid - Rust Expand description
Kernelstack for app
-Fields
pid: usize
Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for KernelStack
impl Send for KernelStack
impl Sync for KernelStack
impl Unpin for KernelStack
impl UnwindSafe for KernelStack
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Kernelstack for app
+Fields§
§pid: usize
Implementations§
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for KernelStack
§impl Send for KernelStack
§impl Sync for KernelStack
§impl Unpin for KernelStack
§impl UnwindSafe for KernelStack
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PID_ALLOCATOR {
+PID_ALLOCATOR in os::task::pid - Rust Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<PidAllocator>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for PID_ALLOCATOR
type Target = UPSafeCell<PidAllocator>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<PidAllocator>
Dereferences the value.
-sourceimpl LazyStatic for PID_ALLOCATOR
Auto Trait Implementations
impl RefUnwindSafe for PID_ALLOCATOR
impl Send for PID_ALLOCATOR
impl Sync for PID_ALLOCATOR
impl Unpin for PID_ALLOCATOR
impl UnwindSafe for PID_ALLOCATOR
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<PidAllocator>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for PID_ALLOCATOR
§type Target = UPSafeCell<PidAllocator>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<PidAllocator>
Dereferences the value.source§impl LazyStatic for PID_ALLOCATOR
Auto Trait Implementations§
§impl RefUnwindSafe for PID_ALLOCATOR
§impl Send for PID_ALLOCATOR
§impl Sync for PID_ALLOCATOR
§impl Unpin for PID_ALLOCATOR
§impl UnwindSafe for PID_ALLOCATOR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PidAllocator {
+PidAllocator in os::task::pid - Rust Struct os::task::pid::PidAllocator
source · pub struct PidAllocator {
current: usize,
recycled: Vec<usize>,
-}
Expand description
Pid Allocator struct
-Fields
current: usize
recycled: Vec<usize>
Implementations
Auto Trait Implementations
impl RefUnwindSafe for PidAllocator
impl Send for PidAllocator
impl Sync for PidAllocator
impl Unpin for PidAllocator
impl UnwindSafe for PidAllocator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Pid Allocator struct
+Fields§
§current: usize
§recycled: Vec<usize>
Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for PidAllocator
§impl Send for PidAllocator
§impl Sync for PidAllocator
§impl Unpin for PidAllocator
§impl UnwindSafe for PidAllocator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PidHandle(pub usize);
Bind pid lifetime to PidHandle
0: usize
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct PidHandle(pub usize);
Bind pid lifetime to PidHandle
0: usize
From<T> for U
chooses to do.
+pub fn current_task() -> Option<Arc<TaskControlBlock>>
Get running task
-pub fn current_task() -> Option<Arc<TaskControlBlock>>
Get running task
+pub fn current_trap_cx() -> &'static mut TrapContext
Get the mutable reference to trap context of current task
-pub fn current_trap_cx() -> &'static mut TrapContext
Get the mutable reference to trap context of current task
+pub fn run_tasks()
The main part of process execution and scheduling +
pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Take the current task,leaving a None in its place
-pub fn take_current_task() -> Option<Arc<TaskControlBlock>>
Take the current task,leaving a None in its place
+Implementation of Processor
and Intersection of control flow
Get running task
-Get the mutable reference to trap context of current task
-Get token of the address space of current task
-The main part of process execution and scheduling
-Loop fetch_task
to get the process that needs to run, and switch the process through __switch
Return to idle control flow for new scheduling
-Take the current task,leaving a None in its place
-Implementation of Processor
and Intersection of control flow
fetch_task
to get the process that needs to run, and switch the process through __switch
pub struct PROCESSOR {
+PROCESSOR in os::task::processor - Rust Fields
__private_field: ()
Methods from Deref<Target = UPSafeCell<Processor>>
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
-Trait Implementations
sourceimpl Deref for PROCESSOR
type Target = UPSafeCell<Processor>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &UPSafeCell<Processor>
Dereferences the value.
-sourceimpl LazyStatic for PROCESSOR
Auto Trait Implementations
impl RefUnwindSafe for PROCESSOR
impl Send for PROCESSOR
impl Sync for PROCESSOR
impl Unpin for PROCESSOR
impl UnwindSafe for PROCESSOR
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§__private_field: ()
Methods from Deref<Target = UPSafeCell<Processor>>§
sourcepub fn exclusive_access(&self) -> RefMut<'_, T>
Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+Trait Implementations§
source§impl Deref for PROCESSOR
§type Target = UPSafeCell<Processor>
The resulting type after dereferencing.source§fn deref(&self) -> &UPSafeCell<Processor>
Dereferences the value.source§impl LazyStatic for PROCESSOR
Auto Trait Implementations§
§impl RefUnwindSafe for PROCESSOR
§impl Send for PROCESSOR
§impl Sync for PROCESSOR
§impl Unpin for PROCESSOR
§impl UnwindSafe for PROCESSOR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct Processor {
+Processor in os::task::processor - Rust pub struct Processor {
current: Option<Arc<TaskControlBlock>>,
idle_task_cx: TaskContext,
-}
Expand description
Processor management structure
-Fields
current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
-idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
-Implementations
sourceimpl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
-sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
-sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
-Auto Trait Implementations
impl !RefUnwindSafe for Processor
impl Send for Processor
impl Sync for Processor
impl Unpin for Processor
impl !UnwindSafe for Processor
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Processor management structure
+Fields§
§current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
+§idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
+Implementations§
source§impl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
+sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
+sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
+Auto Trait Implementations§
§impl !RefUnwindSafe for Processor
§impl Send for Processor
§impl Sync for Processor
§impl Unpin for Processor
§impl !UnwindSafe for Processor
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct INITPROC {
+INITPROC in os::task - Rust Expand description
Globle process that init user shell
-Fields
__private_field: ()
Trait Implementations
sourceimpl Deref for INITPROC
type Target = Arc<TaskControlBlock>
The resulting type after dereferencing.
-sourcefn deref(&self) -> &Arc<TaskControlBlock>
Dereferences the value.
-sourceimpl LazyStatic for INITPROC
Auto Trait Implementations
impl RefUnwindSafe for INITPROC
impl Send for INITPROC
impl Sync for INITPROC
impl Unpin for INITPROC
impl UnwindSafe for INITPROC
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Globle process that init user shell
+Fields§
§__private_field: ()
Trait Implementations§
source§impl Deref for INITPROC
§type Target = Arc<TaskControlBlock, Global>
The resulting type after dereferencing.source§fn deref(&self) -> &Arc<TaskControlBlock>
Dereferences the value.source§impl LazyStatic for INITPROC
Auto Trait Implementations§
§impl RefUnwindSafe for INITPROC
§impl Send for INITPROC
§impl Sync for INITPROC
§impl Unpin for INITPROC
§impl UnwindSafe for INITPROC
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct KernelStack {
+KernelStack in os::task - Rust Struct os::task::KernelStack
source · pub struct KernelStack {
pid: usize,
-}
Expand description
Kernelstack for app
-Fields
pid: usize
Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for KernelStack
impl Send for KernelStack
impl Sync for KernelStack
impl Unpin for KernelStack
impl UnwindSafe for KernelStack
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Kernelstack for app
+Fields§
§pid: usize
Implementations§
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for KernelStack
§impl Send for KernelStack
§impl Sync for KernelStack
§impl Unpin for KernelStack
§impl UnwindSafe for KernelStack
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PidAllocator {
+PidAllocator in os::task - Rust Struct os::task::PidAllocator
source · pub struct PidAllocator {
current: usize,
recycled: Vec<usize>,
-}
Expand description
Pid Allocator struct
-Fields
current: usize
recycled: Vec<usize>
Implementations
Auto Trait Implementations
impl RefUnwindSafe for PidAllocator
impl Send for PidAllocator
impl Sync for PidAllocator
impl Unpin for PidAllocator
impl UnwindSafe for PidAllocator
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Pid Allocator struct
+Fields§
§current: usize
§recycled: Vec<usize>
Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for PidAllocator
§impl Send for PidAllocator
§impl Sync for PidAllocator
§impl Unpin for PidAllocator
§impl UnwindSafe for PidAllocator
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct PidHandle(pub usize);
Bind pid lifetime to PidHandle
0: usize
Mutably borrows from an owned value. Read more
-Calls U::from(self)
.
pub struct PidHandle(pub usize);
Bind pid lifetime to PidHandle
0: usize
From<T> for U
chooses to do.
+pub struct Processor {
+Processor in os::task - Rust pub struct Processor {
current: Option<Arc<TaskControlBlock>>,
idle_task_cx: TaskContext,
-}
Expand description
Processor management structure
-Fields
current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
-idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
-Implementations
sourceimpl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
-sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
-sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
-Auto Trait Implementations
impl !RefUnwindSafe for Processor
impl Send for Processor
impl Sync for Processor
impl Unpin for Processor
impl !UnwindSafe for Processor
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
Processor management structure
+Fields§
§current: Option<Arc<TaskControlBlock>>
The task currently executing on the current processor
+§idle_task_cx: TaskContext
The basic control flow of each core, helping to select and switch process
+Implementations§
source§impl Processor
sourcefn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext
Get mutable reference to idle_task_cx
+sourcepub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>>
Get current task in moving semanteme
+sourcepub fn current(&self) -> Option<Arc<TaskControlBlock>>
Get current task in cloning semanteme
+Auto Trait Implementations§
§impl !RefUnwindSafe for Processor
§impl Send for Processor
§impl Sync for Processor
§impl Unpin for Processor
§impl !UnwindSafe for Processor
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
#[repr(C)]pub struct TaskContext {
+TaskContext in os::task - Rust Struct os::task::TaskContext
source · #[repr(C)]pub struct TaskContext {
ra: usize,
sp: usize,
- s: [usize; 12],
-}
Expand description
task context structure containing some registers
-Fields
ra: usize
return address ( e.g. __restore ) of __switch ASM function
-sp: usize
kernel stack pointer of app
-s: [usize; 12]
s0-11 register, callee saved
-Implementations
sourceimpl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
-Auto Trait Implementations
impl RefUnwindSafe for TaskContext
impl Send for TaskContext
impl Sync for TaskContext
impl Unpin for TaskContext
impl UnwindSafe for TaskContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+ s: [usize; 12],
+}Expand description
task context structure containing some registers
+Fields§
§ra: usize
return address ( e.g. __restore ) of __switch ASM function
+§sp: usize
kernel stack pointer of app
+§s: [usize; 12]
s0-11 register, callee saved
+Implementations§
source§impl TaskContext
sourcepub fn goto_trap_return(kstack_ptr: usize) -> Self
set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
+Auto Trait Implementations§
§impl RefUnwindSafe for TaskContext
§impl Send for TaskContext
§impl Sync for TaskContext
§impl Unpin for TaskContext
§impl UnwindSafe for TaskContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct TaskManager {
+TaskManager in os::task - Rust Struct os::task::TaskManager
source · pub struct TaskManager {
ready_queue: VecDeque<Arc<TaskControlBlock>>,
-}
Expand description
A array of TaskControlBlock
that is thread-safe
-Fields
ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations
sourceimpl TaskManager
A simple FIFO scheduler.
-Auto Trait Implementations
impl !RefUnwindSafe for TaskManager
impl Send for TaskManager
impl Sync for TaskManager
impl Unpin for TaskManager
impl !UnwindSafe for TaskManager
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
A array of TaskControlBlock
that is thread-safe
+Fields§
§ready_queue: VecDeque<Arc<TaskControlBlock>>
Implementations§
source§impl TaskManager
A simple FIFO scheduler.
+Auto Trait Implementations§
§impl !RefUnwindSafe for TaskManager
§impl Send for TaskManager
§impl Sync for TaskManager
§impl Unpin for TaskManager
§impl !UnwindSafe for TaskManager
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub unsafe extern "C" fn __switch(
current_task_cx_ptr: *mut TaskContext,
next_task_cx_ptr: *const TaskContext
)
pub unsafe extern "C" fn __switch(
+ current_task_cx_ptr: *mut TaskContext,
+ next_task_cx_ptr: *const TaskContext
+)
pub enum TaskStatus {
+TaskStatus in os::task::task - Rust Enum os::task::task::TaskStatus
source · pub enum TaskStatus {
Ready,
Running,
Zombie,
-}
Variants
Ready
Running
Zombie
Trait Implementations
sourceimpl Clone for TaskStatus
sourcefn clone(&self) -> TaskStatus
Returns a copy of the value. Read more
-1.0.0 · sourcefn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
-sourceimpl PartialEq<TaskStatus> for TaskStatus
sourceimpl Copy for TaskStatus
sourceimpl StructuralPartialEq for TaskStatus
Auto Trait Implementations
impl RefUnwindSafe for TaskStatus
impl Send for TaskStatus
impl Sync for TaskStatus
impl Unpin for TaskStatus
impl UnwindSafe for TaskStatus
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Variants§
Trait Implementations§
source§impl Clone for TaskStatus
source§fn clone(&self) -> TaskStatus
Returns a copy of the value. Read more1.0.0 · source§fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read moresource§impl PartialEq<TaskStatus> for TaskStatus
source§fn eq(&self, other: &TaskStatus) -> bool
This method tests for self
and other
values to be equal, and is used
+by ==
.source§impl Copy for TaskStatus
source§impl StructuralPartialEq for TaskStatus
Auto Trait Implementations§
§impl RefUnwindSafe for TaskStatus
§impl Send for TaskStatus
§impl Sync for TaskStatus
§impl Unpin for TaskStatus
§impl UnwindSafe for TaskStatus
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read moresourceimpl<T> ToOwned for T where
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
-sourcefn clone_into(&self, target: &mut T)
🔬 This is a nightly-only experimental API. (toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
-
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
Implementation of TaskControlBlock
Implementation of TaskControlBlock
pub struct TaskControlBlock {
+TaskControlBlock in os::task::task - Rust Struct os::task::task::TaskControlBlock
source · pub struct TaskControlBlock {
pub pid: PidHandle,
pub kernel_stack: KernelStack,
inner: UPSafeCell<TaskControlBlockInner>,
-}
Fields
pid: PidHandle
kernel_stack: KernelStack
inner: UPSafeCell<TaskControlBlockInner>
Implementations
Auto Trait Implementations
impl !RefUnwindSafe for TaskControlBlock
impl Send for TaskControlBlock
impl Sync for TaskControlBlock
impl Unpin for TaskControlBlock
impl !UnwindSafe for TaskControlBlock
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§pid: PidHandle
§kernel_stack: KernelStack
§inner: UPSafeCell<TaskControlBlockInner>
Implementations§
source§impl TaskControlBlock
sourcepub fn inner_exclusive_access(&self) -> RefMut<'_, TaskControlBlockInner>
sourcepub fn new(elf_data: &[u8]) -> Self
sourcepub fn exec(&self, elf_data: &[u8])
sourcepub fn fork(self: &Arc<TaskControlBlock>) -> Arc<TaskControlBlock>
sourcepub fn getpid(&self) -> usize
Auto Trait Implementations§
§impl !RefUnwindSafe for TaskControlBlock
§impl Send for TaskControlBlock
§impl Sync for TaskControlBlock
§impl Unpin for TaskControlBlock
§impl !UnwindSafe for TaskControlBlock
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub struct TaskControlBlockInner {
+TaskControlBlockInner in os::task::task - Rust Struct os::task::task::TaskControlBlockInner
source · pub struct TaskControlBlockInner {
pub trap_cx_ppn: PhysPageNum,
pub base_size: usize,
pub task_cx: TaskContext,
@@ -14,16 +8,14 @@
pub children: Vec<Arc<TaskControlBlock>>,
pub exit_code: i32,
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
-}
Fields
trap_cx_ppn: PhysPageNum
base_size: usize
task_cx: TaskContext
task_status: TaskStatus
memory_set: MemorySet
parent: Option<Weak<TaskControlBlock>>
children: Vec<Arc<TaskControlBlock>>
exit_code: i32
fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>
Implementations
sourceimpl TaskControlBlockInner
sourcepub fn get_trap_cx(&self) -> &'static mut TrapContext
sourcepub fn get_user_token(&self) -> usize
sourcefn get_status(&self) -> TaskStatus
sourcepub fn is_zombie(&self) -> bool
sourcepub fn alloc_fd(&mut self) -> usize
Auto Trait Implementations
impl !RefUnwindSafe for TaskControlBlockInner
impl Send for TaskControlBlockInner
impl Sync for TaskControlBlockInner
impl Unpin for TaskControlBlockInner
impl !UnwindSafe for TaskControlBlockInner
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Fields§
§trap_cx_ppn: PhysPageNum
§base_size: usize
§task_cx: TaskContext
§task_status: TaskStatus
§memory_set: MemorySet
§parent: Option<Weak<TaskControlBlock>>
§children: Vec<Arc<TaskControlBlock>>
§exit_code: i32
§fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>
Implementations§
source§impl TaskControlBlockInner
sourcepub fn get_trap_cx(&self) -> &'static mut TrapContext
sourcepub fn get_user_token(&self) -> usize
sourcefn get_status(&self) -> TaskStatus
sourcepub fn is_zombie(&self) -> bool
sourcepub fn alloc_fd(&mut self) -> usize
Auto Trait Implementations§
§impl !RefUnwindSafe for TaskControlBlockInner
§impl Send for TaskControlBlockInner
§impl Sync for TaskControlBlockInner
§impl Unpin for TaskControlBlockInner
§impl !UnwindSafe for TaskControlBlockInner
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
const MSEC_PER_SEC: usize = 1000;
const TICKS_PER_SEC: usize = 100;
pub fn get_time_ms() -> usize
get current time in microseconds
+pub fn set_next_trigger()
set the next timer interrupt
-pub fn set_next_trigger()
set the next timer interrupt
+Implementation of TrapContext
trap context structure containing sstatus, sepc and registers
-Implementation of TrapContext
#[repr(C)]pub struct TrapContext {
- pub x: [usize; 32],
+TrapContext in os::trap::context - Rust Struct os::trap::context::TrapContext
source · #[repr(C)]pub struct TrapContext {
+ pub x: [usize; 32],
pub sstatus: Sstatus,
pub sepc: usize,
pub kernel_satp: usize,
pub kernel_sp: usize,
pub trap_handler: usize,
-}
Expand description
trap context structure containing sstatus, sepc and registers
-Fields
x: [usize; 32]
general regs[0..31]
-sstatus: Sstatus
CSR sstatus
-sepc: usize
CSR sepc
-kernel_satp: usize
Addr of Page Table
-kernel_sp: usize
kernel stack
-trap_handler: usize
Addr of trap_handler function
-Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for TrapContext
impl Send for TrapContext
impl Sync for TrapContext
impl Unpin for TrapContext
impl UnwindSafe for TrapContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
trap context structure containing sstatus, sepc and registers
+Fields§
§x: [usize; 32]
general regs[0..31]
+§sstatus: Sstatus
CSR sstatus
+§sepc: usize
CSR sepc
+§kernel_satp: usize
Addr of Page Table
+§kernel_sp: usize
kernel stack
+§trap_handler: usize
Addr of trap_handler function
+Implementations§
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for TrapContext
§impl Send for TrapContext
§impl Sync for TrapContext
§impl Unpin for TrapContext
§impl UnwindSafe for TrapContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
pub fn enable_timer_interrupt()
enable timer interrupt in sie CSR
-pub fn enable_timer_interrupt()
enable timer interrupt in sie CSR
+fn set_kernel_trap_entry()
fn set_kernel_trap_entry()
fn set_user_trap_entry()
fn set_user_trap_entry()
#[no_mangle]
-pub fn trap_from_kernel() -> !
Unimplement: traps/interrupts/exceptions from kernel mode +
#[no_mangle]
+pub fn trap_from_kernel() -> !
Unimplement: traps/interrupts/exceptions from kernel mode Todo: Chapter 9: I/O device
-#[no_mangle]
+pub fn trap_handler() -> !
handle an interrupt, exception, or system call from user space
+#[no_mangle]
-pub fn trap_return() -> !
set the new addr of __restore asm function in TRAMPOLINE page, +
#[no_mangle]
+pub fn trap_return() -> !
set the new addr of __restore asm function in TRAMPOLINE page, set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table, finally, jump to new addr of __restore asm function
-Trap handling functionality
+Trap handling functionality
For rCore, we have a single trap entry point, namely __alltraps
. At
-initialization in init()
, we set the stvec
CSR to point to it.
init()
, we set the stvec
CSR to point to it.
All traps go through __alltraps
, which is defined in trap.S
. The
assembly language code does just enough work restore the kernel space
context, ensuring that Rust code safely runs, and transfers control to
-trap_handler()
.
trap_handler()
.
It then calls different functionality based on what exactly the exception
was. For example, timer interrupts trigger task preemption, and syscalls go
-to syscall()
.
Implementation of TrapContext
trap context structure containing sstatus, sepc and registers
-enable timer interrupt in sie CSR
-initialize CSR stvec
as the entry of __alltraps
Unimplement: traps/interrupts/exceptions from kernel mode -Todo: Chapter 9: I/O device
-handle an interrupt, exception, or system call from user space
-set the new addr of __restore asm function in TRAMPOLINE page,
+to syscall()
.
TrapContext
stvec
as the entry of __alltraps
#[repr(C)]pub struct TrapContext {
- pub x: [usize; 32],
+TrapContext in os::trap - Rust Struct os::trap::TrapContext
source · #[repr(C)]pub struct TrapContext {
+ pub x: [usize; 32],
pub sstatus: Sstatus,
pub sepc: usize,
pub kernel_satp: usize,
pub kernel_sp: usize,
pub trap_handler: usize,
-}
Expand description
trap context structure containing sstatus, sepc and registers
-Fields
x: [usize; 32]
general regs[0..31]
-sstatus: Sstatus
CSR sstatus
-sepc: usize
CSR sepc
-kernel_satp: usize
Addr of Page Table
-kernel_sp: usize
kernel stack
-trap_handler: usize
Addr of trap_handler function
-Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for TrapContext
impl Send for TrapContext
impl Sync for TrapContext
impl Unpin for TrapContext
impl UnwindSafe for TrapContext
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-sourceimpl<T, U> Into<U> for T where
U: From<T>,
const: unstable · sourcefn into(self) -> U
Calls U::from(self)
.
+}Expand description
trap context structure containing sstatus, sepc and registers
+Fields§
§x: [usize; 32]
general regs[0..31]
+§sstatus: Sstatus
CSR sstatus
+§sepc: usize
CSR sepc
+§kernel_satp: usize
Addr of Page Table
+§kernel_sp: usize
kernel stack
+§trap_handler: usize
Addr of trap_handler function
+Implementations§
Trait Implementations§
Auto Trait Implementations§
§impl RefUnwindSafe for TrapContext
§impl Send for TrapContext
§impl Sync for TrapContext
§impl Unpin for TrapContext
§impl UnwindSafe for TrapContext
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
-
\ No newline at end of file
+From<T> for U
chooses to do.
+
EXIT_FAILURE
, aka 1
.","","Exit QEMU using EXIT_SUCCESS
, aka 0
, if possible.","","Returns the argument unchanged.","Calls U::from(self)
.","Create an instance.","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","","","","","","Number of blocks to erase (SDC) ","Initiate initialization process (SDC) ","","SD commands ","Software reset ","Read CID register ","Stop to read data ","Change R/W block size ","Read block ","Read multiple blocks ","Write a block ","Write multiple blocks ","Leading command for ACMD* ","Read OCR ","Enable/disable CRC check ","Check voltage range (SDC V2) ","Read CSD register ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Card Identification Data: CID Register","Card Specific Data: CSD Register","Card information","","CS value passed to SPI controller, this is a dummy value …","GPIOHS GPIO number to use for controlling the SD card CS …","Data token start byte, Start Multiple Block Read ","Data token start byte, Start Multiple Block Write ","Data token start byte, Start Single Block Read ","Data token start byte, Start Single Block Write ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Connect pins to internal functions ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","File trait","A wrapper around a filesystem inode to implement File …","Open file flags","Standard input","Standard output","","","Arc<Inode>
-> OSInodeInner
: In order to open files …","List all files in the filesystems","Open file with flags","Read file to UserBuffer
","If readable","","Stdin & Stdout","If writable","","Write UserBuffer
to file","Allow create","A wrapper around a filesystem inode to implement File …","The OS inode inner in ‘UPSafeCell’","Open file flags","Read only","Read & Write","","Clear file and return an empty one","Write only","","Returns the set containing all flags.","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","","Returns the difference between the flags in self
and other
.","Returns an empty set of flags.","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","","","","","Inserts the specified flags in-place.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","List all files in the filesystems","","Construct an OS inode from a inode","Returns the complement of this set of flags.","","Open file with flags","","","Read all data inside a inode into vector","Do not check validity for simplicity Return (readable, …","","","Removes the specified flags in-place.","Inserts or removes the specified flags depending on the …","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","Toggles the specified flags in-place.","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","","","","Standard input","Standard output","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","manage a frame which has the same lifecycle as the tracker","a memory set instance through lazy_static! managing kernel …","map permission corresponding to that in pte: R W X U
","memory set structure, controls virtual-memory space","Record root ppn and has the same lifetime as 1 and 2 level …","page table entry structure","Definitions","phiscal page number","Add value by one","Array of u8 slice that user communicate with os","Iterator of UserBuffer
","virtual address","virtual page number","","Implementation of physical and virtual address and page …","","","PTE","U8 vec","","","","allocate a frame","Implementation of FrameAllocator
which controls all the …","deallocate a frame","","The global allocator","initiate heap allocator, frame allocator and kernel space","Get kernelspace root ppn","Implementation of MapArea
and MemorySet
.","Implementation of PageTableEntry
and PageTable
.","","","Check PageTable running correctly","","Add value by one","Translate a pointer to a mutable u8 Vec through page table","Translate a generic through page table and return a …","Translate a generic through page table and return a …","Translate a pointer to a mutable u8 Vec end with \\\\0
…","","","","","","","Definitions","phiscal page number","a simple range structure for type T","iterator for the simple range structure","Add value by one","","a simple range structure for virtual page number","","virtual address","virtual page number","Check page aligned","Check page aligned","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","","","","","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","","Returns the argument unchanged.","","","Returns the argument unchanged.","Get u8 array on PhysPageNum
","","Get mutable reference to PhysAddr
value","Get Get mutable reference to PhysAddr
value on PhysPageNum
","Get PageTableEntry
on PhysPageNum
","Get reference to PhysAddr
value","","Return VPN 3 level index","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","Get page offset","Get page offset","","","","","","Add value by one","","","","","","","","","","","","","","","","","","","","","","","","","","frame allocator instance through lazy_static!","","","manage a frame which has the same lifecycle as the tracker","an implementation for frame allocator","","","","","","","","","","","","","","","","","allocate a frame","a simple test for frame allocator","deallocate a frame","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","initiate the frame allocator using ekernel
and MEMORY_END
","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","Create an empty FrameTracker
","","","","","","","","","","","","","heap allocator instance","heap space ([u8; KERNEL_HEAP_SIZE])","panic when heap allocation error occurs","","initiate heap allocator","","","a memory set instance through lazy_static! managing kernel …","map area structure, controls a contiguous piece of virtual …","map permission corresponding to that in pte: R W X U
","map type for memory set: identical or framed","memory set structure, controls virtual-memory space","Readable","Accessible in U mode","Writable","Excutable","","Refresh TLB with sfence.vma
","Returns the set containing all flags.","","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","data: start-aligned but maybe with shorter length assume …","","","Returns the difference between the flags in self
and other
.","","","","Returns an empty set of flags.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","Include sections in elf and trampoline and TrapContext and …","Clone a same MemorySet
","","","Inserts the specified flags in-place.","Assume that no conflicts.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","Get kernelspace root ppn","","","","Mention that trampoline is not collected by areas.","","","","Create an empty MemorySet
","Without kernel stacks.","Returns the complement of this set of flags.","","","","Remove all MapArea
","Check PageTable running correctly","Removes the specified flags in-place.","Remove MapArea
that starts with start_vpn
","","","Inserts or removes the specified flags depending on the …","","","","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","Get pagetable root_ppn
","Translate throuth pagetable","","","","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","","","","","","","","Record root ppn and has the same lifetime as 1 and 2 level …","page table entry structure","","","Array of u8 slice that user communicate with os","Iterator of UserBuffer
","","","","Returns the set containing all flags.","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","PTE","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","U8 vec","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","","","Returns the difference between the flags in self
and other
.","Returns an empty set of flags.","Return an empty PTE","","Check PTE executable","","Find phsical address by virtual address","Find phsical address by virtual address, create a frame if …","Return 10bit flag","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","","Temporarily used to get arguments from user space.","","Inserts the specified flags in-place.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","Check PTE valid","Length of UserBuffer
","Create a mapping form vpn
to ppn
","","Create an empty PageTable
","Create a UserBuffer
by parameter","Create a PTE from ppn","","Returns the complement of this set of flags.","","Return 44bit ppn","Check PTE readable","Removes the specified flags in-place.","","Inserts or removes the specified flags depending on the …","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","Get root ppn","Translate VirtPageNum
to PageTableEntry
","Translate VirtAddr
to PhysAddr
","Translate a pointer to a mutable u8 Vec through page table","Translate a generic through page table and return a …","Translate a generic through page table and return a …","Translate a pointer to a mutable u8 Vec end with \\\\0
…","","","","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","Delete a mapping form vpn
","Check PTE writable","","","","","","","","","","use sbi call to getchar from console (qemu uart handler)","use sbi call to putchar in console (qemu uart handler)","general sbi call","use sbi call to set timer","use sbi call to shutdown the kernel","Wrap a static data structure inside it so that we are able …","inner data","Uniprocessor interior mutability primitives","Wrap a static data structure inside it so that we are able …","","","Exclusive access inner data in UPSafeCell. Panic if the …","Returns the argument unchanged.","inner data","Calls U::from(self)
.","User is responsible to guarantee that inner struct is only …","","","","","","","","","","","","","","","File and filesystem-related syscalls","","handle syscall exception with syscall_id
and other …","","","","","","","","","","If there is not a child process whose pid is same as …","","","pid of usertests app in make run TEST=1","Globle process that init user shell","Kernelstack for app","Pid Allocator struct","Bind pid lifetime to PidHandle
","Processor management structure","task context structure containing some registers","A array of TaskControlBlock
that is thread-safe","","Add init process to the manager","Interface offered to add task","","","Implementation of TaskContext
","","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Exit the current ‘Running’ task and run the next task …","Interface offered to pop the first task","Returns the argument unchanged.","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Implementation of TaskManager
","Implementation of PidAllocator
","","Allocate a pid from PID_ALLOCATOR","Implementation of Processor
and Intersection of control …","return address ( e.g. __restore ) of __switch ASM function","","","The main part of process execution and scheduling Loop …","s0-11 register, callee saved","Return to idle control flow for new scheduling","kernel stack pointer of app","Suspend the current ‘Running’ task and run the next …","Wrap switch.S
as a function","Take the current task,leaving a None in its place","Implementation of TaskControlBlock
","","","","task context structure containing some registers","","","Returns the argument unchanged.","set Task Context{__restore ASM funciton: trap_return, sp: …","Calls U::from(self)
.","return address ( e.g. __restore ) of __switch ASM function","s0-11 register, callee saved","kernel stack pointer of app","","","","init task context","","A array of TaskControlBlock
that is thread-safe","","Add a task to TaskManager
","Interface offered to add task","","","","","","Remove the first task and return it,or None
if TaskManager
…","Interface offered to pop the first task","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","Creat an empty TaskManager","","","","","","","","","Kernelstack for app","","Pid Allocator struct","Bind pid lifetime to PidHandle
","","Allocate a pid","","","","","","","","","","Recycle a pid","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Get the value on the top of kernelstack","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Return (bottom, top) of a kernel stack in kernel space.","Create an empty PidAllocator
","Create a kernelstack from pid","","Allocate a pid from PID_ALLOCATOR","Push a value on top of kernelstack","","","","","","","","","","","","","","","Processor management structure","","","","","","Get current task in cloning semanteme","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Returns the argument unchanged.","Returns the argument unchanged.","Get mutable reference to idle_task_cx
","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Calls U::from(self)
.","Create an empty Processor","The main part of process execution and scheduling Loop …","Return to idle control flow for new scheduling","Get current task in moving semanteme","Take the current task,leaving a None in its place","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","","","get current time","get current time in microseconds","set the next timer interrupt","trap context structure containing sstatus, sepc and …","Implementation of TrapContext
","enable timer interrupt in sie CSR","initialize CSR stvec
as the entry of __alltraps
","Addr of Page Table","kernel stack","CSR sepc","","","CSR sstatus ","Unimplement: traps/interrupts/exceptions from kernel mode …","handle an interrupt, exception, or system call from user …","Addr of trap_handler function","set the new addr of __restore asm function in TRAMPOLINE …","general regs[0..31]","trap context structure containing sstatus, sepc and …","init app context","","","","Returns the argument unchanged.","Calls U::from(self)
.","Addr of Page Table","kernel stack","CSR sepc","set stack pointer to x_2 reg (sp)","CSR sstatus ","Addr of trap_handler function","","","","general regs[0..31]"],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,1,0,2,1,2,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,3,3,3,3,0,0,4,0,4,4,4,4,4,0,4,4,4,0,5,6,6,7,0,6,6,6,6,6,6,6,6,6,6,6,6,6,8,9,9,10,10,8,11,11,8,9,9,9,9,9,9,9,9,9,9,10,0,9,7,7,9,9,9,7,0,9,9,7,7,7,7,9,9,9,7,9,7,9,9,0,0,0,0,0,0,0,0,0,0,0,11,11,0,9,9,9,9,9,9,9,9,12,10,5,6,8,9,7,11,12,10,5,6,8,9,7,11,12,6,8,9,7,11,6,8,9,7,11,10,12,10,6,6,8,9,7,11,10,5,6,8,9,7,11,12,10,10,10,10,10,10,0,10,5,6,8,9,7,11,12,0,10,10,5,5,10,10,10,10,10,6,8,9,7,11,10,5,6,8,9,7,11,12,10,5,6,8,9,7,11,12,10,5,6,8,9,7,11,12,5,10,10,13,14,13,15,0,0,0,16,15,16,15,16,16,15,16,15,16,15,15,15,16,15,16,15,16,0,0,0,0,15,0,0,0,0,0,17,18,0,0,0,19,19,18,0,19,18,19,17,0,0,0,17,17,0,17,17,20,17,17,17,17,17,17,17,17,17,18,21,20,17,18,21,20,17,17,17,17,17,17,20,17,17,17,17,17,17,17,17,17,18,21,20,17,17,17,17,17,17,18,21,17,17,17,18,21,20,17,17,17,0,17,18,17,21,0,17,18,18,17,18,18,17,17,17,17,17,17,17,18,21,20,17,18,21,20,17,18,21,20,17,17,18,18,18,0,0,22,23,22,23,22,23,22,23,22,23,22,23,22,23,22,23,22,23,22,23,22,23,0,24,25,26,27,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,29,30,31,32,33,33,33,0,0,0,34,0,0,0,0,0,29,35,0,34,36,0,0,0,0,24,25,26,27,0,0,0,0,0,0,0,0,0,0,0,0,24,25,37,24,25,26,27,38,37,24,25,26,27,38,24,25,24,25,26,27,38,24,25,26,27,38,24,25,26,27,37,37,24,25,26,27,24,25,24,25,26,27,37,24,24,24,25,25,25,26,26,26,27,27,27,38,26,38,24,26,26,24,38,27,37,24,25,26,27,38,37,38,38,24,25,26,27,37,38,37,24,25,24,25,26,27,38,36,26,27,24,25,26,27,38,37,24,25,26,27,38,37,24,25,26,27,38,37,24,25,26,27,38,0,0,0,0,0,39,40,41,35,41,39,35,41,39,41,40,41,39,35,41,35,0,0,0,35,41,39,41,0,35,41,39,40,35,41,35,41,35,41,39,35,41,39,35,41,39,0,0,0,0,0,42,42,0,0,0,0,0,30,30,30,30,28,29,30,29,30,30,30,30,30,30,30,30,29,43,28,42,30,29,43,28,42,30,42,30,42,30,30,30,30,43,43,28,30,0,0,0,30,42,30,0,0,30,42,30,30,30,30,30,29,43,28,42,30,43,30,30,30,29,29,30,30,30,29,30,30,29,43,28,42,30,30,30,0,43,43,43,29,43,30,43,29,29,30,29,30,29,29,0,30,29,0,0,30,0,0,0,30,30,30,42,30,30,29,29,29,43,28,42,30,29,43,28,42,30,29,43,28,42,30,30,43,43,43,44,44,44,0,0,0,44,44,0,0,44,44,44,44,44,44,44,44,44,44,31,44,44,34,32,33,44,31,34,32,33,44,31,32,33,44,31,44,31,44,44,44,33,33,44,44,31,44,31,44,34,34,31,44,44,44,44,44,34,34,32,33,44,31,44,44,44,44,34,44,44,44,44,34,32,33,44,31,32,33,44,44,31,32,34,44,34,32,31,33,44,44,31,31,44,34,44,44,44,44,44,31,44,34,34,34,0,0,0,0,34,32,33,44,31,34,32,33,44,31,34,32,33,44,31,44,34,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,0,0,45,45,45,45,45,45,45,45,45,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,0,0,0,0,0,0,0,0,47,0,0,47,47,0,48,49,0,0,0,47,0,0,47,49,47,0,0,50,0,0,51,52,48,0,51,0,51,0,0,0,0,47,47,47,0,51,51,51,51,51,51,51,51,51,51,51,51,0,0,53,52,0,52,53,52,53,53,52,0,52,53,52,53,52,52,52,53,52,53,52,53,46,0,0,0,0,54,48,48,46,50,54,48,46,50,54,48,48,54,46,50,48,46,50,54,50,48,46,50,54,0,48,50,50,0,50,48,48,46,50,54,48,46,50,54,48,46,50,54,0,0,55,49,55,49,55,49,49,0,0,0,55,49,55,49,49,49,55,49,0,0,49,0,49,55,49,55,49,55,0,56,56,0,0,0,56,57,57,58,57,56,58,57,56,57,56,56,56,58,57,57,58,58,57,56,57,57,57,58,58,58,58,57,56,57,58,57,58,57,58,57,57,56,57,58,57,56,58,57,56,58,57,56,0,0,0,0,0,0,0,0,0,59,59,59,0,0,59,0,0,59,0,59,0,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59],"f":[null,[[]],null,null,null,null,null,null,null,null,[[],["never",0]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0],["u32",0]],["never",0]],[[["",0],["u32",0]],["never",0]],[[["u32",0]],["u32",0]],[[["",0]],["never",0]],[[["",0]],["never",0]],[[["",0]],["never",0]],[[["",0]],["never",0]],[[]],[[]],[[["u64",0]]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],null,null,null,null,null,null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[]],[[]],[[["arguments",3]]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0],["str",0]],["result",6]],null,null,null,[[]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["arc",3]],[[]],[[]],null,[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["",0]]],[[["",0]]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["",0]]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["cmd",4]],[[["",0]],["initerror",4]],[[["",0]],["sdcardcsd",3]],[[["",0]],["sdcardcid",3]],[[["",0]],["sdcardinfo",3]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["",0]]],null,[[["",0]],["upsafecell",3]],[[["",0]]],[[["",0],["cmd",4]],["bool",0]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["",0]],["result",4,[["sdcardinfo",3]]]],[[["",0]],["result",4,[["sdcardcid",3]]]],[[["",0]],["result",4,[["sdcardcsd",3]]]],[[["",0]],["u8",0]],[[["",0]],["u8",0]],[[["",0]],["result",4,[["sdcardinfo",3],["initerror",4]]]],[[],["sdcard",3,[["spiimpl",3,[["spi0",3]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["",0]]],[[["u32",0],["u8",0]]],[[]],[[["",0],["usize",0]]],[[["",0]]],[[["",0],["u32",0]],["result",4]],[[["",0],["cmd",4],["u32",0],["u8",0]]],null,null,[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0],["usize",0]]],[[["",0]]],[[["",0],["u32",0]],["result",4]],null,null,null,null,null,null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["upsafecell",3]],[[]],[[]],[[]],[[]],[[]],[[["",0],["usize",0]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["usize",0]],["physaddr",3]],[[["physaddr",3],["usize",0]],["i32",0]],[[["physaddr",3]],["virtaddr",3]],[[["virtaddr",3]],["physaddr",3]],[[["",0],["usize",0]]],null,null,null,null,null,null,null,null,[[]],[[["str",0],["openflags",3]],["option",4,[["arc",3,[["osinode",3]]]]]],[[["",0],["userbuffer",3]],["usize",0]],[[["",0]],["bool",0]],null,null,[[["",0]],["bool",0]],null,[[["",0],["userbuffer",3]],["usize",0]],null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[["",0]]],[[["openflags",3]]],[[["",0]]],[[["",0]],["u32",0]],null,[[]],[[["",0]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["openflags",3]],[[["",0],["",0]]],[[["",0],["openflags",3]],["ordering",4]],[[]],[[["",0]],["bool",0]],[[["",0]],["arc",3]],[[]],[[]],[[["",0],["openflags",3]],["bool",0]],[[["",0],["intoiterator",8]]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[["u32",0]],["option",4]],[[["u32",0]]],[[["u32",0]]],[[["intoiterator",8]]],[[["",0],["",0]]],null,null,[[["",0]]],[[]],[[["",0]],["bool",0]],[[]],[[]],[[]],[[]],[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[]],[[["",0],["openflags",3]],["bool",0]],[[["bool",0],["bool",0],["arc",3,[["inode",3]]]]],[[]],null,[[["str",0],["openflags",3]],["option",4,[["arc",3,[["osinode",3]]]]]],[[["",0],["openflags",3]],["option",4,[["ordering",4]]]],[[["",0],["userbuffer",3]],["usize",0]],[[["",0]],["vec",3,[["u8",0]]]],[[["",0]]],[[["",0]],["bool",0]],null,[[["",0]]],[[["",0],["bool",0]]],[[]],[[["",0]]],[[]],[[["",0]]],[[["",0]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[]],[[["",0]],["bool",0]],null,[[["",0],["userbuffer",3]],["usize",0]],null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[]],[[]],[[]],[[]],[[["",0],["userbuffer",3]],["usize",0]],[[["",0],["userbuffer",3]],["usize",0]],[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[["",0],["userbuffer",3]],["usize",0]],[[["",0],["userbuffer",3]],["usize",0]],[[["panicinfo",3]],["never",0]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],["option",4,[["frametracker",3]]]],null,[[["physpagenum",3]]],null,null,[[]],[[],["usize",0]],null,null,null,null,[[]],null,[[["",0]]],[[["usize",0],["usize",0]],["vec",3]],[[["usize",0]],["",0]],[[["usize",0]],["",0]],[[["usize",0]],["string",3]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["physpagenum",3]],[[["",0]],["virtpagenum",3]],[[["",0]],["physaddr",3]],[[["",0]],["virtaddr",3]],[[["",0]],["physpagenum",3]],[[["",0]],["virtpagenum",3]],[[["",0]],["simplerange",3]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["physaddr",3]],["ordering",4]],[[["",0],["virtaddr",3]],["ordering",4]],[[["",0],["physpagenum",3]],["ordering",4]],[[["",0],["virtpagenum",3]],["ordering",4]],null,null,[[["",0],["physaddr",3]],["bool",0]],[[["",0],["virtaddr",3]],["bool",0]],[[["",0],["physpagenum",3]],["bool",0]],[[["",0],["virtpagenum",3]],["bool",0]],[[["",0]],["physpagenum",3]],[[["",0]],["virtpagenum",3]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[]],[[]],[[["physpagenum",3]]],[[["usize",0]]],[[["usize",0]]],[[]],[[["virtpagenum",3]]],[[]],[[["usize",0]]],[[["physaddr",3]]],[[]],[[["usize",0]]],[[["virtaddr",3]]],[[]],[[["",0]]],[[["",0]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]]],[[["",0]],["",0]],[[["",0]]],[[["",0]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,[[["",0],["physaddr",3]],["bool",0]],[[["",0],["virtaddr",3]],["bool",0]],[[["",0],["physpagenum",3]],["bool",0]],[[["",0],["virtpagenum",3]],["bool",0]],[[]],[[]],[[["",0]],["option",4]],[[["",0]],["usize",0]],[[["",0]],["usize",0]],[[["",0],["physaddr",3]],["option",4,[["ordering",4]]]],[[["",0],["virtaddr",3]],["option",4,[["ordering",4]]]],[[["",0],["physpagenum",3]],["option",4,[["ordering",4]]]],[[["",0],["virtpagenum",3]],["option",4,[["ordering",4]]]],null,[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],null,null,null,null,null,null,[[["",0]],["option",4,[["physpagenum",3]]]],[[["",0]],["option",4,[["physpagenum",3]]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],null,[[["",0],["physpagenum",3]]],[[["",0],["physpagenum",3]]],[[["",0]],["upsafecell",3]],[[["",0]]],null,[[["",0],["formatter",3]],["result",6]],[[],["option",4,[["frametracker",3]]]],[[]],[[["physpagenum",3]]],[[]],[[]],[[]],[[["",0],["physpagenum",3],["physpagenum",3]]],[[]],[[]],[[]],[[]],[[]],[[["physpagenum",3]]],[[]],null,null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],null,null,[[["layout",3]],["never",0]],[[]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,[[["",0]]],[[]],null,[[]],[[["",0]]],[[["mappermission",3]]],[[["",0]]],[[["",0]],["u8",0]],null,[[]],[[["",0]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["maptype",4]],[[["",0]],["mappermission",3]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["mappermission",3]],["ordering",4]],[[]],[[["",0]],["bool",0]],[[["",0],["pagetable",3]]],null,[[["",0]],["arc",3]],[[]],null,null,null,[[]],[[["",0],["maptype",4]],["bool",0]],[[["",0],["mappermission",3]],["bool",0]],null,null,[[["",0],["intoiterator",8]]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[["maparea",3]]],[[["u8",0]],["option",4]],[[["u8",0]]],[[["u8",0]]],[[]],[[["memoryset",3]],["memoryset",3]],[[["intoiterator",8]]],[[["",0],["",0]]],[[["",0]]],[[["",0],["virtaddr",3],["virtaddr",3],["mappermission",3]]],[[]],[[["",0]],["bool",0]],[[]],[[]],[[]],[[]],[[]],[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[],["usize",0]],[[["",0],["pagetable",3]]],[[["",0],["pagetable",3],["virtpagenum",3]]],null,[[["",0]]],null,[[["",0],["mappermission",3]],["bool",0]],[[["virtaddr",3],["virtaddr",3],["maptype",4],["mappermission",3]]],[[]],[[]],[[]],null,[[["",0],["mappermission",3]],["option",4,[["ordering",4]]]],[[["",0],["maparea",3],["option",4]]],[[["",0]]],[[]],[[["",0]]],[[["",0],["virtpagenum",3]]],null,null,[[["",0],["bool",0]]],null,null,null,[[]],[[["",0]]],[[]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]],["usize",0]],[[["",0],["virtpagenum",3]],["option",4,[["pagetableentry",3]]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[]],[[["",0],["pagetable",3]]],[[["",0],["pagetable",3],["virtpagenum",3]]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[["",0]]],[[["pteflags",3]]],[[["",0]]],[[["",0]],["u8",0]],null,null,[[]],[[["",0]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],null,null,[[["",0]],["pteflags",3]],[[["",0]],["pagetableentry",3]],[[["",0],["",0]]],[[["",0],["",0]]],[[["",0],["pteflags",3]],["ordering",4]],[[]],[[["",0]],["bool",0]],null,null,[[]],[[]],[[]],[[["",0],["pteflags",3]],["bool",0]],[[["",0]],["bool",0]],[[["",0],["intoiterator",8]]],[[["",0],["virtpagenum",3]],["option",4,[["pagetableentry",3]]]],[[["",0],["virtpagenum",3]],["option",4,[["pagetableentry",3]]]],[[["",0]],["pteflags",3]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],[[["",0],["formatter",3]],["result",6]],null,[[]],[[]],[[]],[[]],[[]],[[["u8",0]],["option",4]],[[["u8",0]]],[[["u8",0]]],[[["intoiterator",8]]],[[["usize",0]]],[[["",0],["",0]]],[[["",0]]],[[]],[[["",0]],["bool",0]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[["",0]],["bool",0]],[[["",0]],["usize",0]],[[["",0],["virtpagenum",3],["physpagenum",3],["pteflags",3]]],[[["",0],["pteflags",3]],["bool",0]],[[]],[[["vec",3]]],[[["physpagenum",3],["pteflags",3]]],[[["",0]],["option",4]],[[]],[[["",0],["pteflags",3]],["option",4,[["ordering",4]]]],[[["",0]],["physpagenum",3]],[[["",0]],["bool",0]],[[["",0]]],null,[[["",0],["bool",0]]],[[]],[[["",0]]],[[]],[[["",0]]],[[["",0]]],[[["",0]]],[[["",0]],["usize",0]],[[["",0],["virtpagenum",3]],["option",4,[["pagetableentry",3]]]],[[["",0],["virtaddr",3]],["option",4,[["physaddr",3]]]],[[["usize",0],["usize",0]],["vec",3]],[[["usize",0]],["",0]],[[["usize",0]],["",0]],[[["usize",0]],["string",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[]],[[["",0],["virtpagenum",3]]],[[["",0]],["bool",0]],null,null,null,null,null,null,null,null,null,[[],["usize",0]],[[["usize",0]]],[[["usize",0],["usize",0],["usize",0],["usize",0]],["usize",0]],[[["usize",0]]],[[],["never",0]],null,null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["refmut",3]],[[]],null,[[]],[[]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],null,null,null,null,null,null,null,null,null,null,null,null,null,[[["usize",0]],["isize",0]],[[["usize",0]],["isize",0]],[[["u32",0]],["isize",0]],[[["usize",0],["usize",0]],["isize",0]],[[["usize",0],["usize",0]],["isize",0]],[[],["isize",0]],[[["i32",0]],["never",0]],[[],["isize",0]],[[],["isize",0]],[[],["isize",0]],[[["isize",0]],["isize",0]],[[],["isize",0]],null,null,null,null,null,null,null,null,null,null,[[]],[[["arc",3,[["taskcontrolblock",3]]]]],[[["",0]],["",0]],[[["",0]],["",0]],null,null,null,[[],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[],["trapcontext",3]],[[],["usize",0]],[[["",0]],["arc",3]],[[["i32",0]]],[[],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[]],null,[[]],null,null,null,[[],["pidhandle",3]],null,null,null,null,[[]],null,[[]],null,[[]],null,[[],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],null,[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],null,[[["",0]],["",0]],[[["",0]],["",0]],[[]],[[["usize",0]]],[[]],null,null,null,[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[]],null,null,null,[[["",0],["arc",3,[["taskcontrolblock",3]]]]],[[["arc",3,[["taskcontrolblock",3]]]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["upsafecell",3]],[[["",0]],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[]],[[]],[[]],[[]],[[]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],null,null,null,null,null,null,[[["",0]],["pidhandle",3]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],null,[[["",0],["usize",0]]],[[["",0]],["upsafecell",3]],[[["",0]]],[[["",0]]],[[]],[[]],[[]],[[]],[[["",0]],["usize",0]],[[]],[[]],[[]],[[]],[[["usize",0]]],[[]],[[["pidhandle",3]]],null,[[],["pidhandle",3]],[[["",0]]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],null,[[],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[],["trapcontext",3]],[[],["usize",0]],[[["",0]],["upsafecell",3]],[[]],[[]],[[["",0]]],null,[[]],[[]],[[]],[[]],[[]],[[["",0]],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[],["option",4,[["arc",3,[["taskcontrolblock",3]]]]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],null,null,null,null,null,null,null,[[["",0]],["usize",0]],null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0]],["",0]],null,[[["",0]],["taskstatus",4]],[[["",0],["",0]]],[[["",0],["taskstatus",4]],["bool",0]],[[["",0]]],null,null,[[["arc",3]],["arc",3,[["taskcontrolblock",3]]]],[[]],[[]],[[]],[[["",0]],["taskstatus",4]],[[["",0]],["trapcontext",3]],[[["",0]],["usize",0]],[[["",0]],["usize",0]],null,[[["",0]],["refmut",3,[["taskcontrolblockinner",3]]]],[[]],[[]],[[]],[[["",0]],["bool",0]],null,null,[[]],null,null,null,null,[[["",0]]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],[[["",0]],["typeid",3]],null,null,[[],["usize",0]],[[],["usize",0]],[[]],null,null,[[]],[[]],null,null,null,[[]],[[]],null,[[],["never",0]],[[],["never",0]],null,[[],["never",0]],null,null,[[["usize",0],["usize",0],["usize",0],["usize",0],["usize",0]]],[[["",0]],["",0]],[[["",0]],["",0]],[[["",0],["formatter",3]],["result",6]],[[]],[[]],null,null,null,[[["",0],["usize",0]]],null,null,[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],null],"p":[[3,"RISCV64"],[8,"QEMUExit"],[3,"Stdout"],[3,"BLOCK_DEVICE"],[3,"SDCardWrapper"],[4,"CMD"],[3,"SDCardCID"],[4,"InitError"],[3,"SDCardCSD"],[3,"SDCard"],[3,"SDCardInfo"],[3,"PERIPHERALS"],[13,"CMDFailed"],[13,"CardCapacityStatusNotSet"],[3,"VirtIOBlock"],[3,"QUEUE_FRAMES"],[3,"OpenFlags"],[3,"OSInode"],[8,"File"],[3,"ROOT_INODE"],[3,"OSInodeInner"],[3,"Stdin"],[3,"Stdout"],[3,"PhysAddr"],[3,"VirtAddr"],[3,"PhysPageNum"],[3,"VirtPageNum"],[3,"KERNEL_SPACE"],[3,"MemorySet"],[3,"MapPermission"],[3,"PageTableEntry"],[3,"UserBuffer"],[3,"UserBufferIterator"],[3,"PageTable"],[3,"FrameTracker"],[8,"StepByOne"],[3,"SimpleRangeIterator"],[3,"SimpleRange"],[3,"FRAME_ALLOCATOR"],[8,"FrameAllocator"],[3,"StackFrameAllocator"],[4,"MapType"],[3,"MapArea"],[3,"PTEFlags"],[3,"UPSafeCell"],[3,"PidHandle"],[3,"INITPROC"],[3,"PidAllocator"],[3,"Processor"],[3,"KernelStack"],[3,"TaskContext"],[3,"TaskManager"],[3,"TASK_MANAGER"],[3,"PID_ALLOCATOR"],[3,"PROCESSOR"],[4,"TaskStatus"],[3,"TaskControlBlockInner"],[3,"TaskControlBlock"],[3,"TrapContext"]]}\
+"os":{"doc":"The main module and entrypoint","t":"AFAAAAAAOOFAAAAAAGRRRCRRCCRRRRRDLLLLFLLLLCCADCMFLLLLLLLLADRDDMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLIDDDDMMAFFKKMAKMKRSGDDDSSDSSMLLLLLLMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMLLLLLLLLLFLLMFLLLLLMLLLLLLLLLLLLLLLLLLLLLMLDDLLLLLLLLLLLLLLLLLLLLLLFDCCDDDDDDDIDDDDMAMMMMMMMFAFMAFFAAMMFMKFFFFRRDDDDIRGRDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLMMKLLLLLLLLLLLLLLLLLLLLLLLLLDIGDDMKLLLLLLLMMKLLLMMLFFFLLLLFLLLKLLMMMLLLLLLLLLHHFFFNNDDDEDSSSSMLLMLLLLLMLLLLLLLLLLLLLLLLLLLLMLLFFFLLLFFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLLMLMLLLLMLLLFLLFFLFFFLLLLLLLLLLLLLLLLLLLLLLLLLLMSSSDDDSSDDSSSLLLLLLMMLLLLLLLLLLLLMMLLLLLLLMMLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLFFFFLLLLLLLLLLLLLLLLLLFFFFDDMADDLLLLLLLMLLLLLLLLLLLLRRRRRRRRRRRAAFFFFFFFFFFFFRDDDDDDDMFFLLAMMFFFLFFLMLAAMFAMMMFMFMFAFALLLDLLLLLMMMLLLLDDMLFLLLLLLFLLLLLMLLLLLLDDDDMLLLLLLLLLMLLLLLLLLLLLLLFLLMFLMLLLLLLLLLLLLDDMLLLLLMFFFLLLLMLLLFFLFLLLLLLFNNDDENLMLLLLLLMLLLLMMLLLLLLLLMLLLLLMMLMMMMLMLLLLLLLLLRRFFFDAFFMMMFFMFFMFMDLLLLLLMMMLMMLLLM","n":["board","clear_bss","config","console","drivers","fs","lang_items","mm","print","println","rust_main","sbi","sync","syscall","task","timer","trap","BlockDeviceImpl","CLOCK_FREQ","MEMORY_END","MMIO","CLOCK_FREQ","KERNEL_HEAP_SIZE","KERNEL_STACK_SIZE","MEMORY_END","MMIO","PAGE_SIZE","PAGE_SIZE_BITS","TRAMPOLINE","TRAP_CONTEXT","USER_STACK_SIZE","Stdout","borrow","borrow_mut","from","into","print","try_from","try_into","type_id","write_str","BLOCK_DEVICE","BLOCK_DEVICE","block","BLOCK_DEVICE","VirtIOBlock","__private_field","block_device_test","borrow","borrow_mut","deref","from","into","try_from","try_into","type_id","virtio_blk","QUEUE_FRAMES","VIRTIO0","VirtIOBlock","VirtioHal","__private_field","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","deref","dma_alloc","dma_dealloc","from","from","from","into","into","into","new","phys_to_virt","read_block","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","virt_to_phys","write_block","File","OSInode","OpenFlags","Stdin","Stdout","bits","inner","inode","list_apps","open_file","read","readable","readable","stdio","writable","writable","write","BLOCK_CACHE_SIZE","CREATE","InodeType","OSInode","OSInodeInner","OpenFlags","RDONLY","RDWR","ROOT_INODE","TRUNC","WRONLY","__private_field","all","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bitxor","bitxor_assign","block_id","block_offset","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","cmp","complement","contains","deref","difference","empty","eq","extend","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from_bits","from_bits_truncate","from_bits_unchecked","from_iter","fs","hash","inner","inode","insert","intersection","intersects","into","into","into","into","is_all","is_empty","list_apps","new","not","offset","open_file","partial_cmp","read","read_all","read_write","readable","readable","remove","set","sub","sub_assign","symmetric_difference","to_owned","toggle","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","union","writable","writable","write","Stdin","Stdout","borrow","borrow","borrow_mut","borrow_mut","from","from","into","into","read","read","readable","readable","try_from","try_from","try_into","try_into","type_id","type_id","writable","writable","write","write","panic","FrameTracker","KERNEL_SPACE","KERNEL_SPACE","KERNEL_SPACE","MapPermission","MemorySet","PageTable","PageTableEntry","PhysAddr","PhysPageNum","StepByOne","UserBuffer","UserBufferIterator","VirtAddr","VirtPageNum","__private_field","address","areas","bits","bits","buffers","buffers","current_buffer","current_idx","frame_alloc","frame_allocator","frame_dealloc","frames","heap_allocator","init","kernel_token","memory_set","page_table","page_table","ppn","remap_test","root_ppn","step","translated_byte_buffer","translated_ref","translated_refmut","translated_str","PA_WIDTH_SV39","PPN_WIDTH_SV39","PhysAddr","PhysPageNum","SimpleRange","SimpleRangeIterator","StepByOne","VA_WIDTH_SV39","VPNRange","VPN_WIDTH_SV39","VirtAddr","VirtPageNum","aligned","aligned","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","ceil","ceil","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","current","end","eq","eq","eq","eq","floor","floor","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get_bytes_array","get_end","get_mut","get_mut","get_pte_array","get_ref","get_start","indexes","into","into","into","into","into","into","into_iter","into_iter","l","l","new","new","next","page_offset","page_offset","partial_cmp","partial_cmp","partial_cmp","partial_cmp","r","r","step","step","step","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","FRAME_ALLOCATOR","FrameAllocator","FrameAllocatorImpl","FrameTracker","StackFrameAllocator","__private_field","alloc","alloc","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","current","current","dealloc","dealloc","deref","drop","end","end","fmt","frame_alloc","frame_allocator_test","frame_dealloc","from","from","from","init","init_frame_allocator","into","into","into","new","new","new","ppn","recycled","recycled","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","HEAP_ALLOCATOR","HEAP_SPACE","handle_alloc_error","heap_test","init_heap","Framed","Identical","KERNEL_SPACE","MapArea","MapPermission","MapType","MemorySet","R","U","W","X","__private_field","activate","all","areas","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bitxor","bitxor_assign","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","cmp","complement","contains","copy_data","data_frames","deref","difference","ebss","edata","ekernel","empty","eq","eq","erodata","etext","extend","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from_another","from_bits","from_bits_truncate","from_bits_unchecked","from_elf","from_existed_user","from_iter","hash","insert","insert_framed_area","intersection","intersects","into","into","into","into","into","is_all","is_empty","kernel_token","map","map_one","map_perm","map_trampoline","map_type","new","new_bare","new_kernel","not","page_table","partial_cmp","push","recycle_data_pages","remap_test","remove","remove_area_with_start_vpn","sbss_with_stack","sdata","set","srodata","stext","strampoline","sub","sub_assign","symmetric_difference","to_owned","to_owned","toggle","token","translate","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","union","unmap","unmap_one","vpn_range","A","D","G","PTEFlags","PageTable","PageTableEntry","R","U","UserBuffer","UserBufferIterator","V","W","X","all","bitand","bitand_assign","bitor","bitor_assign","bits","bits","bits","bitxor","bitxor_assign","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","buffers","buffers","clone","clone","clone_into","clone_into","cmp","complement","contains","current_buffer","current_idx","difference","empty","empty","eq","executable","extend","find_pte","find_pte_create","flags","fmt","fmt","fmt","fmt","fmt","frames","from","from","from","from","from","from_bits","from_bits_truncate","from_bits_unchecked","from_iter","from_token","hash","insert","intersection","intersects","into","into","into","into","into","into_iter","into_iter","is_all","is_empty","is_valid","len","map","new","new","new","next","not","partial_cmp","ppn","readable","remove","root_ppn","set","sub","sub_assign","symmetric_difference","to_owned","to_owned","toggle","token","translate","translate_va","translated_byte_buffer","translated_ref","translated_refmut","translated_str","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","union","unmap","writable","console_getchar","console_putchar","set_timer","shutdown","RawExclusiveLock","UPSafeCell","inner","up","RawExclusiveLock","UPSafeCell","borrow","borrow","borrow_mut","borrow_mut","exclusive_access","from","from","inner","into","into","lock","new","try_from","try_from","try_into","try_into","try_lock","type_id","type_id","unlock","SYSCALL_CLOSE","SYSCALL_EXEC","SYSCALL_EXIT","SYSCALL_FORK","SYSCALL_GETPID","SYSCALL_GET_TIME","SYSCALL_OPEN","SYSCALL_READ","SYSCALL_WAITPID","SYSCALL_WRITE","SYSCALL_YIELD","fs","process","syscall","sys_close","sys_open","sys_read","sys_write","sys_exec","sys_exit","sys_fork","sys_get_time","sys_getpid","sys_waitpid","sys_yield","IDLE_PID","INITPROC","KernelStack","PidAllocator","PidHandle","Processor","TaskContext","TaskManager","__private_field","add_initproc","add_task","borrow","borrow_mut","context","current","current","current_task","current_trap_cx","current_user_token","deref","exit_current_and_run_next","fetch_task","from","idle_task_cx","into","manager","pid","pid","pid_alloc","processor","ra","ready_queue","recycled","run_tasks","s","schedule","sp","suspend_current_and_run_next","switch","take_current_task","task","try_from","try_into","type_id","TaskContext","borrow","borrow_mut","from","goto_trap_return","into","ra","s","sp","try_from","try_into","type_id","zero_init","TASK_MANAGER","TaskManager","__private_field","add","add_task","borrow","borrow","borrow_mut","borrow_mut","deref","fetch","fetch_task","from","from","into","into","new","ready_queue","try_from","try_from","try_into","try_into","type_id","type_id","KernelStack","PID_ALLOCATOR","PidAllocator","PidHandle","__private_field","alloc","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","current","dealloc","deref","drop","drop","from","from","from","from","get_top","into","into","into","into","kernel_stack_position","new","new","pid","pid_alloc","push_on_top","recycled","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","PROCESSOR","Processor","__private_field","borrow","borrow","borrow_mut","borrow_mut","current","current","current_task","current_trap_cx","current_user_token","deref","from","from","get_idle_task_cx_ptr","idle_task_cx","into","into","new","run_tasks","schedule","take_current","take_current_task","try_from","try_from","try_into","try_into","type_id","type_id","__switch","Ready","Running","TaskControlBlock","TaskControlBlockInner","TaskStatus","Zombie","alloc_fd","base_size","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","children","clone","clone_into","eq","exec","exit_code","fd_table","fork","from","from","from","get_status","get_trap_cx","get_user_token","getpid","inner","inner_exclusive_access","into","into","into","is_zombie","kernel_stack","memory_set","new","parent","pid","task_cx","task_status","to_owned","trap_cx_ppn","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","MSEC_PER_SEC","TICKS_PER_SEC","get_time","get_time_ms","set_next_trigger","TrapContext","context","enable_timer_interrupt","init","kernel_satp","kernel_sp","sepc","set_kernel_trap_entry","set_user_trap_entry","sstatus","trap_from_kernel","trap_handler","trap_handler","trap_return","x","TrapContext","app_init_context","borrow","borrow_mut","fmt","from","into","kernel_satp","kernel_sp","sepc","set_sp","sstatus","trap_handler","try_from","try_into","type_id","x"],"q":[[0,"os"],[17,"os::board"],[21,"os::config"],[31,"os::console"],[41,"os::drivers"],[44,"os::drivers::block"],[57,"os::drivers::block::virtio_blk"],[91,"os::fs"],[108,"os::fs::inode"],[209,"os::fs::stdio"],[233,"os::lang_items"],[234,"os::mm"],[276,"os::mm::address"],[399,"os::mm::frame_allocator"],[448,"os::mm::heap_allocator"],[453,"os::mm::memory_set"],[586,"os::mm::page_table"],[713,"os::sbi"],[717,"os::sync"],[721,"os::sync::up"],[743,"os::syscall"],[757,"os::syscall::fs"],[761,"os::syscall::process"],[768,"os::task"],[812,"os::task::context"],[825,"os::task::manager"],[849,"os::task::pid"],[896,"os::task::processor"],[926,"os::task::switch"],[927,"os::task::task"],[980,"os::timer"],[985,"os::trap"],[1000,"os::trap::context"],[1017,"core::fmt"],[1018,"core::result"],[1019,"core::any"],[1020,"core::fmt"],[1021,"alloc::sync"],[1022,"alloc::vec"],[1023,"core::option"],[1024,"core::cmp"],[1025,"easy_fs::vfs"],[1026,"core::iter::traits::collect"],[1027,"core::fmt"],[1028,"core::panic::panic_info"],[1029,"alloc::string"],[1030,"core::marker"],[1031,"core::cmp"],[1032,"core::alloc::layout"],[1033,"core::cell"],[1034,"core::marker"]],"d":["","clear BSS segment","Constants used in rCore","SBI console driver, for text output","","File system in os","The panic handler","Memory management implementation","print string macro","println string macro","the rust entry-point of os","SBI call wrappers","Synchronization and interior mutability primitives","Implementation of syscalls","Task management implementation","RISC-V timer-related functionality","Trap handling functionality","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","File trait","A wrapper around a filesystem inode to implement File …","Open file flags","Standard input","Standard output","","","Arc<Inode>
-> OSInodeInner
: In order to open files …","List all files in the filesystems","Open file with flags","Read file to UserBuffer
","If readable","","Stdin & Stdout","If writable","","Write UserBuffer
to file","","Allow create","","A wrapper around a filesystem inode to implement File …","The OS inode inner in ‘UPSafeCell’","Open file flags","Read only","Read & Write","","Clear file and return an empty one","Write only","","Returns the set containing all flags.","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","","Returns the difference between the flags in self
and other
.","Returns an empty set of flags.","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","","","","","","Inserts the specified flags in-place.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","List all files in the filesystems","Construct an OS inode from a inode","Returns the complement of this set of flags.","","Open file with flags","","","Read all data inside a inode into vector","Do not check validity for simplicity Return (readable, …","","","Removes the specified flags in-place.","Inserts or removes the specified flags depending on the …","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","Toggles the specified flags in-place.","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","","","","Standard input","Standard output","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","manage a frame which has the same lifecycle as the tracker","","","a memory set instance through lazy_static! managing kernel …","map permission corresponding to that in pte: R W X U
","memory set structure, controls virtual-memory space","Record root ppn and has the same lifetime as 1 and 2 level …","page table entry structure","Definitions","phiscal page number","Add value by one","Array of u8 slice that user communicate with os","Iterator of UserBuffer
","virtual address","virtual page number","","Implementation of physical and virtual address and page …","","","PTE","U8 vec","","","","allocate a frame","Implementation of FrameAllocator
which controls all the …","deallocate a frame","","The global allocator","initiate heap allocator, frame allocator and kernel space","Get kernelspace root ppn","Implementation of MapArea
and MemorySet
.","Implementation of PageTableEntry
and PageTable
.","","","Check PageTable running correctly","","Add value by one","Translate a pointer to a mutable u8 Vec through page table","Translate a generic through page table and return a …","Translate a generic through page table and return a …","Translate a pointer to a mutable u8 Vec end with \\\\0
…","","","Definitions","phiscal page number","a simple range structure for type T","iterator for the simple range structure","Add value by one","","a simple range structure for virtual page number","","virtual address","virtual page number","Check page aligned","Check page aligned","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","","","","","","","","","","","","","","","","","PhysAddr
->PhysPageNum
","VirtAddr
->VirtPageNum
","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Get u8 array on PhysPageNum
","","Get mutable reference to PhysAddr
value","Get Get mutable reference to PhysAddr
value on PhysPageNum
","Get PageTableEntry
on PhysPageNum
","Get reference to PhysAddr
value","","Return VPN 3 level index","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","Get page offset","Get page offset","","","","","","","Add value by one","","","","","","","","","","","","","","","","","","","","","","","","","","frame allocator instance through lazy_static!","","","manage a frame which has the same lifecycle as the tracker","an implementation for frame allocator","","","","","","","","","","","","","","","","","","","allocate a frame","a simple test for frame allocator","deallocate a frame","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","initiate the frame allocator using ekernel
and MEMORY_END
","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","Create an empty FrameTracker
","","","","","","","","","","","","","","heap allocator instance","heap space ([u8; KERNEL_HEAP_SIZE])","panic when heap allocation error occurs","","initiate heap allocator","","","a memory set instance through lazy_static! managing kernel …","map area structure, controls a contiguous piece of virtual …","map permission corresponding to that in pte: R W X U
","map type for memory set: identical or framed","memory set structure, controls virtual-memory space","Readable","Accessible in U mode","Writable","Excutable","","Refresh TLB with sfence.vma
","Returns the set containing all flags.","","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","data: start-aligned but maybe with shorter length assume …","","","Returns the difference between the flags in self
and other
.","","","","Returns an empty set of flags.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","Include sections in elf and trampoline and TrapContext and …","Clone a same MemorySet
","","","Inserts the specified flags in-place.","Assume that no conflicts.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","Get kernelspace root ppn","","","","Mention that trampoline is not collected by areas.","","","Create an empty MemorySet
","Without kernel stacks.","Returns the complement of this set of flags.","","","","Remove all MapArea
","Check PageTable running correctly","Removes the specified flags in-place.","Remove MapArea
that starts with start_vpn
","","","Inserts or removes the specified flags depending on the …","","","","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","Get pagetable root_ppn
","Translate throuth pagetable","","","","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","","","","","","","","Record root ppn and has the same lifetime as 1 and 2 level …","page table entry structure","","","Array of u8 slice that user communicate with os","Iterator of UserBuffer
","","","","Returns the set containing all flags.","Returns the intersection between the two sets of flags.","Disables all flags disabled in the set.","Returns the union of the two sets of flags.","Adds the set of flags.","Returns the raw value of the flags currently stored.","","PTE","Returns the left flags, but with all the right flags …","Toggles the set of flags.","","","","","","","","","","","U8 vec","","","","","","","Returns the complement of this set of flags.","Returns true
if all of the flags in other
are contained …","","","Returns the difference between the flags in self
and other
.","Returns an empty set of flags.","Return an empty PTE","","Check PTE executable","","Find phsical address by virtual address","Find phsical address by virtual address, create a frame if …","Return 10bit flag","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from underlying bit representation, unless that …","Convert from underlying bit representation, dropping any …","Convert from underlying bit representation, preserving all …","","Temporarily used to get arguments from user space.","","Inserts the specified flags in-place.","Returns the intersection between the flags in self
and …","Returns true
if there are flags common to both self
and …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","Returns true
if all flags are currently set.","Returns true
if no flags are currently stored.","Check PTE valid","Length of UserBuffer
","Create a mapping form vpn
to ppn
","Create an empty PageTable
","Create a UserBuffer
by parameter","Create a PTE from ppn","","Returns the complement of this set of flags.","","Return 44bit ppn","Check PTE readable","Removes the specified flags in-place.","","Inserts or removes the specified flags depending on the …","Returns the set difference of the two sets of flags.","Disables all flags enabled in the set.","Returns the symmetric difference between the flags in self
…","","","Toggles the specified flags in-place.","Get root ppn","Translate VirtPageNum
to PageTableEntry
","Translate VirtAddr
to PhysAddr
","Translate a pointer to a mutable u8 Vec through page table","Translate a generic through page table and return a …","Translate a generic through page table and return a …","Translate a pointer to a mutable u8 Vec end with \\\\0
…","","","","","","","","","","","","","","","","Returns the union of between the flags in self
and other
.","Delete a mapping form vpn
","Check PTE writable","use sbi call to getchar from console (qemu uart handler)","use sbi call to putchar in console (qemu uart handler)","use sbi call to set timer","use sbi call to shutdown the kernel","The sync primitive used by easy-fs.","Wrap a static data structure inside it so that we are able …","inner data","Uniprocessor interior mutability primitives","The sync primitive used by easy-fs.","Wrap a static data structure inside it so that we are able …","","","","","Exclusive access inner data in UPSafeCell. Panic if the …","Returns the argument unchanged.","Returns the argument unchanged.","inner data","Calls U::from(self)
.","Calls U::from(self)
.","","User is responsible to guarantee that inner struct is only …","","","","","","","","","","","","","","","","","","","","File and filesystem-related syscalls","","handle syscall exception with syscall_id
and other …","","","","","","","","","","If there is not a child process whose pid is same as …","","pid of usertests app in make run TEST=1","Globle process that init user shell","Kernelstack for app","Pid Allocator struct","Bind pid lifetime to PidHandle
","Processor management structure","task context structure containing some registers","A array of TaskControlBlock
that is thread-safe","","Add init process to the manager","Interface offered to add task","","","Implementation of TaskContext
","","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Exit the current ‘Running’ task and run the next task …","Interface offered to pop the first task","Returns the argument unchanged.","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Implementation of TaskManager
","Implementation of PidAllocator
","","Allocate a pid from PID_ALLOCATOR","Implementation of Processor
and Intersection of control …","return address ( e.g. __restore ) of __switch ASM function","","","The main part of process execution and scheduling Loop …","s0-11 register, callee saved","Return to idle control flow for new scheduling","kernel stack pointer of app","Suspend the current ‘Running’ task and run the next …","Wrap switch.S
as a function","Take the current task,leaving a None in its place","Implementation of TaskControlBlock
","","","","task context structure containing some registers","","","Returns the argument unchanged.","set Task Context{__restore ASM funciton: trap_return, sp: …","Calls U::from(self)
.","return address ( e.g. __restore ) of __switch ASM function","s0-11 register, callee saved","kernel stack pointer of app","","","","init task context","","A array of TaskControlBlock
that is thread-safe","","Add a task to TaskManager
","Interface offered to add task","","","","","","Remove the first task and return it,or None
if TaskManager
…","Interface offered to pop the first task","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","Creat an empty TaskManager","","","","","","","","Kernelstack for app","","Pid Allocator struct","Bind pid lifetime to PidHandle
","","Allocate a pid","","","","","","","","","","Recycle a pid","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Get the value on the top of kernelstack","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Return (bottom, top) of a kernel stack in kernel space.","Create an empty PidAllocator
","Create a kernelstack from pid","","Allocate a pid from PID_ALLOCATOR","Push a value on top of kernelstack","","","","","","","","","","","","","","","Processor management structure","","","","","","Get current task in cloning semanteme","The task currently executing on the current processor","Get running task","Get the mutable reference to trap context of current task","Get token of the address space of current task","","Returns the argument unchanged.","Returns the argument unchanged.","Get mutable reference to idle_task_cx
","The basic control flow of each core, helping to select and …","Calls U::from(self)
.","Calls U::from(self)
.","Create an empty Processor","The main part of process execution and scheduling Loop …","Return to idle control flow for new scheduling","Get current task in moving semanteme","Take the current task,leaving a None in its place","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","","","get current time","get current time in microseconds","set the next timer interrupt","trap context structure containing sstatus, sepc and …","Implementation of TrapContext
","enable timer interrupt in sie CSR","initialize CSR stvec
as the entry of __alltraps
","Addr of Page Table","kernel stack","CSR sepc","","","CSR sstatus ","Unimplement: traps/interrupts/exceptions from kernel mode …","handle an interrupt, exception, or system call from user …","Addr of trap_handler function","set the new addr of __restore asm function in TRAMPOLINE …","general regs[0..31]","trap context structure containing sstatus, sepc and …","init app context","","","","Returns the argument unchanged.","Calls U::from(self)
.","Addr of Page Table","kernel stack","CSR sepc","set stack pointer to x_2 reg (sp)","CSR sstatus ","Addr of trap_handler function","","","","general regs[0..31]"],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,0,6,6,6,6,0,0,0,0,0,9,0,9,9,9,9,9,9,9,9,0,0,0,0,0,12,18,80,12,18,80,12,12,80,80,18,80,12,18,80,12,18,80,18,18,80,12,18,80,12,18,80,12,80,18,0,0,0,0,0,21,22,0,0,0,81,81,22,0,81,22,81,0,21,0,0,0,0,21,21,0,21,21,28,21,21,21,21,21,21,21,21,21,82,82,22,83,28,21,22,83,28,21,21,21,21,21,21,28,21,21,21,21,21,21,21,21,21,22,83,28,21,21,21,21,21,82,21,22,83,21,21,21,22,83,28,21,21,21,0,22,21,83,0,21,22,22,21,22,22,21,21,21,21,21,21,21,22,83,28,21,22,83,28,21,22,83,28,21,21,22,22,22,0,0,34,35,34,35,34,35,34,35,34,35,34,35,34,35,34,35,34,35,34,35,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,0,55,56,49,24,62,62,62,0,0,0,59,0,0,0,0,0,55,13,0,59,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,40,51,39,40,37,41,42,51,39,40,37,41,42,39,40,39,40,37,41,42,39,40,37,41,42,39,40,37,41,51,51,39,40,37,41,39,40,39,40,37,41,51,39,39,39,40,40,40,37,37,37,41,41,41,42,37,42,39,37,37,39,42,41,51,39,40,37,41,42,51,42,84,42,51,42,51,39,40,39,40,37,41,84,42,43,37,41,39,40,37,41,42,51,39,40,37,41,42,51,39,40,37,41,42,51,39,40,37,41,42,0,0,0,0,0,53,85,52,13,52,53,13,52,53,52,86,85,52,53,13,52,86,13,0,0,0,13,52,53,52,0,13,52,53,85,13,52,13,52,86,13,52,53,13,52,53,13,52,53,0,0,0,0,0,57,57,0,0,0,0,0,56,56,56,56,60,55,56,55,56,56,56,56,56,56,56,56,55,58,60,57,56,55,58,60,57,56,57,56,57,56,56,56,56,58,58,60,56,0,0,0,56,57,56,0,0,56,57,56,56,56,56,56,55,58,60,57,56,58,56,56,56,55,55,56,56,56,55,56,56,55,58,60,57,56,56,56,0,58,58,58,55,58,58,55,55,56,55,56,55,55,0,56,55,0,0,56,0,0,0,56,56,56,57,56,56,55,55,55,58,60,57,56,55,58,60,57,56,55,58,60,57,56,56,58,58,58,61,61,61,0,0,0,61,61,0,0,61,61,61,61,61,61,61,61,61,61,49,61,61,59,24,62,61,49,59,24,62,61,49,24,62,61,49,61,49,61,61,61,62,62,61,61,49,61,49,61,59,59,49,61,61,61,61,61,59,59,24,62,61,49,61,61,61,61,59,61,61,61,61,59,24,62,61,49,24,62,61,61,49,24,59,59,24,49,62,61,61,49,49,61,59,61,61,61,61,61,49,61,59,59,59,0,0,0,0,59,24,62,61,49,59,24,62,61,49,59,24,62,61,49,61,59,49,0,0,0,0,0,0,15,0,0,0,15,29,15,29,15,15,29,15,15,29,29,15,15,29,15,29,29,15,29,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,0,0,67,67,0,72,76,0,0,0,67,0,0,67,76,67,0,0,74,0,0,69,70,72,0,69,0,69,0,0,0,0,67,67,67,0,69,69,69,69,69,69,69,69,69,69,69,69,0,0,71,70,0,70,71,70,71,71,70,0,70,71,70,71,70,70,70,71,70,71,70,71,0,0,0,0,73,72,72,68,74,73,72,68,74,73,72,72,73,68,74,72,68,74,73,74,72,68,74,73,0,72,74,74,0,74,72,72,68,74,73,72,68,74,73,72,68,74,73,0,0,77,76,77,76,77,76,76,0,0,0,77,76,77,76,76,76,77,76,0,0,76,0,76,77,76,77,76,77,0,79,79,0,0,0,79,78,78,65,78,79,65,78,79,78,79,79,79,65,78,78,65,65,78,79,78,78,78,65,65,65,65,78,79,78,65,78,65,78,65,78,78,79,78,65,78,79,65,78,79,65,78,79,0,0,0,0,0,0,0,0,0,66,66,66,0,0,66,0,0,66,0,66,0,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66],"f":[0,[[],1],0,0,0,0,0,0,0,0,[[],2],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-1,[]],[-1,-2,[],[]],[3,1],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[[6,7],8],0,0,0,0,0,0,[[],1],[-1,-2,[],[]],[-1,-2,[],[]],[9,[[11,[10]]]],[-1,-1,[]],[-1,-2,[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[12,[[15,[[14,[13]]]]]],[16,16],[[16,16],17],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],18],[16,16],[[18,16,[20,[19]]],1],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[16,16],[[18,16,[20,[19]]],1],0,0,0,0,0,0,0,0,[[],1],[[7,21],[[23,[[11,[22]]]]]],[[-1,24],16,[]],[-1,25,[]],0,0,[-1,25,[]],0,[[-1,24],16,[]],0,0,0,0,0,0,0,0,0,0,0,0,[[],21],[[21,21],21],[[21,21],1],[[21,21],21],[[21,21],1],[21,26],0,[[21,21],21],[[21,21],1],0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[21,21],[[-1,-2],1,[],[]],[[21,21],27],[21,21],[[21,21],25],[28,[[11,[[30,[29,29,29]]]]]],[[21,21],21],[[],21],[[21,21],25],[[21,-1],1,31],[[21,32],8],[[21,32],8],[[21,32],8],[[21,32],8],[[21,32],8],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[26,[[23,[21]]]],[26,21],[26,21],[-1,21,31],0,[[21,-1],1,33],0,0,[[21,21],1],[[21,21],21],[[21,21],25],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[21,25],[21,25],[[],1],[[25,25,[11,[[30,[29,29,29]]]]],22],[21,21],0,[[7,21],[[23,[[11,[22]]]]]],[[21,21],[[23,[27]]]],[[22,24],16],[22,[[14,[19]]]],[21,[[1,[25,25]]]],[22,25],0,[[21,21],1],[[21,21,25],1],[[21,21],21],[[21,21],1],[[21,21],21],[-1,-2,[],[]],[[21,21],1],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[[21,21],21],[22,25],0,[[22,24],16],0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[[34,24],16],[[35,24],16],[34,25],[35,25],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[34,25],[35,25],[[34,24],16],[[35,24],16],[36,2],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],[[23,[13]]]],0,[37,1],0,0,[[],1],[[],16],0,0,0,0,[[],1],0,[-1,1,[]],[[16,19,16],[[14,[[20,[19]]]]]],[16,-1,[]],[16,-1,[]],[[16,19],38],0,0,0,0,0,0,0,0,0,0,0,0,[39,25],[40,25],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[39,37],[40,41],[39,39],[40,40],[37,37],[41,41],[[[42,[-1]]],[[42,[-1]]],[43,44,45,46,47,48]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[39,39],27],[[40,40],27],[[37,37],27],[[41,41],27],0,0,[[39,39],25],[[40,40],25],[[37,37],25],[[41,41],25],[39,37],[40,41],[[39,32],8],[[40,32],8],[[37,32],8],[[41,32],8],[-1,-1,[]],[37,39],[-1,-1,[]],[16,39],[41,40],[-1,-1,[]],[16,40],[16,37],[39,37],[-1,-1,[]],[-1,-1,[]],[16,41],[40,41],[-1,-1,[]],[37,[[20,[19]]]],[[[42,[-1]]],-1,[43,44,45,46,47]],[39,-1,[]],[37,-1,[]],[37,[[20,[49]]]],[39,-1,[]],[[[42,[-1]]],-1,[43,44,45,46,47]],[41,[[50,[16]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[[42,[-1]]],[],[43,44,45,46,47]],0,0,[[-1,-1],[[51,[-1]]],[43,44,45,46,47]],[[-1,-1],[[42,[-1]]],[43,44,45,46,47]],[[[51,[-1]]],23,[43,44,45,46,47]],[39,16],[40,16],[[39,39],[[23,[27]]]],[[40,40],[[23,[27]]]],[[37,37],[[23,[27]]]],[[41,41],[[23,[27]]]],0,0,[-1,1,[]],[37,1],[41,1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,0,0,0,0,[-1,[[23,[37]]],[]],[52,[[23,[37]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,0,[[-1,37],1,[]],[[52,37],1],[53,[[15,[52]]]],[13,1],0,0,[[13,32],8],[[],[[23,[13]]]],[[],1],[37,1],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[[52,37,37],1],[[],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],-1,[]],[37,13],[[],52],0,0,0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,[54,2],[[],1],[[],1],0,0,0,0,0,0,0,0,0,0,0,0,[55,1],[[],56],0,[[56,56],56],[[56,56],1],[[56,56],56],[[56,56],1],[56,19],0,[[56,56],56],[[56,56],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[57,57],[56,56],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[56,56],27],[56,56],[[56,56],25],[[58,59,[20,[19]]],1],0,[60,[[11,[[15,[55]]]]]],[[56,56],56],0,0,0,[[],56],[[57,57],25],[[56,56],25],0,0,[[56,-1],1,31],[[57,32],8],[[56,32],8],[[56,32],8],[[56,32],8],[[56,32],8],[[56,32],8],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[58,58],[19,[[23,[56]]]],[19,56],[19,56],[[[20,[19]]],[[1,[55,16,16]]]],[55,55],[-1,56,31],[[56,-1],1,33],[[56,56],1],[[55,40,40,56],1],[[56,56],56],[[56,56],25],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[56,25],[56,25],[[],16],[[58,59],1],[[58,59,41],1],0,[55,1],0,[[40,40,57,56],58],[[],55],[[],55],[56,56],0,[[56,56],[[23,[27]]]],[[55,58,[23,[[20,[19]]]]],1],[55,1],[[],1],[[56,56],1],[[55,41],1],0,0,[[56,56,25],1],0,0,0,[[56,56],56],[[56,56],1],[[56,56],56],[-1,-2,[],[]],[-1,-2,[],[]],[[56,56],1],[55,16],[[55,41],[[23,[49]]]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[[56,56],56],[[58,59],1],[[58,59,41],1],0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],61],[[61,61],61],[[61,61],1],[[61,61],61],[[61,61],1],[61,19],0,0,[[61,61],61],[[61,61],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,0,[61,61],[49,49],[[-1,-2],1,[],[]],[[-1,-2],1,[],[]],[[61,61],27],[61,61],[[61,61],25],0,0,[[61,61],61],[[],61],[[],49],[[61,61],25],[49,25],[[61,-1],1,31],[[59,41],[[23,[49]]]],[[59,41],[[23,[49]]]],[49,61],[[61,32],8],[[61,32],8],[[61,32],8],[[61,32],8],[[61,32],8],0,[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[19,[[23,[61]]]],[19,61],[19,61],[-1,61,31],[16,59],[[61,-1],1,33],[[61,61],1],[[61,61],61],[[61,61],25],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[24],[-1,-2,[],[]],[61,25],[61,25],[49,25],[24,16],[[59,41,37,61],1],[[],59],[[[14,[[20,[19]]]]],24],[[37,61],49],[62,23],[61,61],[[61,61],[[23,[27]]]],[49,37],[49,25],[[61,61],1],0,[[61,61,25],1],[[61,61],61],[[61,61],1],[[61,61],61],[-1,-2,[],[]],[-1,-2,[],[]],[[61,61],1],[59,16],[[59,41],[[23,[49]]]],[[59,40],[[23,[39]]]],[[16,19,16],[[14,[[20,[19]]]]]],[16,-1,[]],[16,-1,[]],[[16,19],38],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[[61,61],61],[[59,41],1],[49,25],[[],16],[16,1],[16,1],[25,2],0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[[15,[-1]]],[[63,[-1]]],[]],[-1,-1,[]],[-1,-1,[]],0,[-1,-2,[],[]],[-1,-2,[],[]],[29,1],[-1,[[15,[-1]]],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[29,25],[-1,5,[]],[-1,5,[]],[29,1],0,0,0,0,0,0,0,0,0,0,0,0,0,[[16,[50,[16]]],64],[16,64],[[19,26],64],[[16,19,16],64],[[16,19,16],64],[19,64],[17,2],[[],64],[[],64],[[],64],[[64,17],64],[[],64],0,0,0,0,0,0,0,0,0,[[],1],[[[11,[65]]],1],[-1,-2,[],[]],[-1,-2,[],[]],0,0,0,[[],[[23,[[11,[65]]]]]],[[],66],[[],16],[67,[[11,[65]]]],[17,1],[[],[[23,[[11,[65]]]]]],[-1,-1,[]],0,[-1,-2,[],[]],0,0,0,[[],68],0,0,0,0,[[],1],0,[69,1],0,[[],1],0,[[],[[23,[[11,[65]]]]]],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-1,[]],[16,69],[-1,-2,[],[]],0,0,0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[[],69],0,0,0,[[70,[11,[65]]],1],[[[11,[65]]],1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[71,[[15,[70]]]],[70,[[23,[[11,[65]]]]]],[[],[[23,[[11,[65]]]]]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],70],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],0,0,0,0,0,[72,68],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,[[72,16],1],[73,[[15,[72]]]],[68,1],[74,1],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[74,16],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[16,[[1,[16,16]]]],[[],72],[68,74],0,[[],68],[[74,-1],[],75],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[76,[[23,[[11,[65]]]]]],0,[[],[[23,[[11,[65]]]]]],[[],66],[[],16],[77,[[15,[76]]]],[-1,-1,[]],[-1,-1,[]],[76,69],0,[-1,-2,[],[]],[-1,-2,[],[]],[[],76],[[],1],[69,1],[76,[[23,[[11,[65]]]]]],[[],[[23,[[11,[65]]]]]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],0,0,0,0,0,0,0,[78,16],0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],0,[79,79],[[-1,-2],1,[],[]],[[79,79],25],[[65,[20,[19]]],1],0,0,[[[11,[65]]],[[11,[65]]]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[78,79],[78,66],[78,16],[65,16],0,[65,[[63,[78]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[78,25],0,0,[[[20,[19]]],65],0,0,0,0,[-1,-2,[],[]],0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],0,0,[[],16],[[],16],[[],1],0,0,[[],1],[[],1],0,0,0,[[],1],[[],1],0,[[],2],[[],2],0,[[],2],0,0,[[16,16,16,16,16],66],[-1,-2,[],[]],[-1,-2,[],[]],[[66,32],8],[-1,-1,[]],[-1,-2,[],[]],0,0,0,[[66,16],1],0,0,[-1,[[4,[-2]]],[],[]],[-1,[[4,[-2]]],[],[]],[-1,5,[]],0],"c":[],"p":[[15,"tuple"],[15,"never"],[3,"Arguments",1017],[4,"Result",1018],[3,"TypeId",1019],[3,"Stdout",31],[15,"str"],[6,"Result",1017],[3,"BLOCK_DEVICE",44],[8,"BlockDevice",1020],[3,"Arc",1021],[3,"QUEUE_FRAMES",57],[3,"FrameTracker",399],[3,"Vec",1022],[3,"UPSafeCell",721],[15,"usize"],[15,"i32"],[3,"VirtIOBlock",57],[15,"u8"],[15,"slice"],[3,"OpenFlags",108],[3,"OSInode",108],[4,"Option",1023],[3,"UserBuffer",586],[15,"bool"],[15,"u32"],[4,"Ordering",1024],[3,"ROOT_INODE",108],[3,"RawExclusiveLock",721],[3,"Inode",1025],[8,"IntoIterator",1026],[3,"Formatter",1017],[8,"Hasher",1027],[3,"Stdin",209],[3,"Stdout",209],[3,"PanicInfo",1028],[3,"PhysPageNum",276],[3,"String",1029],[3,"PhysAddr",276],[3,"VirtAddr",276],[3,"VirtPageNum",276],[3,"SimpleRange",276],[8,"StepByOne",276],[8,"Copy",1030],[8,"PartialEq",1024],[8,"PartialOrd",1024],[8,"Debug",1017],[8,"Clone",1031],[3,"PageTableEntry",586],[15,"array"],[3,"SimpleRangeIterator",276],[3,"StackFrameAllocator",399],[3,"FRAME_ALLOCATOR",399],[3,"Layout",1032],[3,"MemorySet",453],[3,"MapPermission",453],[4,"MapType",453],[3,"MapArea",453],[3,"PageTable",586],[3,"KERNEL_SPACE",453],[3,"PTEFlags",586],[3,"UserBufferIterator",586],[3,"RefMut",1033],[15,"isize"],[3,"TaskControlBlock",927],[3,"TrapContext",1000],[3,"INITPROC",768],[3,"PidHandle",849],[3,"TaskContext",812],[3,"TaskManager",825],[3,"TASK_MANAGER",825],[3,"PidAllocator",849],[3,"PID_ALLOCATOR",849],[3,"KernelStack",849],[8,"Sized",1030],[3,"Processor",896],[3,"PROCESSOR",896],[3,"TaskControlBlockInner",927],[4,"TaskStatus",927],[3,"VirtioHal",57],[8,"File",91],[6,"InodeType",108],[3,"OSInodeInner",108],[6,"VPNRange",276],[8,"FrameAllocator",399],[6,"FrameAllocatorImpl",399]]}\
}');
-if (window.initSearch) {window.initSearch(searchIndex)};
\ No newline at end of file
+if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
+if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
diff --git a/ch6-dev/search.js b/ch6-dev/search.js
deleted file mode 100644
index a8026db5..00000000
--- a/ch6-dev/search.js
+++ /dev/null
@@ -1,2 +0,0 @@
-(function(){var itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");function printTab(nb){if(nb===0||nb===1||nb===2){searchState.currentTab=nb}var nb_copy=nb;onEachLazy(document.getElementById("titles").childNodes,function(elem){if(nb_copy===0){addClass(elem,"selected")}else{removeClass(elem,"selected")}nb_copy-=1});onEachLazy(document.getElementById("results").childNodes,function(elem){if(nb===0){addClass(elem,"active")}else{removeClass(elem,"active")}nb-=1})}function removeEmptyStringsFromArray(x){for(var i=0,len=x.length;i1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -
pub const CLOCK_FREQ: usize = 12500000;
-pub const MEMORY_END: usize = 0x801000000;
+qemu.rs - source pub const CLOCK_FREQ: usize = 12500000;
+pub const MEMORY_END: usize = 0x88000000;
-pub const MMIO: &[(usize, usize)] = &[
- (0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine
- (0x1000_1000, 0x00_1000), // Virtio Block in virt machine
-];
+pub const MMIO: &[(usize, usize)] = &[
+ (0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine
+ (0x1000_1000, 0x00_1000), // Virtio Block in virt machine
+];
-pub type BlockDeviceImpl = crate::drivers::block::VirtIOBlock;
-
-//ref:: https://github.com/andre-richter/qemu-exit
-use core::arch::asm;
-
-const EXIT_SUCCESS: u32 = 0x5555; // Equals `exit(0)`. qemu successful exit
-
-const EXIT_FAILURE_FLAG: u32 = 0x3333;
-const EXIT_FAILURE: u32 = exit_code_encode(1); // Equals `exit(1)`. qemu failed exit
-const EXIT_RESET: u32 = 0x7777; // qemu reset
-
-pub trait QEMUExit {
- /// Exit with specified return code.
- ///
- /// Note: For `X86`, code is binary-OR'ed with `0x1` inside QEMU.
- fn exit(&self, code: u32) -> !;
-
- /// Exit QEMU using `EXIT_SUCCESS`, aka `0`, if possible.
- ///
- /// Note: Not possible for `X86`.
- fn exit_success(&self) -> !;
-
- /// Exit QEMU using `EXIT_FAILURE`, aka `1`.
- fn exit_failure(&self) -> !;
-}
-
-/// RISCV64 configuration
-pub struct RISCV64 {
- /// Address of the sifive_test mapped device.
- addr: u64,
-}
-
-/// Encode the exit code using EXIT_FAILURE_FLAG.
-const fn exit_code_encode(code: u32) -> u32 {
- (code << 16) | EXIT_FAILURE_FLAG
-}
-
-impl RISCV64 {
- /// Create an instance.
- pub const fn new(addr: u64) -> Self {
- RISCV64 { addr }
- }
-}
-
-impl QEMUExit for RISCV64 {
- /// Exit qemu with specified exit code.
- fn exit(&self, code: u32) -> ! {
- // If code is not a special value, we need to encode it with EXIT_FAILURE_FLAG.
- let code_new = match code {
- EXIT_SUCCESS | EXIT_FAILURE | EXIT_RESET => code,
- _ => exit_code_encode(code),
- };
-
- unsafe {
- asm!(
- "sw {0}, 0({1})",
- in(reg)code_new, in(reg)self.addr
- );
-
- // For the case that the QEMU exit attempt did not work, transition into an infinite
- // loop. Calling `panic!()` here is unfeasible, since there is a good chance
- // this function here is the last expression in the `panic!()` handler
- // itself. This prevents a possible infinite loop.
- loop {
- asm!("wfi", options(nomem, nostack));
- }
- }
- }
-
- fn exit_success(&self) -> ! {
- self.exit(EXIT_SUCCESS);
- }
-
- fn exit_failure(&self) -> ! {
- self.exit(EXIT_FAILURE);
- }
-}
-
-const VIRT_TEST: u64 = 0x100000;
-
-pub const QEMU_EXIT_HANDLE: RISCV64 = RISCV64::new(VIRT_TEST);
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -
//! Constants used in rCore
-#[allow(unused)]
+config.rs - source //! Constants used in rCore
+#[allow(unused)]
-pub const USER_STACK_SIZE: usize = 4096 * 2;
-pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
-pub const KERNEL_HEAP_SIZE: usize = 0x20_0000;
+pub const USER_STACK_SIZE: usize = 4096 * 2;
+pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
+pub const KERNEL_HEAP_SIZE: usize = 0x20_0000;
-pub const PAGE_SIZE: usize = 0x1000;
-pub const PAGE_SIZE_BITS: usize = 0xc;
+pub const PAGE_SIZE: usize = 0x1000;
+pub const PAGE_SIZE_BITS: usize = 0xc;
-pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1;
-pub const TRAP_CONTEXT: usize = TRAMPOLINE - PAGE_SIZE;
+pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1;
+pub const TRAP_CONTEXT: usize = TRAMPOLINE - PAGE_SIZE;
-pub use crate::board::{CLOCK_FREQ, MEMORY_END, MMIO};
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -
//! SBI console driver, for text output
-use crate::sbi::console_putchar;
-use core::fmt::{self, Write};
+console.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+
//! SBI console driver, for text output
+use crate::sbi::console_putchar;
+use core::fmt::{self, Write};
-struct Stdout;
+struct Stdout;
-impl Write for Stdout {
- fn write_str(&mut self, s: &str) -> fmt::Result {
- for c in s.chars() {
- console_putchar(c as usize);
+impl Write for Stdout {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ for c in s.chars() {
+ console_putchar(c as usize);
}
Ok(())
}
}
-pub fn print(args: fmt::Arguments) {
- Stdout.write_fmt(args).unwrap();
+pub fn print(args: fmt::Arguments) {
+ Stdout.write_fmt(args).unwrap();
}
-#[macro_export]
-/// print string macro
-macro_rules! print {
- ($fmt: literal $(, $($arg: tt)+)?) => {
- $crate::console::print(format_args!($fmt $(, $($arg)+)?));
+#[macro_export]
+/// print string macro
+macro_rules! print {
+ ($fmt: literal $(, $($arg: tt)+)?) => {
+ $crate::console::print(format_args!($fmt $(, $($arg)+)?));
}
}
-#[macro_export]
-/// println string macro
-macro_rules! println {
- ($fmt: literal $(, $($arg: tt)+)?) => {
- $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
+#[macro_export]
+/// println string macro
+macro_rules! println {
+ ($fmt: literal $(, $($arg: tt)+)?) => {
+ $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -
mod sdcard;
-mod virtio_blk;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+
mod virtio_blk;
-pub use sdcard::SDCardWrapper;
-pub use virtio_blk::VirtIOBlock;
+pub use virtio_blk::VirtIOBlock;
-use crate::board::BlockDeviceImpl;
-use alloc::sync::Arc;
-use easy_fs::BlockDevice;
-use lazy_static::*;
+use crate::board::BlockDeviceImpl;
+use alloc::sync::Arc;
+use easy_fs::BlockDevice;
+use lazy_static::*;
-lazy_static! {
- pub static ref BLOCK_DEVICE: Arc<dyn BlockDevice> = Arc::new(BlockDeviceImpl::new());
+lazy_static! {
+ pub static ref BLOCK_DEVICE: Arc<dyn BlockDevice> = Arc::new(BlockDeviceImpl::new());
}
-#[allow(unused)]
-pub fn block_device_test() {
- let block_device = BLOCK_DEVICE.clone();
- let mut write_buffer = [0u8; 512];
- let mut read_buffer = [0u8; 512];
- for i in 0..512 {
- for byte in write_buffer.iter_mut() {
- *byte = i as u8;
+#[allow(unused)]
+pub fn block_device_test() {
+ let block_device = BLOCK_DEVICE.clone();
+ let mut write_buffer = [0u8; 512];
+ let mut read_buffer = [0u8; 512];
+ for i in 0..512 {
+ for byte in write_buffer.iter_mut() {
+ *byte = i as u8;
}
- block_device.write_block(i as usize, &write_buffer);
- block_device.read_block(i as usize, &mut read_buffer);
- assert_eq!(write_buffer, read_buffer);
+ block_device.write_block(i as usize, &write_buffer);
+ block_device.read_block(i as usize, &mut read_buffer);
+ assert_eq!(write_buffer, read_buffer);
}
println!("block device test passed!");
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -
#![allow(non_snake_case)]
-#![allow(non_camel_case_types)]
-#![allow(unused)]
-
-use super::BlockDevice;
-use crate::sync::UPSafeCell;
-use core::convert::TryInto;
-use k210_hal::prelude::*;
-use k210_pac::{Peripherals, SPI0};
-use k210_soc::{
- fpioa::{self, io},
- //dmac::{dma_channel, DMAC, DMACExt},
- gpio,
- gpiohs,
- sleep::usleep,
- spi::{aitm, frame_format, tmod, work_mode, SPIExt, SPIImpl, SPI},
- sysctl,
-};
-use lazy_static::*;
-
-pub struct SDCard<SPI> {
- spi: SPI,
- spi_cs: u32,
- cs_gpionum: u8,
- //dmac: &'a DMAC,
- //channel: dma_channel,
-}
-
-/*
- * Start Data tokens:
- * Tokens (necessary because at nop/idle (and CS active) only 0xff is
- * on the data/command line)
- */
-/** Data token start byte, Start Single Block Read */
-pub const SD_START_DATA_SINGLE_BLOCK_READ: u8 = 0xFE;
-/** Data token start byte, Start Multiple Block Read */
-pub const SD_START_DATA_MULTIPLE_BLOCK_READ: u8 = 0xFE;
-/** Data token start byte, Start Single Block Write */
-pub const SD_START_DATA_SINGLE_BLOCK_WRITE: u8 = 0xFE;
-/** Data token start byte, Start Multiple Block Write */
-pub const SD_START_DATA_MULTIPLE_BLOCK_WRITE: u8 = 0xFC;
-
-pub const SEC_LEN: usize = 512;
-
-/** SD commands */
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-#[allow(unused)]
-pub enum CMD {
- /** Software reset */
- CMD0 = 0,
- /** Check voltage range (SDC V2) */
- CMD8 = 8,
- /** Read CSD register */
- CMD9 = 9,
- /** Read CID register */
- CMD10 = 10,
- /** Stop to read data */
- CMD12 = 12,
- /** Change R/W block size */
- CMD16 = 16,
- /** Read block */
- CMD17 = 17,
- /** Read multiple blocks */
- CMD18 = 18,
- /** Number of blocks to erase (SDC) */
- ACMD23 = 23,
- /** Write a block */
- CMD24 = 24,
- /** Write multiple blocks */
- CMD25 = 25,
- /** Initiate initialization process (SDC) */
- ACMD41 = 41,
- /** Leading command for ACMD* */
- CMD55 = 55,
- /** Read OCR */
- CMD58 = 58,
- /** Enable/disable CRC check */
- CMD59 = 59,
-}
-
-#[allow(unused)]
-#[derive(Debug, Copy, Clone)]
-pub enum InitError {
- CMDFailed(CMD, u8),
- CardCapacityStatusNotSet([u8; 4]),
- CannotGetCardInfo,
-}
-
-/**
- * Card Specific Data: CSD Register
- */
-#[derive(Debug, Copy, Clone)]
-pub struct SDCardCSD {
- pub CSDStruct: u8, /* CSD structure */
- pub SysSpecVersion: u8, /* System specification version */
- pub Reserved1: u8, /* Reserved */
- pub TAAC: u8, /* Data read access-time 1 */
- pub NSAC: u8, /* Data read access-time 2 in CLK cycles */
- pub MaxBusClkFrec: u8, /* Max. bus clock frequency */
- pub CardComdClasses: u16, /* Card command classes */
- pub RdBlockLen: u8, /* Max. read data block length */
- pub PartBlockRead: u8, /* Partial blocks for read allowed */
- pub WrBlockMisalign: u8, /* Write block misalignment */
- pub RdBlockMisalign: u8, /* Read block misalignment */
- pub DSRImpl: u8, /* DSR implemented */
- pub Reserved2: u8, /* Reserved */
- pub DeviceSize: u32, /* Device Size */
- //MaxRdCurrentVDDMin: u8, /* Max. read current @ VDD min */
- //MaxRdCurrentVDDMax: u8, /* Max. read current @ VDD max */
- //MaxWrCurrentVDDMin: u8, /* Max. write current @ VDD min */
- //MaxWrCurrentVDDMax: u8, /* Max. write current @ VDD max */
- //DeviceSizeMul: u8, /* Device size multiplier */
- pub EraseGrSize: u8, /* Erase group size */
- pub EraseGrMul: u8, /* Erase group size multiplier */
- pub WrProtectGrSize: u8, /* Write protect group size */
- pub WrProtectGrEnable: u8, /* Write protect group enable */
- pub ManDeflECC: u8, /* Manufacturer default ECC */
- pub WrSpeedFact: u8, /* Write speed factor */
- pub MaxWrBlockLen: u8, /* Max. write data block length */
- pub WriteBlockPaPartial: u8, /* Partial blocks for write allowed */
- pub Reserved3: u8, /* Reserded */
- pub ContentProtectAppli: u8, /* Content protection application */
- pub FileFormatGroup: u8, /* File format group */
- pub CopyFlag: u8, /* Copy flag (OTP) */
- pub PermWrProtect: u8, /* Permanent write protection */
- pub TempWrProtect: u8, /* Temporary write protection */
- pub FileFormat: u8, /* File Format */
- pub ECC: u8, /* ECC code */
- pub CSD_CRC: u8, /* CSD CRC */
- pub Reserved4: u8, /* always 1*/
-}
-
-/**
- * Card Identification Data: CID Register
- */
-#[derive(Debug, Copy, Clone)]
-pub struct SDCardCID {
- pub ManufacturerID: u8, /* ManufacturerID */
- pub OEM_AppliID: u16, /* OEM/Application ID */
- pub ProdName1: u32, /* Product Name part1 */
- pub ProdName2: u8, /* Product Name part2*/
- pub ProdRev: u8, /* Product Revision */
- pub ProdSN: u32, /* Product Serial Number */
- pub Reserved1: u8, /* Reserved1 */
- pub ManufactDate: u16, /* Manufacturing Date */
- pub CID_CRC: u8, /* CID CRC */
- pub Reserved2: u8, /* always 1 */
-}
-
-/**
- * Card information
- */
-#[derive(Debug, Copy, Clone)]
-pub struct SDCardInfo {
- pub SD_csd: SDCardCSD,
- pub SD_cid: SDCardCID,
- pub CardCapacity: u64, /* Card Capacity */
- pub CardBlockSize: u64, /* Card Block Size */
-}
-
-impl</*'a,*/ X: SPI> SDCard</*'a,*/ X> {
- pub fn new(
- spi: X,
- spi_cs: u32,
- cs_gpionum: u8, /*, dmac: &'a DMAC, channel: dma_channel*/
- ) -> Self {
- Self {
- spi,
- spi_cs,
- cs_gpionum,
- /*
- dmac,
- channel,
- */
- }
- }
-
- fn CS_HIGH(&self) {
- gpiohs::set_pin(self.cs_gpionum, true);
- }
-
- fn CS_LOW(&self) {
- gpiohs::set_pin(self.cs_gpionum, false);
- }
-
- fn HIGH_SPEED_ENABLE(&self) {
- self.spi.set_clk_rate(10000000);
- }
-
- fn lowlevel_init(&self) {
- gpiohs::set_direction(self.cs_gpionum, gpio::direction::OUTPUT);
- self.spi.set_clk_rate(200000);
- }
-
- fn write_data(&self, data: &[u8]) {
- self.spi.configure(
- work_mode::MODE0,
- frame_format::STANDARD,
- 8, /* data bits */
- 0, /* endian */
- 0, /*instruction length*/
- 0, /*address length*/
- 0, /*wait cycles*/
- aitm::STANDARD,
- tmod::TRANS,
- );
- self.spi.send_data(self.spi_cs, data);
- }
-
- /*
- fn write_data_dma(&self, data: &[u32]) {
- self.spi.configure(
- work_mode::MODE0,
- frame_format::STANDARD,
- 8, /* data bits */
- 0, /* endian */
- 0, /*instruction length*/
- 0, /*address length*/
- 0, /*wait cycles*/
- aitm::STANDARD,
- tmod::TRANS,
- );
- self.spi
- .send_data_dma(self.dmac, self.channel, self.spi_cs, data);
- }
- */
-
- fn read_data(&self, data: &mut [u8]) {
- self.spi.configure(
- work_mode::MODE0,
- frame_format::STANDARD,
- 8, /* data bits */
- 0, /* endian */
- 0, /*instruction length*/
- 0, /*address length*/
- 0, /*wait cycles*/
- aitm::STANDARD,
- tmod::RECV,
- );
- self.spi.recv_data(self.spi_cs, data);
- }
-
- /*
- fn read_data_dma(&self, data: &mut [u32]) {
- self.spi.configure(
- work_mode::MODE0,
- frame_format::STANDARD,
- 8, /* data bits */
- 0, /* endian */
- 0, /*instruction length*/
- 0, /*address length*/
- 0, /*wait cycles*/
- aitm::STANDARD,
- tmod::RECV,
- );
- self.spi
- .recv_data_dma(self.dmac, self.channel, self.spi_cs, data);
- }
- */
-
- /*
- * Send 5 bytes command to the SD card.
- * @param cmd: The user expected command to send to SD card.
- * @param arg: The command argument.
- * @param crc: The CRC.
- * @retval None
- */
- fn send_cmd(&self, cmd: CMD, arg: u32, crc: u8) {
- /* SD chip select low */
- self.CS_LOW();
- /* Send the Cmd bytes */
- self.write_data(&[
- /* Construct byte 1 */
- ((cmd as u8) | 0x40),
- /* Construct byte 2 */
- (arg >> 24) as u8,
- /* Construct byte 3 */
- ((arg >> 16) & 0xff) as u8,
- /* Construct byte 4 */
- ((arg >> 8) & 0xff) as u8,
- /* Construct byte 5 */
- (arg & 0xff) as u8,
- /* Construct CRC: byte 6 */
- crc,
- ]);
- }
-
- /* Send end-command sequence to SD card */
- fn end_cmd(&self) {
- /* SD chip select high */
- self.CS_HIGH();
- /* Send the cmd byte */
- self.write_data(&[0xff]);
- }
-
- /*
- * Returns the SD response.
- * @param None
- * @retval The SD Response:
- * - 0xFF: Sequence failed
- * - 0: Sequence succeed
- */
- fn get_response(&self) -> u8 {
- let result = &mut [0u8];
- let mut timeout = 0x0FFF;
- /* Check if response is got or a timeout is happen */
- while timeout != 0 {
- self.read_data(result);
- /* Right response got */
- if result[0] != 0xFF {
- return result[0];
- }
- timeout -= 1;
- }
- /* After time out */
- 0xFF
- }
-
- /*
- * Get SD card data response.
- * @param None
- * @retval The SD status: Read data response xxx0<status>1
- * - status 010: Data accecpted
- * - status 101: Data rejected due to a crc error
- * - status 110: Data rejected due to a Write error.
- * - status 111: Data rejected due to other error.
- */
- fn get_dataresponse(&self) -> u8 {
- let response = &mut [0u8];
- /* Read resonse */
- self.read_data(response);
- /* Mask unused bits */
- response[0] &= 0x1F;
- if response[0] != 0x05 {
- return 0xFF;
- }
- /* Wait null data */
- self.read_data(response);
- while response[0] == 0 {
- self.read_data(response);
- }
- /* Return response */
- 0
- }
-
- /*
- * Read the CSD card register
- * Reading the contents of the CSD register in SPI mode is a simple
- * read-block transaction.
- * @param SD_csd: pointer on an SCD register structure
- * @retval The SD Response:
- * - `Err()`: Sequence failed
- * - `Ok(info)`: Sequence succeed
- */
- fn get_csdregister(&self) -> Result<SDCardCSD, ()> {
- let mut csd_tab = [0u8; 18];
- /* Send CMD9 (CSD register) */
- self.send_cmd(CMD::CMD9, 0, 0);
- /* Wait for response in the R1 format (0x00 is no errors) */
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
- self.end_cmd();
- return Err(());
- }
- /* Store CSD register value on csd_tab */
- /* Get CRC bytes (not really needed by us, but required by SD) */
- self.read_data(&mut csd_tab);
- self.end_cmd();
- /* see also: https://cdn-shop.adafruit.com/datasheets/TS16GUSDHC6.pdf */
- Ok(SDCardCSD {
- /* Byte 0 */
- CSDStruct: (csd_tab[0] & 0xC0) >> 6,
- SysSpecVersion: (csd_tab[0] & 0x3C) >> 2,
- Reserved1: csd_tab[0] & 0x03,
- /* Byte 1 */
- TAAC: csd_tab[1],
- /* Byte 2 */
- NSAC: csd_tab[2],
- /* Byte 3 */
- MaxBusClkFrec: csd_tab[3],
- /* Byte 4, 5 */
- CardComdClasses: (u16::from(csd_tab[4]) << 4) | ((u16::from(csd_tab[5]) & 0xF0) >> 4),
- /* Byte 5 */
- RdBlockLen: csd_tab[5] & 0x0F,
- /* Byte 6 */
- PartBlockRead: (csd_tab[6] & 0x80) >> 7,
- WrBlockMisalign: (csd_tab[6] & 0x40) >> 6,
- RdBlockMisalign: (csd_tab[6] & 0x20) >> 5,
- DSRImpl: (csd_tab[6] & 0x10) >> 4,
- Reserved2: 0,
- // DeviceSize: (csd_tab[6] & 0x03) << 10,
- /* Byte 7, 8, 9 */
- DeviceSize: ((u32::from(csd_tab[7]) & 0x3F) << 16)
- | (u32::from(csd_tab[8]) << 8)
- | u32::from(csd_tab[9]),
- /* Byte 10 */
- EraseGrSize: (csd_tab[10] & 0x40) >> 6,
- /* Byte 10, 11 */
- EraseGrMul: ((csd_tab[10] & 0x3F) << 1) | ((csd_tab[11] & 0x80) >> 7),
- /* Byte 11 */
- WrProtectGrSize: (csd_tab[11] & 0x7F),
- /* Byte 12 */
- WrProtectGrEnable: (csd_tab[12] & 0x80) >> 7,
- ManDeflECC: (csd_tab[12] & 0x60) >> 5,
- WrSpeedFact: (csd_tab[12] & 0x1C) >> 2,
- /* Byte 12,13 */
- MaxWrBlockLen: ((csd_tab[12] & 0x03) << 2) | ((csd_tab[13] & 0xC0) >> 6),
- /* Byte 13 */
- WriteBlockPaPartial: (csd_tab[13] & 0x20) >> 5,
- Reserved3: 0,
- ContentProtectAppli: (csd_tab[13] & 0x01),
- /* Byte 14 */
- FileFormatGroup: (csd_tab[14] & 0x80) >> 7,
- CopyFlag: (csd_tab[14] & 0x40) >> 6,
- PermWrProtect: (csd_tab[14] & 0x20) >> 5,
- TempWrProtect: (csd_tab[14] & 0x10) >> 4,
- FileFormat: (csd_tab[14] & 0x0C) >> 2,
- ECC: (csd_tab[14] & 0x03),
- /* Byte 15 */
- CSD_CRC: (csd_tab[15] & 0xFE) >> 1,
- Reserved4: 1,
- /* Return the reponse */
- })
- }
-
- /*
- * Read the CID card register.
- * Reading the contents of the CID register in SPI mode is a simple
- * read-block transaction.
- * @param SD_cid: pointer on an CID register structure
- * @retval The SD Response:
- * - `Err()`: Sequence failed
- * - `Ok(info)`: Sequence succeed
- */
- fn get_cidregister(&self) -> Result<SDCardCID, ()> {
- let mut cid_tab = [0u8; 18];
- /* Send CMD10 (CID register) */
- self.send_cmd(CMD::CMD10, 0, 0);
- /* Wait for response in the R1 format (0x00 is no errors) */
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
- self.end_cmd();
- return Err(());
- }
- /* Store CID register value on cid_tab */
- /* Get CRC bytes (not really needed by us, but required by SD) */
- self.read_data(&mut cid_tab);
- self.end_cmd();
- Ok(SDCardCID {
- /* Byte 0 */
- ManufacturerID: cid_tab[0],
- /* Byte 1, 2 */
- OEM_AppliID: (u16::from(cid_tab[1]) << 8) | u16::from(cid_tab[2]),
- /* Byte 3, 4, 5, 6 */
- ProdName1: (u32::from(cid_tab[3]) << 24)
- | (u32::from(cid_tab[4]) << 16)
- | (u32::from(cid_tab[5]) << 8)
- | u32::from(cid_tab[6]),
- /* Byte 7 */
- ProdName2: cid_tab[7],
- /* Byte 8 */
- ProdRev: cid_tab[8],
- /* Byte 9, 10, 11, 12 */
- ProdSN: (u32::from(cid_tab[9]) << 24)
- | (u32::from(cid_tab[10]) << 16)
- | (u32::from(cid_tab[11]) << 8)
- | u32::from(cid_tab[12]),
- /* Byte 13, 14 */
- Reserved1: (cid_tab[13] & 0xF0) >> 4,
- ManufactDate: ((u16::from(cid_tab[13]) & 0x0F) << 8) | u16::from(cid_tab[14]),
- /* Byte 15 */
- CID_CRC: (cid_tab[15] & 0xFE) >> 1,
- Reserved2: 1,
- })
- }
-
- /*
- * Returns information about specific card.
- * @param cardinfo: pointer to a SD_CardInfo structure that contains all SD
- * card information.
- * @retval The SD Response:
- * - `Err(())`: Sequence failed
- * - `Ok(info)`: Sequence succeed
- */
- fn get_cardinfo(&self) -> Result<SDCardInfo, ()> {
- let mut info = SDCardInfo {
- SD_csd: self.get_csdregister()?,
- SD_cid: self.get_cidregister()?,
- CardCapacity: 0,
- CardBlockSize: 0,
- };
- info.CardBlockSize = 1 << u64::from(info.SD_csd.RdBlockLen);
- info.CardCapacity = (u64::from(info.SD_csd.DeviceSize) + 1) * 1024 * info.CardBlockSize;
-
- Ok(info)
- }
-
- /*
- * Initializes the SD/SD communication in SPI mode.
- * @param None
- * @retval The SD Response info if succeeeded, otherwise Err
- */
- pub fn init(&self) -> Result<SDCardInfo, InitError> {
- /* Initialize SD_SPI */
- self.lowlevel_init();
- /* SD chip select high */
- self.CS_HIGH();
- /* NOTE: this reset doesn't always seem to work if the SD access was broken off in the
- * middle of an operation: CMDFailed(CMD0, 127). */
-
- /* Send dummy byte 0xFF, 10 times with CS high */
- /* Rise CS and MOSI for 80 clocks cycles */
- /* Send dummy byte 0xFF */
- self.write_data(&[0xff; 10]);
- /*------------Put SD in SPI mode--------------*/
- /* SD initialized and set to SPI mode properly */
-
- /* Send software reset */
- self.send_cmd(CMD::CMD0, 0, 0x95);
- let result = self.get_response();
- self.end_cmd();
- if result != 0x01 {
- return Err(InitError::CMDFailed(CMD::CMD0, result));
- }
-
- /* Check voltage range */
- self.send_cmd(CMD::CMD8, 0x01AA, 0x87);
- /* 0x01 or 0x05 */
- let result = self.get_response();
- let mut frame = [0u8; 4];
- self.read_data(&mut frame);
- self.end_cmd();
- if result != 0x01 {
- return Err(InitError::CMDFailed(CMD::CMD8, result));
- }
- let mut index = 255;
- while index != 0 {
- /* <ACMD> */
- self.send_cmd(CMD::CMD55, 0, 0);
- let result = self.get_response();
- self.end_cmd();
- if result != 0x01 {
- return Err(InitError::CMDFailed(CMD::CMD55, result));
- }
- /* Initiate SDC initialization process */
- self.send_cmd(CMD::ACMD41, 0x40000000, 0);
- let result = self.get_response();
- self.end_cmd();
- if result == 0x00 {
- break;
- }
- index -= 1;
- }
- if index == 0 {
- return Err(InitError::CMDFailed(CMD::ACMD41, result));
- }
- index = 255;
- let mut frame = [0u8; 4];
- while index != 0 {
- /* Read OCR */
- self.send_cmd(CMD::CMD58, 0, 1);
- let result = self.get_response();
- self.read_data(&mut frame);
- self.end_cmd();
- if result == 0 {
- break;
- }
- index -= 1;
- }
- if index == 0 {
- return Err(InitError::CMDFailed(CMD::CMD58, result));
- }
- if (frame[0] & 0x40) == 0 {
- return Err(InitError::CardCapacityStatusNotSet(frame));
- }
- self.HIGH_SPEED_ENABLE();
- self.get_cardinfo()
- .map_err(|_| InitError::CannotGetCardInfo)
- }
-
- /*
- * Reads a block of data from the SD.
- * @param data_buf: slice that receives the data read from the SD.
- * @param sector: SD's internal address to read from.
- * @retval The SD Response:
- * - `Err(())`: Sequence failed
- * - `Ok(())`: Sequence succeed
- */
- pub fn read_sector(&self, data_buf: &mut [u8], sector: u32) -> Result<(), ()> {
- assert!(data_buf.len() >= SEC_LEN && (data_buf.len() % SEC_LEN) == 0);
- /* Send CMD17 to read one block, or CMD18 for multiple */
- let flag = if data_buf.len() == SEC_LEN {
- self.send_cmd(CMD::CMD17, sector, 0);
- false
- } else {
- self.send_cmd(CMD::CMD18, sector, 0);
- true
- };
- /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- let mut error = false;
- //let mut dma_chunk = [0u32; SEC_LEN];
- let mut tmp_chunk = [0u8; SEC_LEN];
- for chunk in data_buf.chunks_mut(SEC_LEN) {
- if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
- error = true;
- break;
- }
- /* Read the SD block data : read NumByteToRead data */
- //self.read_data_dma(&mut dma_chunk);
- self.read_data(&mut tmp_chunk);
- /* Place the data received as u32 units from DMA into the u8 target buffer */
- for (a, b) in chunk.iter_mut().zip(/*dma_chunk*/ tmp_chunk.iter()) {
- //*a = (b & 0xff) as u8;
- *a = *b;
- }
- /* Get CRC bytes (not really needed by us, but required by SD) */
- let mut frame = [0u8; 2];
- self.read_data(&mut frame);
- }
- self.end_cmd();
- if flag {
- self.send_cmd(CMD::CMD12, 0, 0);
- self.get_response();
- self.end_cmd();
- self.end_cmd();
- }
- /* It is an error if not everything requested was read */
- if error {
- Err(())
- } else {
- Ok(())
- }
- }
-
- /*
- * Writes a block to the SD
- * @param data_buf: slice containing the data to be written to the SD.
- * @param sector: address to write on.
- * @retval The SD Response:
- * - `Err(())`: Sequence failed
- * - `Ok(())`: Sequence succeed
- */
- pub fn write_sector(&self, data_buf: &[u8], sector: u32) -> Result<(), ()> {
- assert!(data_buf.len() >= SEC_LEN && (data_buf.len() % SEC_LEN) == 0);
- let mut frame = [0xff, 0x00];
- if data_buf.len() == SEC_LEN {
- frame[1] = SD_START_DATA_SINGLE_BLOCK_WRITE;
- self.send_cmd(CMD::CMD24, sector, 0);
- } else {
- frame[1] = SD_START_DATA_MULTIPLE_BLOCK_WRITE;
- self.send_cmd(
- CMD::ACMD23,
- (data_buf.len() / SEC_LEN).try_into().unwrap(),
- 0,
- );
- self.get_response();
- self.end_cmd();
- self.send_cmd(CMD::CMD25, sector, 0);
- }
- /* Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- //let mut dma_chunk = [0u32; SEC_LEN];
- let mut tmp_chunk = [0u8; SEC_LEN];
- for chunk in data_buf.chunks(SEC_LEN) {
- /* Send the data token to signify the start of the data */
- self.write_data(&frame);
- /* Write the block data to SD : write count data by block */
- for (a, &b) in /*dma_chunk*/ tmp_chunk.iter_mut().zip(chunk.iter()) {
- //*a = b.into();
- *a = b;
- }
- //self.write_data_dma(&mut dma_chunk);
- self.write_data(&tmp_chunk);
- /* Put dummy CRC bytes */
- self.write_data(&[0xff, 0xff]);
- /* Read data response */
- if self.get_dataresponse() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- }
- self.end_cmd();
- self.end_cmd();
- Ok(())
- }
-}
-
-/** GPIOHS GPIO number to use for controlling the SD card CS pin */
-const SD_CS_GPIONUM: u8 = 7;
-/** CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapping to anything
- * in the FPIOA */
-const SD_CS: u32 = 3;
-
-/** Connect pins to internal functions */
-fn io_init() {
- fpioa::set_function(io::SPI0_SCLK, fpioa::function::SPI0_SCLK);
- fpioa::set_function(io::SPI0_MOSI, fpioa::function::SPI0_D0);
- fpioa::set_function(io::SPI0_MISO, fpioa::function::SPI0_D1);
- fpioa::set_function(io::SPI0_CS0, fpioa::function::gpiohs(SD_CS_GPIONUM));
- fpioa::set_io_pull(io::SPI0_CS0, fpioa::pull::DOWN); // GPIO output=pull down
-}
-
-lazy_static! {
- static ref PERIPHERALS: UPSafeCell<Peripherals> =
- unsafe { UPSafeCell::new(Peripherals::take().unwrap()) };
-}
-
-fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
- // wait previous output
- usleep(100000);
- let peripherals = unsafe { Peripherals::steal() };
- sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap();
- sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap();
- sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap();
- let clocks = k210_hal::clock::Clocks::new();
- peripherals.UARTHS.configure(115_200.bps(), &clocks);
- io_init();
-
- let spi = peripherals.SPI0.constrain();
- let sd = SDCard::new(spi, SD_CS, SD_CS_GPIONUM);
- let info = sd.init().unwrap();
- let num_sectors = info.CardCapacity / 512;
- assert!(num_sectors > 0);
-
- println!("init sdcard!");
- sd
-}
-
-pub struct SDCardWrapper(UPSafeCell<SDCard<SPIImpl<SPI0>>>);
-
-impl SDCardWrapper {
- pub fn new() -> Self {
- unsafe { Self(UPSafeCell::new(init_sdcard())) }
- }
-}
-
-impl BlockDevice for SDCardWrapper {
- fn read_block(&self, block_id: usize, buf: &mut [u8]) {
- self.0
- .exclusive_access()
- .read_sector(buf, block_id as u32)
- .unwrap();
- }
- fn write_block(&self, block_id: usize, buf: &[u8]) {
- self.0
- .exclusive_access()
- .write_sector(buf, block_id as u32)
- .unwrap();
- }
-}
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -
use super::BlockDevice;
-use crate::mm::{
- frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum,
- StepByOne, VirtAddr,
+virtio_blk.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+
use super::BlockDevice;
+use crate::mm::{
+ frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum,
+ StepByOne, VirtAddr,
};
-use crate::sync::UPSafeCell;
-use alloc::vec::Vec;
-use lazy_static::*;
-use virtio_drivers::{VirtIOBlk, VirtIOHeader};
+use crate::sync::UPSafeCell;
+use alloc::vec::Vec;
+use lazy_static::*;
+use virtio_drivers::{Hal, VirtIOBlk, VirtIOHeader};
-#[allow(unused)]
-const VIRTIO0: usize = 0x10001000;
+#[allow(unused)]
+const VIRTIO0: usize = 0x10001000;
-pub struct VirtIOBlock(UPSafeCell<VirtIOBlk<'static>>);
+pub struct VirtIOBlock(UPSafeCell<VirtIOBlk<'static, VirtioHal>>);
-lazy_static! {
- static ref QUEUE_FRAMES: UPSafeCell<Vec<FrameTracker>> = unsafe { UPSafeCell::new(Vec::new()) };
+lazy_static! {
+ static ref QUEUE_FRAMES: UPSafeCell<Vec<FrameTracker>> = unsafe { UPSafeCell::new(Vec::new()) };
}
-impl BlockDevice for VirtIOBlock {
- fn read_block(&self, block_id: usize, buf: &mut [u8]) {
- self.0
- .exclusive_access()
- .read_block(block_id, buf)
- .expect("Error when reading VirtIOBlk");
+impl BlockDevice for VirtIOBlock {
+ fn read_block(&self, block_id: usize, buf: &mut [u8]) {
+ self.0
+ .exclusive_access()
+ .read_block(block_id, buf)
+ .expect("Error when reading VirtIOBlk");
}
- fn write_block(&self, block_id: usize, buf: &[u8]) {
- self.0
- .exclusive_access()
- .write_block(block_id, buf)
- .expect("Error when writing VirtIOBlk");
+ fn write_block(&self, block_id: usize, buf: &[u8]) {
+ self.0
+ .exclusive_access()
+ .write_block(block_id, buf)
+ .expect("Error when writing VirtIOBlk");
}
}
-impl VirtIOBlock {
- #[allow(unused)]
- pub fn new() -> Self {
- unsafe {
- Self(UPSafeCell::new(
- VirtIOBlk::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap(),
+impl VirtIOBlock {
+ #[allow(unused)]
+ pub fn new() -> Self {
+ unsafe {
+ Self(UPSafeCell::new(
+ VirtIOBlk::<VirtioHal>::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap(),
))
}
}
}
-#[no_mangle]
-pub extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr {
- let mut ppn_base = PhysPageNum(0);
- for i in 0..pages {
- let frame = frame_alloc().unwrap();
- if i == 0 {
- ppn_base = frame.ppn;
+pub struct VirtioHal;
+
+impl Hal for VirtioHal {
+ fn dma_alloc(pages: usize) -> usize {
+ let mut ppn_base = PhysPageNum(0);
+ for i in 0..pages {
+ let frame = frame_alloc().unwrap();
+ if i == 0 {
+ ppn_base = frame.ppn;
+ }
+ assert_eq!(frame.ppn.0, ppn_base.0 + i);
+ QUEUE_FRAMES.exclusive_access().push(frame);
}
- assert_eq!(frame.ppn.0, ppn_base.0 + i);
- QUEUE_FRAMES.exclusive_access().push(frame);
+ let pa: PhysAddr = ppn_base.into();
+ pa.0
+ }
+
+ fn dma_dealloc(pa: usize, pages: usize) -> i32 {
+ let pa = PhysAddr::from(pa);
+ let mut ppn_base: PhysPageNum = pa.into();
+ for _ in 0..pages {
+ frame_dealloc(ppn_base);
+ ppn_base.step();
+ }
+ 0
+ }
+
+ fn phys_to_virt(addr: usize) -> usize {
+ addr
}
- ppn_base.into()
-}
-#[no_mangle]
-pub extern "C" fn virtio_dma_dealloc(pa: PhysAddr, pages: usize) -> i32 {
- let mut ppn_base: PhysPageNum = pa.into();
- for _ in 0..pages {
- frame_dealloc(ppn_base);
- ppn_base.step();
- }
- 0
+ fn virt_to_phys(vaddr: usize) -> usize {
+ PageTable::from_token(kernel_token())
+ .translate_va(VirtAddr::from(vaddr))
+ .unwrap()
+ .0
+ }
}
-
-#[no_mangle]
-pub extern "C" fn virtio_phys_to_virt(paddr: PhysAddr) -> VirtAddr {
- VirtAddr(paddr.0)
-}
-
-#[no_mangle]
-pub extern "C" fn virtio_virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
- PageTable::from_token(kernel_token())
- .translate_va(vaddr)
- .unwrap()
-}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -
//! `Arc<Inode>` -> `OSInodeInner`: In order to open files concurrently
-//! we need to wrap `Inode` into `Arc`,but `Mutex` in `Inode` prevents
-//! file systems from being accessed simultaneously
-//!
-//! `UPSafeCell<OSInodeInner>` -> `OSInode`: for static `ROOT_INODE`,we
-//! need to wrap `OSInodeInner` into `UPSafeCell`
-use super::File;
-use crate::drivers::BLOCK_DEVICE;
-use crate::mm::UserBuffer;
-use crate::sync::UPSafeCell;
-use alloc::sync::Arc;
-use alloc::vec::Vec;
-use bitflags::*;
-use easy_fs::{EasyFileSystem, Inode};
-use lazy_static::*;
-/// A wrapper around a filesystem inode
-/// to implement File trait atop
-pub struct OSInode {
- readable: bool,
- writable: bool,
- inner: UPSafeCell<OSInodeInner>,
+inode.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+
//! `Arc<Inode>` -> `OSInodeInner`: In order to open files concurrently
+//! we need to wrap `Inode` into `Arc`,but `Mutex` in `Inode` prevents
+//! file systems from being accessed simultaneously
+//!
+//! `UPSafeCell<OSInodeInner>` -> `OSInode`: for static `ROOT_INODE`,we
+//! need to wrap `OSInodeInner` into `UPSafeCell`
+use super::File;
+use crate::drivers::BLOCK_DEVICE;
+use crate::mm::UserBuffer;
+use crate::sync::{RawExclusiveLock, UPSafeCell};
+use alloc::sync::Arc;
+use alloc::vec::Vec;
+use bitflags::*;
+use easy_fs::{BlockCacheMgr, EasyFileSystem, Inode};
+use lazy_static::*;
+
+const BLOCK_CACHE_SIZE: usize = 64;
+type InodeType = Inode<RawExclusiveLock, BLOCK_CACHE_SIZE, RawExclusiveLock, RawExclusiveLock>;
+
+/// A wrapper around a filesystem inode
+/// to implement File trait atop
+pub struct OSInode {
+ readable: bool,
+ writable: bool,
+ inner: UPSafeCell<OSInodeInner>,
}
-/// The OS inode inner in 'UPSafeCell'
-pub struct OSInodeInner {
- offset: usize,
- inode: Arc<Inode>,
+/// The OS inode inner in 'UPSafeCell'
+pub struct OSInodeInner {
+ offset: usize,
+ inode: Arc<InodeType>,
}
-impl OSInode {
- /// Construct an OS inode from a inode
- pub fn new(readable: bool, writable: bool, inode: Arc<Inode>) -> Self {
- Self {
- readable,
- writable,
- inner: unsafe { UPSafeCell::new(OSInodeInner { offset: 0, inode }) },
+impl OSInode {
+ /// Construct an OS inode from a inode
+ pub fn new(readable: bool, writable: bool, inode: Arc<InodeType>) -> Self {
+ Self {
+ readable,
+ writable,
+ inner: unsafe { UPSafeCell::new(OSInodeInner { offset: 0, inode }) },
}
}
- /// Read all data inside a inode into vector
- pub fn read_all(&self) -> Vec<u8> {
- let mut inner = self.inner.exclusive_access();
- let mut buffer = [0u8; 512];
- let mut v: Vec<u8> = Vec::new();
- loop {
- let len = inner.inode.read_at(inner.offset, &mut buffer);
- if len == 0 {
+ /// Read all data inside a inode into vector
+ pub fn read_all(&self) -> Vec<u8> {
+ let mut inner = self.inner.exclusive_access();
+ let mut buffer = [0u8; 512];
+ let mut v: Vec<u8> = Vec::new();
+ loop {
+ let len = inner.inode.read_at(inner.offset, &mut buffer);
+ if len == 0 {
break;
}
- inner.offset += len;
- v.extend_from_slice(&buffer[..len]);
+ inner.offset += len;
+ v.extend_from_slice(&buffer[..len]);
}
- v
+ v
}
}
-lazy_static! {
- pub static ref ROOT_INODE: Arc<Inode> = {
- let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
- Arc::new(EasyFileSystem::root_inode(&efs))
+lazy_static! {
+ pub static ref ROOT_INODE: Arc<InodeType> = {
+ let block_dev = BLOCK_DEVICE.clone();
+ let bcache_mgr: BlockCacheMgr<BLOCK_CACHE_SIZE, RawExclusiveLock> =
+ BlockCacheMgr::new(&block_dev);
+ let efs: EasyFileSystem<BLOCK_CACHE_SIZE, RawExclusiveLock, _> =
+ EasyFileSystem::open(bcache_mgr);
+ let efs = Arc::new(lock_api::Mutex::<RawExclusiveLock, _>::new(efs));
+ Arc::new(Inode::root_inode(&efs))
};
}
-/// List all files in the filesystems
-pub fn list_apps() {
+/// List all files in the filesystems
+#[allow(warnings)]
+pub fn list_apps() {
println!("/**** APPS ****");
- for app in ROOT_INODE.ls() {
- println!("{}", app);
+ for app in ROOT_INODE.listdir() {
+ println!("{}", app);
}
println!("**************/");
}
-bitflags! {
- ///Open file flags
- pub struct OpenFlags: u32 {
- ///Read only
- const RDONLY = 0;
- ///Write only
- const WRONLY = 1 << 0;
- ///Read & Write
- const RDWR = 1 << 1;
- ///Allow create
- const CREATE = 1 << 9;
- ///Clear file and return an empty one
- const TRUNC = 1 << 10;
+bitflags! {
+ ///Open file flags
+ pub struct OpenFlags: u32 {
+ ///Read only
+ const RDONLY = 0;
+ ///Write only
+ const WRONLY = 1 << 0;
+ ///Read & Write
+ const RDWR = 1 << 1;
+ ///Allow create
+ const CREATE = 1 << 9;
+ ///Clear file and return an empty one
+ const TRUNC = 1 << 10;
}
}
-impl OpenFlags {
- /// Do not check validity for simplicity
- /// Return (readable, writable)
- pub fn read_write(&self) -> (bool, bool) {
- if self.is_empty() {
+impl OpenFlags {
+ /// Do not check validity for simplicity
+ /// Return (readable, writable)
+ pub fn read_write(&self) -> (bool, bool) {
+ if self.is_empty() {
(true, false)
- } else if self.contains(Self::WRONLY) {
+ } else if self.contains(Self::WRONLY) {
(false, true)
- } else {
+ } else {
(true, true)
}
}
}
-///Open file with flags
-pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
- let (readable, writable) = flags.read_write();
- if flags.contains(OpenFlags::CREATE) {
- if let Some(inode) = ROOT_INODE.find(name) {
- // clear size
- inode.clear();
- Some(Arc::new(OSInode::new(readable, writable, inode)))
- } else {
- // create file
- ROOT_INODE
- .create(name)
- .map(|inode| Arc::new(OSInode::new(readable, writable, inode)))
+///Open file with flags
+pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
+ let (readable, writable) = flags.read_write();
+ if flags.contains(OpenFlags::CREATE) {
+ if let Some(inode) = ROOT_INODE.find(name) {
+ // clear size
+ inode.clear();
+ Some(Arc::new(OSInode::new(readable, writable, inode)))
+ } else {
+ // create file
+ ROOT_INODE
+ .create(name)
+ .map(|inode| Arc::new(OSInode::new(readable, writable, inode)))
}
- } else {
- ROOT_INODE.find(name).map(|inode| {
- if flags.contains(OpenFlags::TRUNC) {
- inode.clear();
+ } else {
+ ROOT_INODE.find(name).map(|inode| {
+ if flags.contains(OpenFlags::TRUNC) {
+ inode.clear();
}
- Arc::new(OSInode::new(readable, writable, inode))
+ Arc::new(OSInode::new(readable, writable, inode))
})
}
}
-impl File for OSInode {
- fn readable(&self) -> bool {
- self.readable
+impl File for OSInode {
+ fn readable(&self) -> bool {
+ self.readable
}
- fn writable(&self) -> bool {
- self.writable
+ fn writable(&self) -> bool {
+ self.writable
}
- fn read(&self, mut buf: UserBuffer) -> usize {
- let mut inner = self.inner.exclusive_access();
- let mut total_read_size = 0usize;
- for slice in buf.buffers.iter_mut() {
- let read_size = inner.inode.read_at(inner.offset, *slice);
- if read_size == 0 {
+ fn read(&self, mut buf: UserBuffer) -> usize {
+ let mut inner = self.inner.exclusive_access();
+ let mut total_read_size = 0usize;
+ for slice in buf.buffers.iter_mut() {
+ let read_size = inner.inode.read_at(inner.offset, *slice);
+ if read_size == 0 {
break;
}
- inner.offset += read_size;
- total_read_size += read_size;
+ inner.offset += read_size;
+ total_read_size += read_size;
}
- total_read_size
+ total_read_size
}
- fn write(&self, buf: UserBuffer) -> usize {
- let mut inner = self.inner.exclusive_access();
- let mut total_write_size = 0usize;
- for slice in buf.buffers.iter() {
- let write_size = inner.inode.write_at(inner.offset, *slice);
- assert_eq!(write_size, slice.len());
- inner.offset += write_size;
- total_write_size += write_size;
+ fn write(&self, buf: UserBuffer) -> usize {
+ let mut inner = self.inner.exclusive_access();
+ let mut total_write_size = 0usize;
+ for slice in buf.buffers.iter() {
+ let write_size = inner.inode.write_at(inner.offset, *slice);
+ assert_eq!(write_size, slice.len());
+ inner.offset += write_size;
+ total_write_size += write_size;
}
- total_write_size
+ total_write_size
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -
//! File system in os
-mod inode;
-mod stdio;
+mod.rs - source //! File system in os
+mod inode;
+mod stdio;
-use crate::mm::UserBuffer;
-/// File trait
-pub trait File: Send + Sync {
- /// If readable
- fn readable(&self) -> bool;
- /// If writable
- fn writable(&self) -> bool;
- /// Read file to `UserBuffer`
- fn read(&self, buf: UserBuffer) -> usize;
- /// Write `UserBuffer` to file
- fn write(&self, buf: UserBuffer) -> usize;
+use crate::mm::UserBuffer;
+/// File trait
+pub trait File: Send + Sync {
+ /// If readable
+ fn readable(&self) -> bool;
+ /// If writable
+ fn writable(&self) -> bool;
+ /// Read file to `UserBuffer`
+ fn read(&self, buf: UserBuffer) -> usize;
+ /// Write `UserBuffer` to file
+ fn write(&self, buf: UserBuffer) -> usize;
}
-pub use inode::{list_apps, open_file, OSInode, OpenFlags};
-pub use stdio::{Stdin, Stdout};
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -
//!Stdin & Stdout
-use super::File;
-use crate::mm::UserBuffer;
-use crate::sbi::console_getchar;
-use crate::task::suspend_current_and_run_next;
-///Standard input
-pub struct Stdin;
-///Standard output
-pub struct Stdout;
+stdio.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+
//!Stdin & Stdout
+use super::File;
+use crate::mm::UserBuffer;
+use crate::sbi::console_getchar;
+use crate::task::suspend_current_and_run_next;
+///Standard input
+pub struct Stdin;
+///Standard output
+pub struct Stdout;
-impl File for Stdin {
- fn readable(&self) -> bool {
- true
- }
- fn writable(&self) -> bool {
- false
- }
- fn read(&self, mut user_buf: UserBuffer) -> usize {
- assert_eq!(user_buf.len(), 1);
- // busy loop
- let mut c: usize;
- loop {
- c = console_getchar();
- if c == 0 {
- suspend_current_and_run_next();
+impl File for Stdin {
+ fn readable(&self) -> bool {
+ true
+ }
+ fn writable(&self) -> bool {
+ false
+ }
+ fn read(&self, mut user_buf: UserBuffer) -> usize {
+ assert_eq!(user_buf.len(), 1);
+ // busy loop
+ let mut c: usize;
+ loop {
+ c = console_getchar();
+ if c == 0 {
+ suspend_current_and_run_next();
continue;
- } else {
+ } else {
break;
}
}
- let ch = c as u8;
- unsafe {
- user_buf.buffers[0].as_mut_ptr().write_volatile(ch);
+ let ch = c as u8;
+ unsafe {
+ user_buf.buffers[0].as_mut_ptr().write_volatile(ch);
}
- 1
- }
- fn write(&self, _user_buf: UserBuffer) -> usize {
+ 1
+ }
+ fn write(&self, _user_buf: UserBuffer) -> usize {
panic!("Cannot write to stdin!");
}
}
-impl File for Stdout {
- fn readable(&self) -> bool {
- false
- }
- fn writable(&self) -> bool {
- true
- }
- fn read(&self, _user_buf: UserBuffer) -> usize {
+impl File for Stdout {
+ fn readable(&self) -> bool {
+ false
+ }
+ fn writable(&self) -> bool {
+ true
+ }
+ fn read(&self, _user_buf: UserBuffer) -> usize {
panic!("Cannot read from stdout!");
}
- fn write(&self, user_buf: UserBuffer) -> usize {
- for buffer in user_buf.buffers.iter() {
- print!("{}", core::str::from_utf8(*buffer).unwrap());
+ fn write(&self, user_buf: UserBuffer) -> usize {
+ for buffer in user_buf.buffers.iter() {
+ print!("{}", core::str::from_utf8(*buffer).unwrap());
}
- user_buf.len()
+ user_buf.len()
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -
//! The panic handler
-use crate::sbi::shutdown;
-use core::panic::PanicInfo;
+lang_items.rs - source //! The panic handler
+use crate::sbi::shutdown;
+use core::panic::PanicInfo;
+use log::*;
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
- if let Some(location) = info.location() {
- println!(
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+ if let Some(location) = info.location() {
+ error!(
"[kernel] Panicked at {}:{} {}",
- location.file(),
- location.line(),
- info.message().unwrap()
+ location.file(),
+ location.line(),
+ info.message().unwrap()
);
- } else {
- println!("[kernel] Panicked: {}", info.message().unwrap());
+ } else {
+ error!("[kernel] Panicked: {}", info.message().unwrap());
}
- shutdown()
+ shutdown(true)
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -
//! The main module and entrypoint
-//!
-//! Various facilities of the kernels are implemented as submodules. The most
-//! important ones are:
-//!
-//! - [`trap`]: Handles all cases of switching from userspace to the kernel
-//! - [`task`]: Task management
-//! - [`syscall`]: System call handling and implementation
-//! - [`mm`]: Address map using SV39
-//! - [`sync`]: Wrap a static data structure inside it so that we are able to access it without any `unsafe`.
-//! - [`fs`]: Separate user from file system with some structures
-//!
-//! The operating system also starts in this module. Kernel code starts
-//! executing from `entry.asm`, after which [`rust_main()`] is called to
-//! initialize various pieces of functionality. (See its source code for
-//! details.)
-//!
-//! We then call [`task::run_tasks()`] and for the first time go to
-//! userspace.
+main.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
//! The main module and entrypoint
+//!
+//! Various facilities of the kernels are implemented as submodules. The most
+//! important ones are:
+//!
+//! - [`trap`]: Handles all cases of switching from userspace to the kernel
+//! - [`task`]: Task management
+//! - [`syscall`]: System call handling and implementation
+//! - [`mm`]: Address map using SV39
+//! - [`sync`]: Wrap a static data structure inside it so that we are able to access it without any `unsafe`.
+//! - [`fs`]: Separate user from file system with some structures
+//!
+//! The operating system also starts in this module. Kernel code starts
+//! executing from `entry.asm`, after which [`rust_main()`] is called to
+//! initialize various pieces of functionality. (See its source code for
+//! details.)
+//!
+//! We then call [`task::run_tasks()`] and for the first time go to
+//! userspace.
-#![deny(missing_docs)]
-#![deny(warnings)]
-#![allow(unused_imports)]
-#![no_std]
-#![no_main]
-#![feature(panic_info_message)]
-#![feature(alloc_error_handler)]
+#![deny(missing_docs)]
+#![deny(warnings)]
+#![allow(unused_imports)]
+#![no_std]
+#![no_main]
+#![feature(panic_info_message)]
+#![feature(alloc_error_handler)]
-extern crate alloc;
+extern crate alloc;
-#[macro_use]
-extern crate bitflags;
+#[macro_use]
+extern crate bitflags;
-#[cfg(feature = "board_k210")]
-#[path = "boards/k210.rs"]
-mod board;
-#[cfg(not(any(feature = "board_k210")))]
-#[path = "boards/qemu.rs"]
-mod board;
+#[path = "boards/qemu.rs"]
+mod board;
-#[macro_use]
-mod console;
-mod config;
-mod drivers;
-pub mod fs;
-pub mod lang_items;
-pub mod mm;
-pub mod sbi;
-pub mod sync;
-pub mod syscall;
-pub mod task;
-pub mod timer;
-pub mod trap;
+#[macro_use]
+mod console;
+mod config;
+mod drivers;
+pub mod fs;
+pub mod lang_items;
+pub mod mm;
+pub mod sbi;
+pub mod sync;
+pub mod syscall;
+pub mod task;
+pub mod timer;
+pub mod trap;
-use core::arch::global_asm;
+use core::arch::global_asm;
global_asm!(include_str!("entry.asm"));
-/// clear BSS segment
-fn clear_bss() {
- extern "C" {
- fn sbss();
- fn ebss();
+/// clear BSS segment
+fn clear_bss() {
+ extern "C" {
+ fn sbss();
+ fn ebss();
}
- unsafe {
- core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
- .fill(0);
+ unsafe {
+ core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
+ .fill(0);
}
}
-#[no_mangle]
-/// the rust entry-point of os
-pub fn rust_main() -> ! {
- clear_bss();
+#[no_mangle]
+/// the rust entry-point of os
+pub fn rust_main() -> ! {
+ clear_bss();
println!("[kernel] Hello, world!");
- mm::init();
- mm::remap_test();
- trap::init();
- trap::enable_timer_interrupt();
- timer::set_next_trigger();
- fs::list_apps();
- task::add_initproc();
- task::run_tasks();
+ mm::init();
+ mm::remap_test();
+ trap::init();
+ trap::enable_timer_interrupt();
+ timer::set_next_trigger();
+ fs::list_apps();
+ task::add_initproc();
+ task::run_tasks();
panic!("Unreachable in rust_main!");
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -
//! Implementation of physical and virtual address and page number.
-use super::PageTableEntry;
-use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
-use core::fmt::{self, Debug, Formatter};
+address.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+
//! Implementation of physical and virtual address and page number.
+use super::PageTableEntry;
+use crate::config::{PAGE_SIZE, PAGE_SIZE_BITS};
+use core::fmt::{self, Debug, Formatter};
-const PA_WIDTH_SV39: usize = 56;
-const VA_WIDTH_SV39: usize = 39;
-const PPN_WIDTH_SV39: usize = PA_WIDTH_SV39 - PAGE_SIZE_BITS;
-const VPN_WIDTH_SV39: usize = VA_WIDTH_SV39 - PAGE_SIZE_BITS;
+const PA_WIDTH_SV39: usize = 56;
+const VA_WIDTH_SV39: usize = 39;
+const PPN_WIDTH_SV39: usize = PA_WIDTH_SV39 - PAGE_SIZE_BITS;
+const VPN_WIDTH_SV39: usize = VA_WIDTH_SV39 - PAGE_SIZE_BITS;
-/// Definitions
-#[repr(C)]
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-pub struct PhysAddr(pub usize);
+/// Definitions
+#[repr(C)]
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub struct PhysAddr(pub usize);
-#[repr(C)]
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-///virtual address
-pub struct VirtAddr(pub usize);
+#[repr(C)]
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+///virtual address
+pub struct VirtAddr(pub usize);
-#[repr(C)]
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-///phiscal page number
-pub struct PhysPageNum(pub usize);
+#[repr(C)]
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+///phiscal page number
+pub struct PhysPageNum(pub usize);
-#[repr(C)]
-#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-///virtual page number
-pub struct VirtPageNum(pub usize);
+#[repr(C)]
+#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+///virtual page number
+pub struct VirtPageNum(pub usize);
-/// Debugging
+/// Debugging
-impl Debug for VirtAddr {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("VA:{:#x}", self.0))
+impl Debug for VirtAddr {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("VA:{:#x}", self.0))
}
}
-impl Debug for VirtPageNum {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("VPN:{:#x}", self.0))
+impl Debug for VirtPageNum {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("VPN:{:#x}", self.0))
}
}
-impl Debug for PhysAddr {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("PA:{:#x}", self.0))
+impl Debug for PhysAddr {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("PA:{:#x}", self.0))
}
}
-impl Debug for PhysPageNum {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("PPN:{:#x}", self.0))
+impl Debug for PhysPageNum {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("PPN:{:#x}", self.0))
}
}
-/// T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
-/// T -> usize: T.0
-/// usize -> T: usize.into()
+/// T: {PhysAddr, VirtAddr, PhysPageNum, VirtPageNum}
+/// T -> usize: T.0
+/// usize -> T: usize.into()
-impl From<usize> for PhysAddr {
- fn from(v: usize) -> Self {
- Self(v & ((1 << PA_WIDTH_SV39) - 1))
+impl From<usize> for PhysAddr {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << PA_WIDTH_SV39) - 1))
}
}
-impl From<usize> for PhysPageNum {
- fn from(v: usize) -> Self {
- Self(v & ((1 << PPN_WIDTH_SV39) - 1))
+impl From<usize> for PhysPageNum {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << PPN_WIDTH_SV39) - 1))
}
}
-impl From<usize> for VirtAddr {
- fn from(v: usize) -> Self {
- Self(v & ((1 << VA_WIDTH_SV39) - 1))
+impl From<usize> for VirtAddr {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << VA_WIDTH_SV39) - 1))
}
}
-impl From<usize> for VirtPageNum {
- fn from(v: usize) -> Self {
- Self(v & ((1 << VPN_WIDTH_SV39) - 1))
+impl From<usize> for VirtPageNum {
+ fn from(v: usize) -> Self {
+ Self(v & ((1 << VPN_WIDTH_SV39) - 1))
}
}
-impl From<PhysAddr> for usize {
- fn from(v: PhysAddr) -> Self {
- v.0
+impl From<PhysAddr> for usize {
+ fn from(v: PhysAddr) -> Self {
+ v.0
+ }
+}
+impl From<PhysPageNum> for usize {
+ fn from(v: PhysPageNum) -> Self {
+ v.0
+ }
+}
+impl From<VirtAddr> for usize {
+ fn from(v: VirtAddr) -> Self {
+ if v.0 >= (1 << (VA_WIDTH_SV39 - 1)) {
+ v.0 | (!((1 << VA_WIDTH_SV39) - 1))
+ } else {
+ v.0
+ }
}
}
-impl From<PhysPageNum> for usize {
- fn from(v: PhysPageNum) -> Self {
- v.0
+impl From<VirtPageNum> for usize {
+ fn from(v: VirtPageNum) -> Self {
+ v.0
+ }
+}
+///
+impl VirtAddr {
+ ///`VirtAddr`->`VirtPageNum`
+ pub fn floor(&self) -> VirtPageNum {
+ VirtPageNum(self.0 / PAGE_SIZE)
+ }
+ ///`VirtAddr`->`VirtPageNum`
+ pub fn ceil(&self) -> VirtPageNum {
+ if self.0 == 0 {
+ VirtPageNum(0)
+ } else {
+ VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
+ }
+ }
+ ///Get page offset
+ pub fn page_offset(&self) -> usize {
+ self.0 & (PAGE_SIZE - 1)
+ }
+ ///Check page aligned
+ pub fn aligned(&self) -> bool {
+ self.page_offset() == 0
+ }
+}
+impl From<VirtAddr> for VirtPageNum {
+ fn from(v: VirtAddr) -> Self {
+ assert_eq!(v.page_offset(), 0);
+ v.floor()
}
}
-impl From<VirtAddr> for usize {
- fn from(v: VirtAddr) -> Self {
- if v.0 >= (1 << (VA_WIDTH_SV39 - 1)) {
- v.0 | (!((1 << VA_WIDTH_SV39) - 1))
- } else {
- v.0
+impl From<VirtPageNum> for VirtAddr {
+ fn from(v: VirtPageNum) -> Self {
+ Self(v.0 << PAGE_SIZE_BITS)
+ }
+}
+impl PhysAddr {
+ ///`PhysAddr`->`PhysPageNum`
+ pub fn floor(&self) -> PhysPageNum {
+ PhysPageNum(self.0 / PAGE_SIZE)
+ }
+ ///`PhysAddr`->`PhysPageNum`
+ pub fn ceil(&self) -> PhysPageNum {
+ if self.0 == 0 {
+ PhysPageNum(0)
+ } else {
+ PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
+ }
+ }
+ ///Get page offset
+ pub fn page_offset(&self) -> usize {
+ self.0 & (PAGE_SIZE - 1)
+ }
+ ///Check page aligned
+ pub fn aligned(&self) -> bool {
+ self.page_offset() == 0
+ }
+}
+impl From<PhysAddr> for PhysPageNum {
+ fn from(v: PhysAddr) -> Self {
+ assert_eq!(v.page_offset(), 0);
+ v.floor()
+ }
+}
+impl From<PhysPageNum> for PhysAddr {
+ fn from(v: PhysPageNum) -> Self {
+ Self(v.0 << PAGE_SIZE_BITS)
+ }
+}
+
+impl VirtPageNum {
+ ///Return VPN 3 level index
+ pub fn indexes(&self) -> [usize; 3] {
+ let mut vpn = self.0;
+ let mut idx = [0usize; 3];
+ for i in (0..3).rev() {
+ idx[i] = vpn & 511;
+ vpn >>= 9;
+ }
+ idx
+ }
+}
+
+impl PhysAddr {
+ ///Get reference to `PhysAddr` value
+ pub fn get_ref<T>(&self) -> &'static T {
+ unsafe { (self.0 as *const T).as_ref().unwrap() }
+ }
+ ///Get mutable reference to `PhysAddr` value
+ pub fn get_mut<T>(&self) -> &'static mut T {
+ unsafe { (self.0 as *mut T).as_mut().unwrap() }
+ }
+}
+impl PhysPageNum {
+ ///Get `PageTableEntry` on `PhysPageNum`
+ pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
+ let pa: PhysAddr = (*self).into();
+ unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512) }
+ }
+ ///Get u8 array on `PhysPageNum`
+ pub fn get_bytes_array(&self) -> &'static mut [u8] {
+ let pa: PhysAddr = (*self).into();
+ unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096) }
+ }
+ ///Get Get mutable reference to `PhysAddr` value on `PhysPageNum`
+ pub fn get_mut<T>(&self) -> &'static mut T {
+ let pa: PhysAddr = (*self).into();
+ pa.get_mut()
+ }
+}
+///Add value by one
+pub trait StepByOne {
+ ///Add value by one
+ fn step(&mut self);
+}
+impl StepByOne for VirtPageNum {
+ fn step(&mut self) {
+ self.0 += 1;
+ }
+}
+impl StepByOne for PhysPageNum {
+ fn step(&mut self) {
+ self.0 += 1;
+ }
+}
+
+#[derive(Copy, Clone)]
+/// a simple range structure for type T
+pub struct SimpleRange<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ l: T,
+ r: T,
+}
+impl<T> SimpleRange<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ pub fn new(start: T, end: T) -> Self {
+ assert!(start <= end, "start {:?} > end {:?}!", start, end);
+ Self { l: start, r: end }
+ }
+ pub fn get_start(&self) -> T {
+ self.l
+ }
+ pub fn get_end(&self) -> T {
+ self.r
+ }
+}
+impl<T> IntoIterator for SimpleRange<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ type Item = T;
+ type IntoIter = SimpleRangeIterator<T>;
+ fn into_iter(self) -> Self::IntoIter {
+ SimpleRangeIterator::new(self.l, self.r)
+ }
+}
+/// iterator for the simple range structure
+pub struct SimpleRangeIterator<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ current: T,
+ end: T,
+}
+impl<T> SimpleRangeIterator<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ pub fn new(l: T, r: T) -> Self {
+ Self { current: l, end: r }
+ }
+}
+impl<T> Iterator for SimpleRangeIterator<T>
+where
+ T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
+{
+ type Item = T;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.current == self.end {
+ None
+ } else {
+ let t = self.current;
+ self.current.step();
+ Some(t)
}
}
}
-impl From<VirtPageNum> for usize {
- fn from(v: VirtPageNum) -> Self {
- v.0
- }
-}
-///
-impl VirtAddr {
- ///`VirtAddr`->`VirtPageNum`
- pub fn floor(&self) -> VirtPageNum {
- VirtPageNum(self.0 / PAGE_SIZE)
- }
- ///`VirtAddr`->`VirtPageNum`
- pub fn ceil(&self) -> VirtPageNum {
- VirtPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
- }
- ///Get page offset
- pub fn page_offset(&self) -> usize {
- self.0 & (PAGE_SIZE - 1)
- }
- ///Check page aligned
- pub fn aligned(&self) -> bool {
- self.page_offset() == 0
- }
-}
-impl From<VirtAddr> for VirtPageNum {
- fn from(v: VirtAddr) -> Self {
- assert_eq!(v.page_offset(), 0);
- v.floor()
- }
-}
-impl From<VirtPageNum> for VirtAddr {
- fn from(v: VirtPageNum) -> Self {
- Self(v.0 << PAGE_SIZE_BITS)
- }
-}
-impl PhysAddr {
- ///`PhysAddr`->`PhysPageNum`
- pub fn floor(&self) -> PhysPageNum {
- PhysPageNum(self.0 / PAGE_SIZE)
- }
- ///`PhysAddr`->`PhysPageNum`
- pub fn ceil(&self) -> PhysPageNum {
- PhysPageNum((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
- }
- ///Get page offset
- pub fn page_offset(&self) -> usize {
- self.0 & (PAGE_SIZE - 1)
- }
- ///Check page aligned
- pub fn aligned(&self) -> bool {
- self.page_offset() == 0
- }
-}
-impl From<PhysAddr> for PhysPageNum {
- fn from(v: PhysAddr) -> Self {
- assert_eq!(v.page_offset(), 0);
- v.floor()
- }
-}
-impl From<PhysPageNum> for PhysAddr {
- fn from(v: PhysPageNum) -> Self {
- Self(v.0 << PAGE_SIZE_BITS)
- }
-}
-
-impl VirtPageNum {
- ///Return VPN 3 level index
- pub fn indexes(&self) -> [usize; 3] {
- let mut vpn = self.0;
- let mut idx = [0usize; 3];
- for i in (0..3).rev() {
- idx[i] = vpn & 511;
- vpn >>= 9;
- }
- idx
- }
-}
-
-impl PhysAddr {
- ///Get reference to `PhysAddr` value
- pub fn get_ref<T>(&self) -> &'static T {
- unsafe { (self.0 as *const T).as_ref().unwrap() }
- }
- ///Get mutable reference to `PhysAddr` value
- pub fn get_mut<T>(&self) -> &'static mut T {
- unsafe { (self.0 as *mut T).as_mut().unwrap() }
- }
-}
-impl PhysPageNum {
- ///Get `PageTableEntry` on `PhysPageNum`
- pub fn get_pte_array(&self) -> &'static mut [PageTableEntry] {
- let pa: PhysAddr = (*self).into();
- unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut PageTableEntry, 512) }
- }
- ///Get u8 array on `PhysPageNum`
- pub fn get_bytes_array(&self) -> &'static mut [u8] {
- let pa: PhysAddr = (*self).into();
- unsafe { core::slice::from_raw_parts_mut(pa.0 as *mut u8, 4096) }
- }
- ///Get Get mutable reference to `PhysAddr` value on `PhysPageNum`
- pub fn get_mut<T>(&self) -> &'static mut T {
- let pa: PhysAddr = (*self).into();
- pa.get_mut()
- }
-}
-///Add value by one
-pub trait StepByOne {
- ///Add value by one
- fn step(&mut self);
-}
-impl StepByOne for VirtPageNum {
- fn step(&mut self) {
- self.0 += 1;
- }
-}
-impl StepByOne for PhysPageNum {
- fn step(&mut self) {
- self.0 += 1;
- }
-}
-
-#[derive(Copy, Clone)]
-/// a simple range structure for type T
-pub struct SimpleRange<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- l: T,
- r: T,
-}
-impl<T> SimpleRange<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- pub fn new(start: T, end: T) -> Self {
- assert!(start <= end, "start {:?} > end {:?}!", start, end);
- Self { l: start, r: end }
- }
- pub fn get_start(&self) -> T {
- self.l
- }
- pub fn get_end(&self) -> T {
- self.r
- }
-}
-impl<T> IntoIterator for SimpleRange<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- type Item = T;
- type IntoIter = SimpleRangeIterator<T>;
- fn into_iter(self) -> Self::IntoIter {
- SimpleRangeIterator::new(self.l, self.r)
- }
-}
-/// iterator for the simple range structure
-pub struct SimpleRangeIterator<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- current: T,
- end: T,
-}
-impl<T> SimpleRangeIterator<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- pub fn new(l: T, r: T) -> Self {
- Self { current: l, end: r }
- }
-}
-impl<T> Iterator for SimpleRangeIterator<T>
-where
- T: StepByOne + Copy + PartialEq + PartialOrd + Debug,
-{
- type Item = T;
- fn next(&mut self) -> Option<Self::Item> {
- if self.current == self.end {
- None
- } else {
- let t = self.current;
- self.current.step();
- Some(t)
- }
- }
-}
-/// a simple range structure for virtual page number
-pub type VPNRange = SimpleRange<VirtPageNum>;
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -
//! Implementation of [`FrameAllocator`] which
-//! controls all the frames in the operating system.
-use super::{PhysAddr, PhysPageNum};
-use crate::config::MEMORY_END;
-use crate::sync::UPSafeCell;
-use alloc::vec::Vec;
-use core::fmt::{self, Debug, Formatter};
-use lazy_static::*;
+frame_allocator.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+
//! Implementation of [`FrameAllocator`] which
+//! controls all the frames in the operating system.
+use super::{PhysAddr, PhysPageNum};
+use crate::config::MEMORY_END;
+use crate::sync::UPSafeCell;
+use alloc::vec::Vec;
+use core::fmt::{self, Debug, Formatter};
+use lazy_static::*;
-/// manage a frame which has the same lifecycle as the tracker
-pub struct FrameTracker {
- ///
- pub ppn: PhysPageNum,
+/// manage a frame which has the same lifecycle as the tracker
+pub struct FrameTracker {
+ ///
+ pub ppn: PhysPageNum,
}
-impl FrameTracker {
- ///Create an empty `FrameTracker`
- pub fn new(ppn: PhysPageNum) -> Self {
- // page cleaning
- let bytes_array = ppn.get_bytes_array();
- for i in bytes_array {
- *i = 0;
+impl FrameTracker {
+ ///Create an empty `FrameTracker`
+ pub fn new(ppn: PhysPageNum) -> Self {
+ // page cleaning
+ let bytes_array = ppn.get_bytes_array();
+ for i in bytes_array {
+ *i = 0;
}
- Self { ppn }
+ Self { ppn }
}
}
-impl Debug for FrameTracker {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- f.write_fmt(format_args!("FrameTracker:PPN={:#x}", self.ppn.0))
+impl Debug for FrameTracker {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("FrameTracker:PPN={:#x}", self.ppn.0))
}
}
-impl Drop for FrameTracker {
- fn drop(&mut self) {
- frame_dealloc(self.ppn);
+impl Drop for FrameTracker {
+ fn drop(&mut self) {
+ frame_dealloc(self.ppn);
}
}
-trait FrameAllocator {
- fn new() -> Self;
- fn alloc(&mut self) -> Option<PhysPageNum>;
- fn dealloc(&mut self, ppn: PhysPageNum);
+trait FrameAllocator {
+ fn new() -> Self;
+ fn alloc(&mut self) -> Option<PhysPageNum>;
+ fn dealloc(&mut self, ppn: PhysPageNum);
}
-/// an implementation for frame allocator
-pub struct StackFrameAllocator {
- current: usize,
- end: usize,
- recycled: Vec<usize>,
+/// an implementation for frame allocator
+pub struct StackFrameAllocator {
+ current: usize,
+ end: usize,
+ recycled: Vec<usize>,
}
-impl StackFrameAllocator {
- pub fn init(&mut self, l: PhysPageNum, r: PhysPageNum) {
- self.current = l.0;
- self.end = r.0;
- println!("last {} Physical Frames.", self.end - self.current);
+impl StackFrameAllocator {
+ pub fn init(&mut self, l: PhysPageNum, r: PhysPageNum) {
+ self.current = l.0;
+ self.end = r.0;
+ println!("last {} Physical Frames.", self.end - self.current);
}
}
-impl FrameAllocator for StackFrameAllocator {
- fn new() -> Self {
- Self {
- current: 0,
- end: 0,
- recycled: Vec::new(),
+impl FrameAllocator for StackFrameAllocator {
+ fn new() -> Self {
+ Self {
+ current: 0,
+ end: 0,
+ recycled: Vec::new(),
}
}
- fn alloc(&mut self) -> Option<PhysPageNum> {
- if let Some(ppn) = self.recycled.pop() {
- Some(ppn.into())
- } else if self.current == self.end {
- None
- } else {
- self.current += 1;
- Some((self.current - 1).into())
+ fn alloc(&mut self) -> Option<PhysPageNum> {
+ if let Some(ppn) = self.recycled.pop() {
+ Some(ppn.into())
+ } else if self.current == self.end {
+ None
+ } else {
+ self.current += 1;
+ Some((self.current - 1).into())
}
}
- fn dealloc(&mut self, ppn: PhysPageNum) {
- let ppn = ppn.0;
- // validity check
- if ppn >= self.current || self.recycled.iter().any(|&v| v == ppn) {
- panic!("Frame ppn={:#x} has not been allocated!", ppn);
+ fn dealloc(&mut self, ppn: PhysPageNum) {
+ let ppn = ppn.0;
+ // validity check
+ if ppn >= self.current || self.recycled.iter().any(|&v| v == ppn) {
+ panic!("Frame ppn={:#x} has not been allocated!", ppn);
}
- // recycle
- self.recycled.push(ppn);
+ // recycle
+ self.recycled.push(ppn);
}
}
-type FrameAllocatorImpl = StackFrameAllocator;
+type FrameAllocatorImpl = StackFrameAllocator;
-lazy_static! {
- /// frame allocator instance through lazy_static!
- pub static ref FRAME_ALLOCATOR: UPSafeCell<FrameAllocatorImpl> =
- unsafe { UPSafeCell::new(FrameAllocatorImpl::new()) };
+lazy_static! {
+ /// frame allocator instance through lazy_static!
+ pub static ref FRAME_ALLOCATOR: UPSafeCell<FrameAllocatorImpl> =
+ unsafe { UPSafeCell::new(FrameAllocatorImpl::new()) };
}
-/// initiate the frame allocator using `ekernel` and `MEMORY_END`
-pub fn init_frame_allocator() {
- extern "C" {
- fn ekernel();
+/// initiate the frame allocator using `ekernel` and `MEMORY_END`
+pub fn init_frame_allocator() {
+ extern "C" {
+ fn ekernel();
}
- FRAME_ALLOCATOR.exclusive_access().init(
- PhysAddr::from(ekernel as usize).ceil(),
- PhysAddr::from(MEMORY_END).floor(),
+ FRAME_ALLOCATOR.exclusive_access().init(
+ PhysAddr::from(ekernel as usize).ceil(),
+ PhysAddr::from(MEMORY_END).floor(),
);
}
-/// allocate a frame
-pub fn frame_alloc() -> Option<FrameTracker> {
- FRAME_ALLOCATOR
- .exclusive_access()
- .alloc()
- .map(FrameTracker::new)
+/// allocate a frame
+pub fn frame_alloc() -> Option<FrameTracker> {
+ FRAME_ALLOCATOR
+ .exclusive_access()
+ .alloc()
+ .map(FrameTracker::new)
}
-/// deallocate a frame
-pub fn frame_dealloc(ppn: PhysPageNum) {
- FRAME_ALLOCATOR.exclusive_access().dealloc(ppn);
+/// deallocate a frame
+pub fn frame_dealloc(ppn: PhysPageNum) {
+ FRAME_ALLOCATOR.exclusive_access().dealloc(ppn);
}
-#[allow(unused)]
-/// a simple test for frame allocator
-pub fn frame_allocator_test() {
- let mut v: Vec<FrameTracker> = Vec::new();
- for i in 0..5 {
- let frame = frame_alloc().unwrap();
- println!("{:?}", frame);
- v.push(frame);
+#[allow(unused)]
+/// a simple test for frame allocator
+pub fn frame_allocator_test() {
+ let mut v: Vec<FrameTracker> = Vec::new();
+ for i in 0..5 {
+ let frame = frame_alloc().unwrap();
+ println!("{:?}", frame);
+ v.push(frame);
}
- v.clear();
- for i in 0..5 {
- let frame = frame_alloc().unwrap();
- println!("{:?}", frame);
- v.push(frame);
+ v.clear();
+ for i in 0..5 {
+ let frame = frame_alloc().unwrap();
+ println!("{:?}", frame);
+ v.push(frame);
}
- drop(v);
+ drop(v);
println!("frame_allocator_test passed!");
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -
//! The global allocator
-use crate::config::KERNEL_HEAP_SIZE;
-use buddy_system_allocator::LockedHeap;
+heap_allocator.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+
//! The global allocator
+use crate::config::KERNEL_HEAP_SIZE;
+use buddy_system_allocator::LockedHeap;
-#[global_allocator]
-/// heap allocator instance
-static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
+#[global_allocator]
+/// heap allocator instance
+static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty();
-#[alloc_error_handler]
-/// panic when heap allocation error occurs
-pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
- panic!("Heap allocation error, layout = {:?}", layout);
+#[alloc_error_handler]
+/// panic when heap allocation error occurs
+pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
+ panic!("Heap allocation error, layout = {:?}", layout);
}
-/// heap space ([u8; KERNEL_HEAP_SIZE])
-static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];
-/// initiate heap allocator
-pub fn init_heap() {
- unsafe {
- HEAP_ALLOCATOR
- .lock()
- .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE);
+/// heap space ([u8; KERNEL_HEAP_SIZE])
+static mut HEAP_SPACE: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE];
+/// initiate heap allocator
+pub fn init_heap() {
+ unsafe {
+ HEAP_ALLOCATOR
+ .lock()
+ .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE);
}
}
-#[allow(unused)]
-pub fn heap_test() {
- use alloc::boxed::Box;
- use alloc::vec::Vec;
- extern "C" {
- fn sbss();
- fn ebss();
+#[allow(unused)]
+pub fn heap_test() {
+ use alloc::boxed::Box;
+ use alloc::vec::Vec;
+ extern "C" {
+ fn sbss();
+ fn ebss();
}
- let bss_range = sbss as usize..ebss as usize;
- let a = Box::new(5);
- assert_eq!(*a, 5);
- assert!(bss_range.contains(&(a.as_ref() as *const _ as usize)));
- drop(a);
- let mut v: Vec<usize> = Vec::new();
- for i in 0..500 {
- v.push(i);
+ let bss_range = sbss as usize..ebss as usize;
+ let a = Box::new(5);
+ assert_eq!(*a, 5);
+ assert!(bss_range.contains(&(a.as_ref() as *const _ as usize)));
+ drop(a);
+ let mut v: Vec<usize> = Vec::new();
+ for i in 0..500 {
+ v.push(i);
}
- for (i, val) in v.iter().take(500).enumerate() {
- assert_eq!(*val, i);
+ for (i, val) in v.iter().take(500).enumerate() {
+ assert_eq!(*val, i);
}
- assert!(bss_range.contains(&(v.as_ptr() as usize)));
- drop(v);
+ assert!(bss_range.contains(&(v.as_ptr() as usize)));
+ drop(v);
println!("heap_test passed!");
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -
//! Implementation of [`MapArea`] and [`MemorySet`].
-use super::{frame_alloc, FrameTracker};
-use super::{PTEFlags, PageTable, PageTableEntry};
-use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
-use super::{StepByOne, VPNRange};
-use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE};
-use crate::sync::UPSafeCell;
-use alloc::collections::BTreeMap;
-use alloc::sync::Arc;
-use alloc::vec::Vec;
-use core::arch::asm;
-use lazy_static::*;
-use riscv::register::satp;
+memory_set.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+
//! Implementation of [`MapArea`] and [`MemorySet`].
+use super::{frame_alloc, FrameTracker};
+use super::{PTEFlags, PageTable, PageTableEntry};
+use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
+use super::{StepByOne, VPNRange};
+use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE, TRAP_CONTEXT, USER_STACK_SIZE};
+use crate::sync::UPSafeCell;
+use alloc::collections::BTreeMap;
+use alloc::sync::Arc;
+use alloc::vec::Vec;
+use core::arch::asm;
+use lazy_static::*;
+use riscv::register::satp;
-extern "C" {
- fn stext();
- fn etext();
- fn srodata();
- fn erodata();
- fn sdata();
- fn edata();
- fn sbss_with_stack();
- fn ebss();
- fn ekernel();
- fn strampoline();
+extern "C" {
+ fn stext();
+ fn etext();
+ fn srodata();
+ fn erodata();
+ fn sdata();
+ fn edata();
+ fn sbss_with_stack();
+ fn ebss();
+ fn ekernel();
+ fn strampoline();
}
-lazy_static! {
- /// a memory set instance through lazy_static! managing kernel space
- pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> =
- Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) });
+lazy_static! {
+ /// a memory set instance through lazy_static! managing kernel space
+ pub static ref KERNEL_SPACE: Arc<UPSafeCell<MemorySet>> =
+ Arc::new(unsafe { UPSafeCell::new(MemorySet::new_kernel()) });
}
-///Get kernelspace root ppn
-pub fn kernel_token() -> usize {
- KERNEL_SPACE.exclusive_access().token()
+///Get kernelspace root ppn
+pub fn kernel_token() -> usize {
+ KERNEL_SPACE.exclusive_access().token()
}
-/// memory set structure, controls virtual-memory space
-pub struct MemorySet {
- page_table: PageTable,
- areas: Vec<MapArea>,
+/// memory set structure, controls virtual-memory space
+pub struct MemorySet {
+ page_table: PageTable,
+ areas: Vec<MapArea>,
}
-impl MemorySet {
- ///Create an empty `MemorySet`
- pub fn new_bare() -> Self {
- Self {
- page_table: PageTable::new(),
- areas: Vec::new(),
+impl MemorySet {
+ ///Create an empty `MemorySet`
+ pub fn new_bare() -> Self {
+ Self {
+ page_table: PageTable::new(),
+ areas: Vec::new(),
}
}
- ///Get pagetable `root_ppn`
- pub fn token(&self) -> usize {
- self.page_table.token()
+ ///Get pagetable `root_ppn`
+ pub fn token(&self) -> usize {
+ self.page_table.token()
}
- /// Assume that no conflicts.
- pub fn insert_framed_area(
- &mut self,
- start_va: VirtAddr,
- end_va: VirtAddr,
- permission: MapPermission,
+ /// Assume that no conflicts.
+ pub fn insert_framed_area(
+ &mut self,
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ permission: MapPermission,
) {
- self.push(
- MapArea::new(start_va, end_va, MapType::Framed, permission),
+ self.push(
+ MapArea::new(start_va, end_va, MapType::Framed, permission),
None,
);
}
- ///Remove `MapArea` that starts with `start_vpn`
- pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) {
- if let Some((idx, area)) = self
- .areas
- .iter_mut()
- .enumerate()
- .find(|(_, area)| area.vpn_range.get_start() == start_vpn)
+ ///Remove `MapArea` that starts with `start_vpn`
+ pub fn remove_area_with_start_vpn(&mut self, start_vpn: VirtPageNum) {
+ if let Some((idx, area)) = self
+ .areas
+ .iter_mut()
+ .enumerate()
+ .find(|(_, area)| area.vpn_range.get_start() == start_vpn)
{
- area.unmap(&mut self.page_table);
- self.areas.remove(idx);
+ area.unmap(&mut self.page_table);
+ self.areas.remove(idx);
}
}
- fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
- map_area.map(&mut self.page_table);
- if let Some(data) = data {
- map_area.copy_data(&mut self.page_table, data);
+ fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) {
+ map_area.map(&mut self.page_table);
+ if let Some(data) = data {
+ map_area.copy_data(&mut self.page_table, data);
}
- self.areas.push(map_area);
+ self.areas.push(map_area);
}
- /// Mention that trampoline is not collected by areas.
- fn map_trampoline(&mut self) {
- self.page_table.map(
- VirtAddr::from(TRAMPOLINE).into(),
- PhysAddr::from(strampoline as usize).into(),
- PTEFlags::R | PTEFlags::X,
+ /// Mention that trampoline is not collected by areas.
+ fn map_trampoline(&mut self) {
+ self.page_table.map(
+ VirtAddr::from(TRAMPOLINE).into(),
+ PhysAddr::from(strampoline as usize).into(),
+ PTEFlags::R | PTEFlags::X,
);
}
- /// Without kernel stacks.
- pub fn new_kernel() -> Self {
- let mut memory_set = Self::new_bare();
- // map trampoline
- memory_set.map_trampoline();
- // map kernel sections
- println!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
- println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
- println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
+ /// Without kernel stacks.
+ pub fn new_kernel() -> Self {
+ let mut memory_set = Self::new_bare();
+ // map trampoline
+ memory_set.map_trampoline();
+ // map kernel sections
+ println!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
+ println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
+ println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
println!(
".bss [{:#x}, {:#x})",
- sbss_with_stack as usize, ebss as usize
+ sbss_with_stack as usize, ebss as usize
);
println!("mapping .text section");
- memory_set.push(
- MapArea::new(
- (stext as usize).into(),
- (etext as usize).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::X,
+ memory_set.push(
+ MapArea::new(
+ (stext as usize).into(),
+ (etext as usize).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::X,
),
None,
);
println!("mapping .rodata section");
- memory_set.push(
- MapArea::new(
- (srodata as usize).into(),
- (erodata as usize).into(),
- MapType::Identical,
- MapPermission::R,
+ memory_set.push(
+ MapArea::new(
+ (srodata as usize).into(),
+ (erodata as usize).into(),
+ MapType::Identical,
+ MapPermission::R,
),
None,
);
println!("mapping .data section");
- memory_set.push(
- MapArea::new(
- (sdata as usize).into(),
- (edata as usize).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ memory_set.push(
+ MapArea::new(
+ (sdata as usize).into(),
+ (edata as usize).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
println!("mapping .bss section");
- memory_set.push(
- MapArea::new(
- (sbss_with_stack as usize).into(),
- (ebss as usize).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ memory_set.push(
+ MapArea::new(
+ (sbss_with_stack as usize).into(),
+ (ebss as usize).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
println!("mapping physical memory");
- memory_set.push(
- MapArea::new(
- (ekernel as usize).into(),
- MEMORY_END.into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ memory_set.push(
+ MapArea::new(
+ (ekernel as usize).into(),
+ MEMORY_END.into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
println!("mapping memory-mapped registers");
- for pair in MMIO {
- memory_set.push(
- MapArea::new(
- (*pair).0.into(),
- ((*pair).0 + (*pair).1).into(),
- MapType::Identical,
- MapPermission::R | MapPermission::W,
+ for pair in MMIO {
+ memory_set.push(
+ MapArea::new(
+ (*pair).0.into(),
+ ((*pair).0 + (*pair).1).into(),
+ MapType::Identical,
+ MapPermission::R | MapPermission::W,
),
None,
);
}
- memory_set
+ memory_set
}
- /// Include sections in elf and trampoline and TrapContext and user stack,
- /// also returns user_sp and entry point.
- pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
- let mut memory_set = Self::new_bare();
- // map trampoline
- memory_set.map_trampoline();
- // map program headers of elf, with U flag
- let elf = xmas_elf::ElfFile::new(elf_data).unwrap();
- let elf_header = elf.header;
- let magic = elf_header.pt1.magic;
- assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
- let ph_count = elf_header.pt2.ph_count();
- let mut max_end_vpn = VirtPageNum(0);
- for i in 0..ph_count {
- let ph = elf.program_header(i).unwrap();
- if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
- let start_va: VirtAddr = (ph.virtual_addr() as usize).into();
- let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into();
- let mut map_perm = MapPermission::U;
- let ph_flags = ph.flags();
- if ph_flags.is_read() {
- map_perm |= MapPermission::R;
+ /// Include sections in elf and trampoline and TrapContext and user stack,
+ /// also returns user_sp and entry point.
+ pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
+ let mut memory_set = Self::new_bare();
+ // map trampoline
+ memory_set.map_trampoline();
+ // map program headers of elf, with U flag
+ let elf = xmas_elf::ElfFile::new(elf_data).unwrap();
+ let elf_header = elf.header;
+ let magic = elf_header.pt1.magic;
+ assert_eq!(magic, [0x7f, 0x45, 0x4c, 0x46], "invalid elf!");
+ let ph_count = elf_header.pt2.ph_count();
+ let mut max_end_vpn = VirtPageNum(0);
+ for i in 0..ph_count {
+ let ph = elf.program_header(i).unwrap();
+ if ph.get_type().unwrap() == xmas_elf::program::Type::Load {
+ let start_va: VirtAddr = (ph.virtual_addr() as usize).into();
+ let end_va: VirtAddr = ((ph.virtual_addr() + ph.mem_size()) as usize).into();
+ let mut map_perm = MapPermission::U;
+ let ph_flags = ph.flags();
+ if ph_flags.is_read() {
+ map_perm |= MapPermission::R;
}
- if ph_flags.is_write() {
- map_perm |= MapPermission::W;
+ if ph_flags.is_write() {
+ map_perm |= MapPermission::W;
}
- if ph_flags.is_execute() {
- map_perm |= MapPermission::X;
+ if ph_flags.is_execute() {
+ map_perm |= MapPermission::X;
}
- let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm);
- max_end_vpn = map_area.vpn_range.get_end();
- memory_set.push(
- map_area,
- Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]),
+ let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm);
+ max_end_vpn = map_area.vpn_range.get_end();
+ memory_set.push(
+ map_area,
+ Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]),
);
}
}
- // map user stack with U flags
- let max_end_va: VirtAddr = max_end_vpn.into();
- let mut user_stack_bottom: usize = max_end_va.into();
- // guard page
- user_stack_bottom += PAGE_SIZE;
- let user_stack_top = user_stack_bottom + USER_STACK_SIZE;
- memory_set.push(
- MapArea::new(
- user_stack_bottom.into(),
- user_stack_top.into(),
- MapType::Framed,
- MapPermission::R | MapPermission::W | MapPermission::U,
+ // map user stack with U flags
+ let max_end_va: VirtAddr = max_end_vpn.into();
+ let mut user_stack_bottom: usize = max_end_va.into();
+ // guard page
+ user_stack_bottom += PAGE_SIZE;
+ let user_stack_top = user_stack_bottom + USER_STACK_SIZE;
+ memory_set.push(
+ MapArea::new(
+ user_stack_bottom.into(),
+ user_stack_top.into(),
+ MapType::Framed,
+ MapPermission::R | MapPermission::W | MapPermission::U,
),
None,
);
- // map TrapContext
- memory_set.push(
- MapArea::new(
- TRAP_CONTEXT.into(),
- TRAMPOLINE.into(),
- MapType::Framed,
- MapPermission::R | MapPermission::W,
+ // map TrapContext
+ memory_set.push(
+ MapArea::new(
+ TRAP_CONTEXT.into(),
+ TRAMPOLINE.into(),
+ MapType::Framed,
+ MapPermission::R | MapPermission::W,
),
None,
);
(
- memory_set,
- user_stack_top,
- elf.header.pt2.entry_point() as usize,
+ memory_set,
+ user_stack_top,
+ elf.header.pt2.entry_point() as usize,
)
}
- ///Clone a same `MemorySet`
- pub fn from_existed_user(user_space: &MemorySet) -> MemorySet {
- let mut memory_set = Self::new_bare();
- // map trampoline
- memory_set.map_trampoline();
- // copy data sections/trap_context/user_stack
- for area in user_space.areas.iter() {
- let new_area = MapArea::from_another(area);
- memory_set.push(new_area, None);
- // copy data from another space
- for vpn in area.vpn_range {
- let src_ppn = user_space.translate(vpn).unwrap().ppn();
- let dst_ppn = memory_set.translate(vpn).unwrap().ppn();
- dst_ppn
- .get_bytes_array()
- .copy_from_slice(src_ppn.get_bytes_array());
+ ///Clone a same `MemorySet`
+ pub fn from_existed_user(user_space: &MemorySet) -> MemorySet {
+ let mut memory_set = Self::new_bare();
+ // map trampoline
+ memory_set.map_trampoline();
+ // copy data sections/trap_context/user_stack
+ for area in user_space.areas.iter() {
+ let new_area = MapArea::from_another(area);
+ memory_set.push(new_area, None);
+ // copy data from another space
+ for vpn in area.vpn_range {
+ let src_ppn = user_space.translate(vpn).unwrap().ppn();
+ let dst_ppn = memory_set.translate(vpn).unwrap().ppn();
+ dst_ppn
+ .get_bytes_array()
+ .copy_from_slice(src_ppn.get_bytes_array());
}
}
- memory_set
+ memory_set
}
- ///Refresh TLB with `sfence.vma`
- pub fn activate(&self) {
- let satp = self.page_table.token();
- unsafe {
- satp::write(satp);
+ ///Refresh TLB with `sfence.vma`
+ pub fn activate(&self) {
+ let satp = self.page_table.token();
+ unsafe {
+ satp::write(satp);
asm!("sfence.vma");
}
}
- ///Translate throuth pagetable
- pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
- self.page_table.translate(vpn)
+ ///Translate throuth pagetable
+ pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
+ self.page_table.translate(vpn)
}
- ///Remove all `MapArea`
- pub fn recycle_data_pages(&mut self) {
- //*self = Self::new_bare();
- self.areas.clear();
+ ///Remove all `MapArea`
+ pub fn recycle_data_pages(&mut self) {
+ //*self = Self::new_bare();
+ self.areas.clear();
}
}
-/// map area structure, controls a contiguous piece of virtual memory
-pub struct MapArea {
- vpn_range: VPNRange,
- data_frames: BTreeMap<VirtPageNum, FrameTracker>,
- map_type: MapType,
- map_perm: MapPermission,
+/// map area structure, controls a contiguous piece of virtual memory
+pub struct MapArea {
+ vpn_range: VPNRange,
+ data_frames: BTreeMap<VirtPageNum, FrameTracker>,
+ map_type: MapType,
+ map_perm: MapPermission,
}
-impl MapArea {
- pub fn new(
- start_va: VirtAddr,
- end_va: VirtAddr,
- map_type: MapType,
- map_perm: MapPermission,
- ) -> Self {
- let start_vpn: VirtPageNum = start_va.floor();
- let end_vpn: VirtPageNum = end_va.ceil();
- Self {
- vpn_range: VPNRange::new(start_vpn, end_vpn),
- data_frames: BTreeMap::new(),
- map_type,
- map_perm,
+impl MapArea {
+ pub fn new(
+ start_va: VirtAddr,
+ end_va: VirtAddr,
+ map_type: MapType,
+ map_perm: MapPermission,
+ ) -> Self {
+ let start_vpn: VirtPageNum = start_va.floor();
+ let end_vpn: VirtPageNum = end_va.ceil();
+ Self {
+ vpn_range: VPNRange::new(start_vpn, end_vpn),
+ data_frames: BTreeMap::new(),
+ map_type,
+ map_perm,
}
}
- pub fn from_another(another: &MapArea) -> Self {
- Self {
- vpn_range: VPNRange::new(another.vpn_range.get_start(), another.vpn_range.get_end()),
- data_frames: BTreeMap::new(),
- map_type: another.map_type,
- map_perm: another.map_perm,
+ pub fn from_another(another: &MapArea) -> Self {
+ Self {
+ vpn_range: VPNRange::new(another.vpn_range.get_start(), another.vpn_range.get_end()),
+ data_frames: BTreeMap::new(),
+ map_type: another.map_type,
+ map_perm: another.map_perm,
}
}
- pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
- let ppn: PhysPageNum;
- match self.map_type {
- MapType::Identical => {
- ppn = PhysPageNum(vpn.0);
+ pub fn map_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
+ let ppn: PhysPageNum;
+ match self.map_type {
+ MapType::Identical => {
+ ppn = PhysPageNum(vpn.0);
}
- MapType::Framed => {
- let frame = frame_alloc().unwrap();
- ppn = frame.ppn;
- self.data_frames.insert(vpn, frame);
+ MapType::Framed => {
+ let frame = frame_alloc().unwrap();
+ ppn = frame.ppn;
+ self.data_frames.insert(vpn, frame);
}
}
- let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
- page_table.map(vpn, ppn, pte_flags);
+ let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
+ page_table.map(vpn, ppn, pte_flags);
}
- pub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
- if self.map_type == MapType::Framed {
- self.data_frames.remove(&vpn);
+ pub fn unmap_one(&mut self, page_table: &mut PageTable, vpn: VirtPageNum) {
+ if self.map_type == MapType::Framed {
+ self.data_frames.remove(&vpn);
}
- page_table.unmap(vpn);
+ page_table.unmap(vpn);
}
- pub fn map(&mut self, page_table: &mut PageTable) {
- for vpn in self.vpn_range {
- self.map_one(page_table, vpn);
+ pub fn map(&mut self, page_table: &mut PageTable) {
+ for vpn in self.vpn_range {
+ self.map_one(page_table, vpn);
}
}
- pub fn unmap(&mut self, page_table: &mut PageTable) {
- for vpn in self.vpn_range {
- self.unmap_one(page_table, vpn);
+ pub fn unmap(&mut self, page_table: &mut PageTable) {
+ for vpn in self.vpn_range {
+ self.unmap_one(page_table, vpn);
}
}
- /// data: start-aligned but maybe with shorter length
- /// assume that all frames were cleared before
- pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) {
- assert_eq!(self.map_type, MapType::Framed);
- let mut start: usize = 0;
- let mut current_vpn = self.vpn_range.get_start();
- let len = data.len();
- loop {
- let src = &data[start..len.min(start + PAGE_SIZE)];
- let dst = &mut page_table
- .translate(current_vpn)
- .unwrap()
- .ppn()
- .get_bytes_array()[..src.len()];
- dst.copy_from_slice(src);
- start += PAGE_SIZE;
- if start >= len {
+ /// data: start-aligned but maybe with shorter length
+ /// assume that all frames were cleared before
+ pub fn copy_data(&mut self, page_table: &mut PageTable, data: &[u8]) {
+ assert_eq!(self.map_type, MapType::Framed);
+ let mut start: usize = 0;
+ let mut current_vpn = self.vpn_range.get_start();
+ let len = data.len();
+ loop {
+ let src = &data[start..len.min(start + PAGE_SIZE)];
+ let dst = &mut page_table
+ .translate(current_vpn)
+ .unwrap()
+ .ppn()
+ .get_bytes_array()[..src.len()];
+ dst.copy_from_slice(src);
+ start += PAGE_SIZE;
+ if start >= len {
break;
}
- current_vpn.step();
+ current_vpn.step();
}
}
}
-#[derive(Copy, Clone, PartialEq, Debug)]
-/// map type for memory set: identical or framed
-pub enum MapType {
- Identical,
- Framed,
+#[derive(Copy, Clone, PartialEq, Debug)]
+/// map type for memory set: identical or framed
+pub enum MapType {
+ Identical,
+ Framed,
}
-bitflags! {
- /// map permission corresponding to that in pte: `R W X U`
- pub struct MapPermission: u8 {
- ///Readable
- const R = 1 << 1;
- ///Writable
- const W = 1 << 2;
- ///Excutable
- const X = 1 << 3;
- ///Accessible in U mode
- const U = 1 << 4;
+bitflags! {
+ /// map permission corresponding to that in pte: `R W X U`
+ pub struct MapPermission: u8 {
+ ///Readable
+ const R = 1 << 1;
+ ///Writable
+ const W = 1 << 2;
+ ///Excutable
+ const X = 1 << 3;
+ ///Accessible in U mode
+ const U = 1 << 4;
}
}
-#[allow(unused)]
-///Check PageTable running correctly
-pub fn remap_test() {
- let mut kernel_space = KERNEL_SPACE.exclusive_access();
- let mid_text: VirtAddr = ((stext as usize + etext as usize) / 2).into();
- let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into();
- let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into();
- assert!(!kernel_space
- .page_table
- .translate(mid_text.floor())
- .unwrap()
- .writable(),);
- assert!(!kernel_space
- .page_table
- .translate(mid_rodata.floor())
- .unwrap()
- .writable(),);
- assert!(!kernel_space
- .page_table
- .translate(mid_data.floor())
- .unwrap()
- .executable(),);
+#[allow(unused)]
+///Check PageTable running correctly
+pub fn remap_test() {
+ let mut kernel_space = KERNEL_SPACE.exclusive_access();
+ let mid_text: VirtAddr = ((stext as usize + etext as usize) / 2).into();
+ let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into();
+ let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into();
+ assert!(!kernel_space
+ .page_table
+ .translate(mid_text.floor())
+ .unwrap()
+ .writable(),);
+ assert!(!kernel_space
+ .page_table
+ .translate(mid_rodata.floor())
+ .unwrap()
+ .writable(),);
+ assert!(!kernel_space
+ .page_table
+ .translate(mid_data.floor())
+ .unwrap()
+ .executable(),);
println!("remap_test passed!");
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -
//! Memory management implementation
-//!
-//! SV39 page-based virtual-memory architecture for RV64 systems, and
-//! everything about memory management, like frame allocator, page table,
-//! map area and memory set, is implemented here.
-//!
-//! Every task or process has a memory_set to control its virtual memory.
-mod address;
-mod frame_allocator;
-mod heap_allocator;
-mod memory_set;
-mod page_table;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+
//! Memory management implementation
+//!
+//! SV39 page-based virtual-memory architecture for RV64 systems, and
+//! everything about memory management, like frame allocator, page table,
+//! map area and memory set, is implemented here.
+//!
+//! Every task or process has a memory_set to control its virtual memory.
+mod address;
+mod frame_allocator;
+mod heap_allocator;
+mod memory_set;
+mod page_table;
-use address::VPNRange;
-pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
-pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker};
-pub use memory_set::remap_test;
-pub use memory_set::{kernel_token, MapPermission, MemorySet, KERNEL_SPACE};
-use page_table::PTEFlags;
-pub use page_table::{
- translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable,
- PageTableEntry, UserBuffer, UserBufferIterator,
+use address::VPNRange;
+pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
+pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker};
+pub use memory_set::remap_test;
+pub use memory_set::{kernel_token, MapPermission, MemorySet, KERNEL_SPACE};
+use page_table::PTEFlags;
+pub use page_table::{
+ translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable,
+ PageTableEntry, UserBuffer, UserBufferIterator,
};
-/// initiate heap allocator, frame allocator and kernel space
-pub fn init() {
- heap_allocator::init_heap();
- frame_allocator::init_frame_allocator();
- KERNEL_SPACE.exclusive_access().activate();
+/// initiate heap allocator, frame allocator and kernel space
+pub fn init() {
+ heap_allocator::init_heap();
+ frame_allocator::init_frame_allocator();
+ KERNEL_SPACE.exclusive_access().activate();
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -
//! Implementation of [`PageTableEntry`] and [`PageTable`].
-use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
-use alloc::string::String;
-use alloc::vec;
-use alloc::vec::Vec;
-use bitflags::*;
+page_table.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+
//! Implementation of [`PageTableEntry`] and [`PageTable`].
+use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
+use alloc::string::String;
+use alloc::vec;
+use alloc::vec::Vec;
+use bitflags::*;
-bitflags! {
- pub struct PTEFlags: u8 {
- const V = 1 << 0;
- const R = 1 << 1;
- const W = 1 << 2;
- const X = 1 << 3;
- const U = 1 << 4;
- const G = 1 << 5;
- const A = 1 << 6;
- const D = 1 << 7;
+bitflags! {
+ pub struct PTEFlags: u8 {
+ const V = 1 << 0;
+ const R = 1 << 1;
+ const W = 1 << 2;
+ const X = 1 << 3;
+ const U = 1 << 4;
+ const G = 1 << 5;
+ const A = 1 << 6;
+ const D = 1 << 7;
}
}
-#[derive(Copy, Clone)]
-#[repr(C)]
-/// page table entry structure
-pub struct PageTableEntry {
- ///PTE
- pub bits: usize,
+#[derive(Copy, Clone)]
+#[repr(C)]
+/// page table entry structure
+pub struct PageTableEntry {
+ ///PTE
+ pub bits: usize,
}
-impl PageTableEntry {
- ///Create a PTE from ppn
- pub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self {
- PageTableEntry {
- bits: ppn.0 << 10 | flags.bits as usize,
+impl PageTableEntry {
+ ///Create a PTE from ppn
+ pub fn new(ppn: PhysPageNum, flags: PTEFlags) -> Self {
+ PageTableEntry {
+ bits: ppn.0 << 10 | flags.bits as usize,
}
}
- ///Return an empty PTE
- pub fn empty() -> Self {
- PageTableEntry { bits: 0 }
+ ///Return an empty PTE
+ pub fn empty() -> Self {
+ PageTableEntry { bits: 0 }
}
- ///Return 44bit ppn
- pub fn ppn(&self) -> PhysPageNum {
- (self.bits >> 10 & ((1usize << 44) - 1)).into()
+ ///Return 44bit ppn
+ pub fn ppn(&self) -> PhysPageNum {
+ (self.bits >> 10 & ((1usize << 44) - 1)).into()
}
- ///Return 10bit flag
- pub fn flags(&self) -> PTEFlags {
- PTEFlags::from_bits(self.bits as u8).unwrap()
+ ///Return 10bit flag
+ pub fn flags(&self) -> PTEFlags {
+ PTEFlags::from_bits(self.bits as u8).unwrap()
}
- ///Check PTE valid
- pub fn is_valid(&self) -> bool {
- (self.flags() & PTEFlags::V) != PTEFlags::empty()
+ ///Check PTE valid
+ pub fn is_valid(&self) -> bool {
+ (self.flags() & PTEFlags::V) != PTEFlags::empty()
}
- ///Check PTE readable
- pub fn readable(&self) -> bool {
- (self.flags() & PTEFlags::R) != PTEFlags::empty()
+ ///Check PTE readable
+ pub fn readable(&self) -> bool {
+ (self.flags() & PTEFlags::R) != PTEFlags::empty()
}
- ///Check PTE writable
- pub fn writable(&self) -> bool {
- (self.flags() & PTEFlags::W) != PTEFlags::empty()
+ ///Check PTE writable
+ pub fn writable(&self) -> bool {
+ (self.flags() & PTEFlags::W) != PTEFlags::empty()
}
- ///Check PTE executable
- pub fn executable(&self) -> bool {
- (self.flags() & PTEFlags::X) != PTEFlags::empty()
+ ///Check PTE executable
+ pub fn executable(&self) -> bool {
+ (self.flags() & PTEFlags::X) != PTEFlags::empty()
}
}
-///Record root ppn and has the same lifetime as 1 and 2 level `PageTableEntry`
-pub struct PageTable {
- root_ppn: PhysPageNum,
- frames: Vec<FrameTracker>,
+///Record root ppn and has the same lifetime as 1 and 2 level `PageTableEntry`
+pub struct PageTable {
+ root_ppn: PhysPageNum,
+ frames: Vec<FrameTracker>,
}
-/// Assume that it won't oom when creating/mapping.
-impl PageTable {
- /// Create an empty `PageTable`
- pub fn new() -> Self {
- let frame = frame_alloc().unwrap();
- PageTable {
- root_ppn: frame.ppn,
- frames: vec![frame],
+/// Assume that it won't oom when creating/mapping.
+impl PageTable {
+ /// Create an empty `PageTable`
+ pub fn new() -> Self {
+ let frame = frame_alloc().unwrap();
+ PageTable {
+ root_ppn: frame.ppn,
+ frames: vec![frame],
}
}
- /// Temporarily used to get arguments from user space.
- pub fn from_token(satp: usize) -> Self {
- Self {
- root_ppn: PhysPageNum::from(satp & ((1usize << 44) - 1)),
- frames: Vec::new(),
+ /// Temporarily used to get arguments from user space.
+ pub fn from_token(satp: usize) -> Self {
+ Self {
+ root_ppn: PhysPageNum::from(satp & ((1usize << 44) - 1)),
+ frames: Vec::new(),
}
}
- /// Find phsical address by virtual address, create a frame if not exist
- fn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
- let idxs = vpn.indexes();
- let mut ppn = self.root_ppn;
- let mut result: Option<&mut PageTableEntry> = None;
- for (i, idx) in idxs.iter().enumerate() {
- let pte = &mut ppn.get_pte_array()[*idx];
- if i == 2 {
- result = Some(pte);
+ /// Find phsical address by virtual address, create a frame if not exist
+ fn find_pte_create(&mut self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
+ let idxs = vpn.indexes();
+ let mut ppn = self.root_ppn;
+ let mut result: Option<&mut PageTableEntry> = None;
+ for (i, idx) in idxs.iter().enumerate() {
+ let pte = &mut ppn.get_pte_array()[*idx];
+ if i == 2 {
+ result = Some(pte);
break;
}
- if !pte.is_valid() {
- let frame = frame_alloc().unwrap();
- *pte = PageTableEntry::new(frame.ppn, PTEFlags::V);
- self.frames.push(frame);
+ if !pte.is_valid() {
+ let frame = frame_alloc().unwrap();
+ *pte = PageTableEntry::new(frame.ppn, PTEFlags::V);
+ self.frames.push(frame);
}
- ppn = pte.ppn();
+ ppn = pte.ppn();
}
- result
+ result
}
- /// Find phsical address by virtual address
- fn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
- let idxs = vpn.indexes();
- let mut ppn = self.root_ppn;
- let mut result: Option<&mut PageTableEntry> = None;
- for (i, idx) in idxs.iter().enumerate() {
- let pte = &mut ppn.get_pte_array()[*idx];
- if i == 2 {
- result = Some(pte);
+ /// Find phsical address by virtual address
+ fn find_pte(&self, vpn: VirtPageNum) -> Option<&mut PageTableEntry> {
+ let idxs = vpn.indexes();
+ let mut ppn = self.root_ppn;
+ let mut result: Option<&mut PageTableEntry> = None;
+ for (i, idx) in idxs.iter().enumerate() {
+ let pte = &mut ppn.get_pte_array()[*idx];
+ if i == 2 {
+ result = Some(pte);
break;
}
- if !pte.is_valid() {
- return None;
+ if !pte.is_valid() {
+ return None;
}
- ppn = pte.ppn();
+ ppn = pte.ppn();
}
- result
+ result
}
- #[allow(unused)]
- /// Create a mapping form `vpn` to `ppn`
- pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
- let pte = self.find_pte_create(vpn).unwrap();
- assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
- *pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
+ #[allow(unused)]
+ /// Create a mapping form `vpn` to `ppn`
+ pub fn map(&mut self, vpn: VirtPageNum, ppn: PhysPageNum, flags: PTEFlags) {
+ let pte = self.find_pte_create(vpn).unwrap();
+ assert!(!pte.is_valid(), "vpn {:?} is mapped before mapping", vpn);
+ *pte = PageTableEntry::new(ppn, flags | PTEFlags::V);
}
- #[allow(unused)]
- /// Delete a mapping form `vpn`
- pub fn unmap(&mut self, vpn: VirtPageNum) {
- let pte = self.find_pte(vpn).unwrap();
- assert!(pte.is_valid(), "vpn {:?} is invalid before unmapping", vpn);
- *pte = PageTableEntry::empty();
+ #[allow(unused)]
+ /// Delete a mapping form `vpn`
+ pub fn unmap(&mut self, vpn: VirtPageNum) {
+ let pte = self.find_pte(vpn).unwrap();
+ assert!(pte.is_valid(), "vpn {:?} is invalid before unmapping", vpn);
+ *pte = PageTableEntry::empty();
}
- /// Translate `VirtPageNum` to `PageTableEntry`
- pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
- self.find_pte(vpn).map(|pte| *pte)
+ /// Translate `VirtPageNum` to `PageTableEntry`
+ pub fn translate(&self, vpn: VirtPageNum) -> Option<PageTableEntry> {
+ self.find_pte(vpn).map(|pte| *pte)
}
- /// Translate `VirtAddr` to `PhysAddr`
- pub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr> {
- self.find_pte(va.clone().floor()).map(|pte| {
- let aligned_pa: PhysAddr = pte.ppn().into();
- let offset = va.page_offset();
- let aligned_pa_usize: usize = aligned_pa.into();
- (aligned_pa_usize + offset).into()
+ /// Translate `VirtAddr` to `PhysAddr`
+ pub fn translate_va(&self, va: VirtAddr) -> Option<PhysAddr> {
+ self.find_pte(va.clone().floor()).map(|pte| {
+ let aligned_pa: PhysAddr = pte.ppn().into();
+ let offset = va.page_offset();
+ let aligned_pa_usize: usize = aligned_pa.into();
+ (aligned_pa_usize + offset).into()
})
}
- /// Get root ppn
- pub fn token(&self) -> usize {
- 8usize << 60 | self.root_ppn.0
- }
+ /// Get root ppn
+ pub fn token(&self) -> usize {
+ 8usize << 60 | self.root_ppn.0
+ }
}
-/// Translate a pointer to a mutable u8 Vec through page table
-pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static mut [u8]> {
- let page_table = PageTable::from_token(token);
- let mut start = ptr as usize;
- let end = start + len;
- let mut v = Vec::new();
- while start < end {
- let start_va = VirtAddr::from(start);
- let mut vpn = start_va.floor();
- let ppn = page_table.translate(vpn).unwrap().ppn();
- vpn.step();
- let mut end_va: VirtAddr = vpn.into();
- end_va = end_va.min(VirtAddr::from(end));
- if end_va.page_offset() == 0 {
- v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..]);
- } else {
- v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
+/// Translate a pointer to a mutable u8 Vec through page table
+pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<&'static mut [u8]> {
+ let page_table = PageTable::from_token(token);
+ let mut start = ptr as usize;
+ let end = start + len;
+ let mut v = Vec::new();
+ while start < end {
+ let start_va = VirtAddr::from(start);
+ let mut vpn = start_va.floor();
+ let ppn = page_table.translate(vpn).unwrap().ppn();
+ vpn.step();
+ let mut end_va: VirtAddr = vpn.into();
+ end_va = end_va.min(VirtAddr::from(end));
+ if end_va.page_offset() == 0 {
+ v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..]);
+ } else {
+ v.push(&mut ppn.get_bytes_array()[start_va.page_offset()..end_va.page_offset()]);
}
- start = end_va.into();
+ start = end_va.into();
}
- v
+ v
}
-/// Translate a pointer to a mutable u8 Vec end with `\0` through page table to a `String`
-pub fn translated_str(token: usize, ptr: *const u8) -> String {
- let page_table = PageTable::from_token(token);
- let mut string = String::new();
- let mut va = ptr as usize;
- loop {
- let ch: u8 = *(page_table
- .translate_va(VirtAddr::from(va))
- .unwrap()
- .get_mut());
- if ch == 0 {
+/// Translate a pointer to a mutable u8 Vec end with `\0` through page table to a `String`
+pub fn translated_str(token: usize, ptr: *const u8) -> String {
+ let page_table = PageTable::from_token(token);
+ let mut string = String::new();
+ let mut va = ptr as usize;
+ loop {
+ let ch: u8 = *(page_table
+ .translate_va(VirtAddr::from(va))
+ .unwrap()
+ .get_mut());
+ if ch == 0 {
break;
}
- string.push(ch as char);
- va += 1;
+ string.push(ch as char);
+ va += 1;
}
- string
+ string
}
-#[allow(unused)]
-///Translate a generic through page table and return a reference
-pub fn translated_ref<T>(token: usize, ptr: *const T) -> &'static T {
- let page_table = PageTable::from_token(token);
- page_table
- .translate_va(VirtAddr::from(ptr as usize))
- .unwrap()
- .get_ref()
+#[allow(unused)]
+///Translate a generic through page table and return a reference
+pub fn translated_ref<T>(token: usize, ptr: *const T) -> &'static T {
+ let page_table = PageTable::from_token(token);
+ page_table
+ .translate_va(VirtAddr::from(ptr as usize))
+ .unwrap()
+ .get_ref()
}
-///Translate a generic through page table and return a mutable reference
-pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T {
- let page_table = PageTable::from_token(token);
- let va = ptr as usize;
- page_table
- .translate_va(VirtAddr::from(va))
- .unwrap()
- .get_mut()
+///Translate a generic through page table and return a mutable reference
+pub fn translated_refmut<T>(token: usize, ptr: *mut T) -> &'static mut T {
+ let page_table = PageTable::from_token(token);
+ let va = ptr as usize;
+ page_table
+ .translate_va(VirtAddr::from(va))
+ .unwrap()
+ .get_mut()
}
-///Array of u8 slice that user communicate with os
-pub struct UserBuffer {
- ///U8 vec
- pub buffers: Vec<&'static mut [u8]>,
+///Array of u8 slice that user communicate with os
+pub struct UserBuffer {
+ ///U8 vec
+ pub buffers: Vec<&'static mut [u8]>,
}
-impl UserBuffer {
- ///Create a `UserBuffer` by parameter
- pub fn new(buffers: Vec<&'static mut [u8]>) -> Self {
- Self { buffers }
+impl UserBuffer {
+ ///Create a `UserBuffer` by parameter
+ pub fn new(buffers: Vec<&'static mut [u8]>) -> Self {
+ Self { buffers }
}
- ///Length of `UserBuffer`
- pub fn len(&self) -> usize {
- let mut total: usize = 0;
- for b in self.buffers.iter() {
- total += b.len();
+ ///Length of `UserBuffer`
+ pub fn len(&self) -> usize {
+ let mut total: usize = 0;
+ for b in self.buffers.iter() {
+ total += b.len();
}
- total
+ total
}
}
-impl IntoIterator for UserBuffer {
- type Item = *mut u8;
- type IntoIter = UserBufferIterator;
- fn into_iter(self) -> Self::IntoIter {
- UserBufferIterator {
- buffers: self.buffers,
- current_buffer: 0,
- current_idx: 0,
+impl IntoIterator for UserBuffer {
+ type Item = *mut u8;
+ type IntoIter = UserBufferIterator;
+ fn into_iter(self) -> Self::IntoIter {
+ UserBufferIterator {
+ buffers: self.buffers,
+ current_buffer: 0,
+ current_idx: 0,
}
}
}
-/// Iterator of `UserBuffer`
-pub struct UserBufferIterator {
- buffers: Vec<&'static mut [u8]>,
- current_buffer: usize,
- current_idx: usize,
+/// Iterator of `UserBuffer`
+pub struct UserBufferIterator {
+ buffers: Vec<&'static mut [u8]>,
+ current_buffer: usize,
+ current_idx: usize,
}
-impl Iterator for UserBufferIterator {
- type Item = *mut u8;
- fn next(&mut self) -> Option<Self::Item> {
- if self.current_buffer >= self.buffers.len() {
- None
- } else {
- let r = &mut self.buffers[self.current_buffer][self.current_idx] as *mut _;
- if self.current_idx + 1 == self.buffers[self.current_buffer].len() {
- self.current_idx = 0;
- self.current_buffer += 1;
- } else {
- self.current_idx += 1;
+impl Iterator for UserBufferIterator {
+ type Item = *mut u8;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.current_buffer >= self.buffers.len() {
+ None
+ } else {
+ let r = &mut self.buffers[self.current_buffer][self.current_idx] as *mut _;
+ if self.current_idx + 1 == self.buffers[self.current_buffer].len() {
+ self.current_idx = 0;
+ self.current_buffer += 1;
+ } else {
+ self.current_idx += 1;
}
- Some(r)
+ Some(r)
}
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -
//! SBI call wrappers
-#![allow(unused)]
+sbi.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
//! SBI call wrappers
+#![allow(unused)]
-use core::arch::asm;
+/// use sbi call to putchar in console (qemu uart handler)
+pub fn console_putchar(c: usize) {
+ #[allow(deprecated)]
+ sbi_rt::legacy::console_putchar(c);
+}
-const SBI_SET_TIMER: usize = 0;
-const SBI_CONSOLE_PUTCHAR: usize = 1;
-const SBI_CONSOLE_GETCHAR: usize = 2;
-const SBI_CLEAR_IPI: usize = 3;
-const SBI_SEND_IPI: usize = 4;
-const SBI_REMOTE_FENCE_I: usize = 5;
-const SBI_REMOTE_SFENCE_VMA: usize = 6;
-const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7;
-const SBI_SHUTDOWN: usize = 8;
-/// general sbi call
-#[inline(always)]
-fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize {
- let mut ret;
- unsafe {
- asm!(
- "li x16, 0",
- "ecall",
- inlateout("x10") arg0 => ret,
- in("x11") arg1,
- in("x12") arg2,
- in("x17") which,
- );
+/// use sbi call to getchar from console (qemu uart handler)
+pub fn console_getchar() -> usize {
+ #[allow(deprecated)]
+ sbi_rt::legacy::console_getchar()
+}
+
+/// use sbi call to set timer
+pub fn set_timer(timer: usize) {
+ sbi_rt::set_timer(timer as _);
+}
+
+/// use sbi call to shutdown the kernel
+pub fn shutdown(failure: bool) -> ! {
+ use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure};
+ if !failure {
+ system_reset(Shutdown, NoReason);
+ } else {
+ system_reset(Shutdown, SystemFailure);
}
- ret
+ unreachable!()
}
-/// use sbi call to set timer
-pub fn set_timer(timer: usize) {
- sbi_call(SBI_SET_TIMER, timer, 0, 0);
-}
-/// use sbi call to putchar in console (qemu uart handler)
-pub fn console_putchar(c: usize) {
- sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0);
-}
-/// use sbi call to getchar from console (qemu uart handler)
-pub fn console_getchar() -> usize {
- sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0)
-}
-/// use sbi call to shutdown the kernel
-pub fn shutdown() -> ! {
- sbi_call(SBI_SHUTDOWN, 0, 0, 0);
- panic!("It should shutdown!");
-}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -
//! Uniprocessor interior mutability primitives
-use core::cell::{RefCell, RefMut};
+up.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+
//! Uniprocessor interior mutability primitives
+use core::cell::{RefCell, RefMut};
+use core::sync::atomic::{AtomicBool, Ordering};
-/// Wrap a static data structure inside it so that we are
-/// able to access it without any `unsafe`.
-///
-/// We should only use it in uniprocessor.
-///
-/// In order to get mutable reference of inner data, call
-/// `exclusive_access`.
-pub struct UPSafeCell<T> {
- /// inner data
- inner: RefCell<T>,
+/// Wrap a static data structure inside it so that we are
+/// able to access it without any `unsafe`.
+///
+/// We should only use it in uniprocessor.
+///
+/// In order to get mutable reference of inner data, call
+/// `exclusive_access`.
+pub struct UPSafeCell<T> {
+ /// inner data
+ inner: RefCell<T>,
}
-unsafe impl<T> Sync for UPSafeCell<T> {}
+unsafe impl<T> Sync for UPSafeCell<T> {}
-impl<T> UPSafeCell<T> {
- /// User is responsible to guarantee that inner struct is only used in
- /// uniprocessor.
- pub unsafe fn new(value: T) -> Self {
- Self {
- inner: RefCell::new(value),
+impl<T> UPSafeCell<T> {
+ /// User is responsible to guarantee that inner struct is only used in
+ /// uniprocessor.
+ pub unsafe fn new(value: T) -> Self {
+ Self {
+ inner: RefCell::new(value),
}
}
- /// Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
- pub fn exclusive_access(&self) -> RefMut<'_, T> {
- self.inner.borrow_mut()
+ /// Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
+ pub fn exclusive_access(&self) -> RefMut<'_, T> {
+ self.inner.borrow_mut()
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -
//! File and filesystem-related syscalls
-use crate::fs::{open_file, OpenFlags};
-use crate::mm::{translated_byte_buffer, translated_str, UserBuffer};
-use crate::task::{current_task, current_user_token};
+fs.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+
//! File and filesystem-related syscalls
+use crate::fs::{open_file, OpenFlags};
+use crate::mm::{translated_byte_buffer, translated_str, UserBuffer};
+use crate::task::{current_task, current_user_token};
-pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
- let token = current_user_token();
- let task = current_task().unwrap();
- let inner = task.inner_exclusive_access();
- if fd >= inner.fd_table.len() {
- return -1;
+pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
+ let token = current_user_token();
+ let task = current_task().unwrap();
+ let inner = task.inner_exclusive_access();
+ if fd >= inner.fd_table.len() {
+ return -1;
}
- if let Some(file) = &inner.fd_table[fd] {
- if !file.writable() {
- return -1;
+ if let Some(file) = &inner.fd_table[fd] {
+ if !file.writable() {
+ return -1;
}
- let file = file.clone();
- // release current task TCB manually to avoid multi-borrow
- drop(inner);
- file.write(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize
- } else {
- -1
- }
+ let file = file.clone();
+ // release current task TCB manually to avoid multi-borrow
+ drop(inner);
+ file.write(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize
+ } else {
+ -1
+ }
}
-pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
- let token = current_user_token();
- let task = current_task().unwrap();
- let inner = task.inner_exclusive_access();
- if fd >= inner.fd_table.len() {
- return -1;
+pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
+ let token = current_user_token();
+ let task = current_task().unwrap();
+ let inner = task.inner_exclusive_access();
+ if fd >= inner.fd_table.len() {
+ return -1;
}
- if let Some(file) = &inner.fd_table[fd] {
- let file = file.clone();
- if !file.readable() {
- return -1;
+ if let Some(file) = &inner.fd_table[fd] {
+ let file = file.clone();
+ if !file.readable() {
+ return -1;
}
- // release current task TCB manually to avoid multi-borrow
- drop(inner);
- file.read(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize
- } else {
- -1
- }
+ // release current task TCB manually to avoid multi-borrow
+ drop(inner);
+ file.read(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize
+ } else {
+ -1
+ }
}
-pub fn sys_open(path: *const u8, flags: u32) -> isize {
- let task = current_task().unwrap();
- let token = current_user_token();
- let path = translated_str(token, path);
- if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) {
- let mut inner = task.inner_exclusive_access();
- let fd = inner.alloc_fd();
- inner.fd_table[fd] = Some(inode);
- fd as isize
- } else {
- -1
- }
+pub fn sys_open(path: *const u8, flags: u32) -> isize {
+ let task = current_task().unwrap();
+ let token = current_user_token();
+ let path = translated_str(token, path);
+ if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) {
+ let mut inner = task.inner_exclusive_access();
+ let fd = inner.alloc_fd();
+ inner.fd_table[fd] = Some(inode);
+ fd as isize
+ } else {
+ -1
+ }
}
-pub fn sys_close(fd: usize) -> isize {
- let task = current_task().unwrap();
- let mut inner = task.inner_exclusive_access();
- if fd >= inner.fd_table.len() {
- return -1;
+pub fn sys_close(fd: usize) -> isize {
+ let task = current_task().unwrap();
+ let mut inner = task.inner_exclusive_access();
+ if fd >= inner.fd_table.len() {
+ return -1;
}
- if inner.fd_table[fd].is_none() {
- return -1;
+ if inner.fd_table[fd].is_none() {
+ return -1;
}
- inner.fd_table[fd].take();
- 0
-}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -
//! Implementation of syscalls
-//!
-//! The single entry point to all system calls, [`syscall()`], is called
-//! whenever userspace wishes to perform a system call using the `ecall`
-//! instruction. In this case, the processor raises an 'Environment call from
-//! U-mode' exception, which is handled as one of the cases in
-//! [`crate::trap::trap_handler`].
-//!
-//! For clarity, each single syscall is implemented as its own function, named
-//! `sys_` then the name of the syscall. You can find functions like this in
-//! submodules, and you should also implement syscalls this way.
-const SYSCALL_OPEN: usize = 56;
-const SYSCALL_CLOSE: usize = 57;
-const SYSCALL_READ: usize = 63;
-const SYSCALL_WRITE: usize = 64;
-const SYSCALL_EXIT: usize = 93;
-const SYSCALL_YIELD: usize = 124;
-const SYSCALL_GET_TIME: usize = 169;
-const SYSCALL_GETPID: usize = 172;
-const SYSCALL_FORK: usize = 220;
-const SYSCALL_EXEC: usize = 221;
-const SYSCALL_WAITPID: usize = 260;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
//! Implementation of syscalls
+//!
+//! The single entry point to all system calls, [`syscall()`], is called
+//! whenever userspace wishes to perform a system call using the `ecall`
+//! instruction. In this case, the processor raises an 'Environment call from
+//! U-mode' exception, which is handled as one of the cases in
+//! [`crate::trap::trap_handler`].
+//!
+//! For clarity, each single syscall is implemented as its own function, named
+//! `sys_` then the name of the syscall. You can find functions like this in
+//! submodules, and you should also implement syscalls this way.
+const SYSCALL_OPEN: usize = 56;
+const SYSCALL_CLOSE: usize = 57;
+const SYSCALL_READ: usize = 63;
+const SYSCALL_WRITE: usize = 64;
+const SYSCALL_EXIT: usize = 93;
+const SYSCALL_YIELD: usize = 124;
+const SYSCALL_GET_TIME: usize = 169;
+const SYSCALL_GETPID: usize = 172;
+const SYSCALL_FORK: usize = 220;
+const SYSCALL_EXEC: usize = 221;
+const SYSCALL_WAITPID: usize = 260;
-mod fs;
-mod process;
+mod fs;
+mod process;
-use fs::*;
-use process::*;
-/// handle syscall exception with `syscall_id` and other arguments
-pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
- match syscall_id {
- SYSCALL_OPEN => sys_open(args[0] as *const u8, args[1] as u32),
- SYSCALL_CLOSE => sys_close(args[0]),
- SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
- SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
- SYSCALL_EXIT => sys_exit(args[0] as i32),
- SYSCALL_YIELD => sys_yield(),
- SYSCALL_GET_TIME => sys_get_time(),
- SYSCALL_GETPID => sys_getpid(),
- SYSCALL_FORK => sys_fork(),
- SYSCALL_EXEC => sys_exec(args[0] as *const u8),
- SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
- _ => panic!("Unsupported syscall_id: {}", syscall_id),
+use fs::*;
+use process::*;
+/// handle syscall exception with `syscall_id` and other arguments
+pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
+ match syscall_id {
+ SYSCALL_OPEN => sys_open(args[0] as *const u8, args[1] as u32),
+ SYSCALL_CLOSE => sys_close(args[0]),
+ SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
+ SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
+ SYSCALL_EXIT => sys_exit(args[0] as i32),
+ SYSCALL_YIELD => sys_yield(),
+ SYSCALL_GET_TIME => sys_get_time(),
+ SYSCALL_GETPID => sys_getpid(),
+ SYSCALL_FORK => sys_fork(),
+ SYSCALL_EXEC => sys_exec(args[0] as *const u8),
+ SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
+ _ => panic!("Unsupported syscall_id: {}", syscall_id),
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -
use crate::fs::{open_file, OpenFlags};
-use crate::mm::{translated_refmut, translated_str};
-use crate::task::{
- add_task, current_task, current_user_token, exit_current_and_run_next,
- suspend_current_and_run_next,
+process.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+
use crate::fs::{open_file, OpenFlags};
+use crate::mm::{translated_refmut, translated_str};
+use crate::task::{
+ add_task, current_task, current_user_token, exit_current_and_run_next,
+ suspend_current_and_run_next,
};
-use crate::timer::get_time_ms;
-use alloc::sync::Arc;
+use crate::timer::get_time_ms;
+use alloc::sync::Arc;
-pub fn sys_exit(exit_code: i32) -> ! {
- exit_current_and_run_next(exit_code);
+pub fn sys_exit(exit_code: i32) -> ! {
+ exit_current_and_run_next(exit_code);
panic!("Unreachable in sys_exit!");
}
-pub fn sys_yield() -> isize {
- suspend_current_and_run_next();
- 0
+pub fn sys_yield() -> isize {
+ suspend_current_and_run_next();
+ 0
+}
+
+pub fn sys_get_time() -> isize {
+ get_time_ms() as isize
}
-pub fn sys_get_time() -> isize {
- get_time_ms() as isize
+pub fn sys_getpid() -> isize {
+ current_task().unwrap().pid.0 as isize
}
-pub fn sys_getpid() -> isize {
- current_task().unwrap().pid.0 as isize
+pub fn sys_fork() -> isize {
+ let current_task = current_task().unwrap();
+ let new_task = current_task.fork();
+ let new_pid = new_task.pid.0;
+ // modify trap context of new_task, because it returns immediately after switching
+ let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
+ // we do not have to move to next instruction since we have done it before
+ // for child process, fork returns 0
+ trap_cx.x[10] = 0;
+ // add new task to scheduler
+ add_task(new_task);
+ new_pid as isize
}
-pub fn sys_fork() -> isize {
- let current_task = current_task().unwrap();
- let new_task = current_task.fork();
- let new_pid = new_task.pid.0;
- // modify trap context of new_task, because it returns immediately after switching
- let trap_cx = new_task.inner_exclusive_access().get_trap_cx();
- // we do not have to move to next instruction since we have done it before
- // for child process, fork returns 0
- trap_cx.x[10] = 0;
- // add new task to scheduler
- add_task(new_task);
- new_pid as isize
+pub fn sys_exec(path: *const u8) -> isize {
+ let token = current_user_token();
+ let path = translated_str(token, path);
+ if let Some(app_inode) = open_file(path.as_str(), OpenFlags::RDONLY) {
+ let all_data = app_inode.read_all();
+ let task = current_task().unwrap();
+ task.exec(all_data.as_slice());
+ 0
+ } else {
+ -1
+ }
}
-pub fn sys_exec(path: *const u8) -> isize {
- let token = current_user_token();
- let path = translated_str(token, path);
- if let Some(app_inode) = open_file(path.as_str(), OpenFlags::RDONLY) {
- let all_data = app_inode.read_all();
- let task = current_task().unwrap();
- task.exec(all_data.as_slice());
- 0
- } else {
- -1
- }
-}
+/// If there is not a child process whose pid is same as given, return -1.
+/// Else if there is a child process but it is still running, return -2.
+pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
+ let task = current_task().unwrap();
+ // find a child process
-/// If there is not a child process whose pid is same as given, return -1.
-/// Else if there is a child process but it is still running, return -2.
-pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
- let task = current_task().unwrap();
- // find a child process
-
- // ---- access current PCB exclusively
- let mut inner = task.inner_exclusive_access();
- if !inner
- .children
- .iter()
- .any(|p| pid == -1 || pid as usize == p.getpid())
+ // ---- access current PCB exclusively
+ let mut inner = task.inner_exclusive_access();
+ if !inner
+ .children
+ .iter()
+ .any(|p| pid == -1 || pid as usize == p.getpid())
{
- return -1;
- // ---- release current PCB
- }
- let pair = inner.children.iter().enumerate().find(|(_, p)| {
- // ++++ temporarily access child PCB exclusively
- p.inner_exclusive_access().is_zombie() && (pid == -1 || pid as usize == p.getpid())
- // ++++ release child PCB
- });
- if let Some((idx, _)) = pair {
- let child = inner.children.remove(idx);
- // confirm that child will be deallocated after being removed from children list
- assert_eq!(Arc::strong_count(&child), 1);
- let found_pid = child.getpid();
- // ++++ temporarily access child PCB exclusively
- let exit_code = child.inner_exclusive_access().exit_code;
- // ++++ release child PCB
- *translated_refmut(inner.memory_set.token(), exit_code_ptr) = exit_code;
- found_pid as isize
- } else {
- -2
- }
- // ---- release current PCB automatically
-}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -
//! Implementation of [`TaskContext`]
-use crate::trap::trap_return;
+context.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+
//! Implementation of [`TaskContext`]
+use crate::trap::trap_return;
-#[repr(C)]
-/// task context structure containing some registers
-pub struct TaskContext {
- /// return address ( e.g. __restore ) of __switch ASM function
- ra: usize,
- /// kernel stack pointer of app
- sp: usize,
- /// s0-11 register, callee saved
- s: [usize; 12],
+#[repr(C)]
+/// task context structure containing some registers
+pub struct TaskContext {
+ /// return address ( e.g. __restore ) of __switch ASM function
+ ra: usize,
+ /// kernel stack pointer of app
+ sp: usize,
+ /// s0-11 register, callee saved
+ s: [usize; 12],
}
-impl TaskContext {
- /// init task context
- pub fn zero_init() -> Self {
- Self {
- ra: 0,
- sp: 0,
- s: [0; 12],
+impl TaskContext {
+ /// init task context
+ pub fn zero_init() -> Self {
+ Self {
+ ra: 0,
+ sp: 0,
+ s: [0; 12],
}
}
- /// set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
- pub fn goto_trap_return(kstack_ptr: usize) -> Self {
- Self {
- ra: trap_return as usize,
- sp: kstack_ptr,
- s: [0; 12],
+ /// set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
+ pub fn goto_trap_return(kstack_ptr: usize) -> Self {
+ Self {
+ ra: trap_return as usize,
+ sp: kstack_ptr,
+ s: [0; 12],
}
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -
//!Implementation of [`TaskManager`]
-use super::TaskControlBlock;
-use crate::sync::UPSafeCell;
-use alloc::collections::VecDeque;
-use alloc::sync::Arc;
-use lazy_static::*;
-///A array of `TaskControlBlock` that is thread-safe
-pub struct TaskManager {
- ready_queue: VecDeque<Arc<TaskControlBlock>>,
+manager.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
//!Implementation of [`TaskManager`]
+use super::TaskControlBlock;
+use crate::sync::UPSafeCell;
+use alloc::collections::VecDeque;
+use alloc::sync::Arc;
+use lazy_static::*;
+///A array of `TaskControlBlock` that is thread-safe
+pub struct TaskManager {
+ ready_queue: VecDeque<Arc<TaskControlBlock>>,
}
-/// A simple FIFO scheduler.
-impl TaskManager {
- ///Creat an empty TaskManager
- pub fn new() -> Self {
- Self {
- ready_queue: VecDeque::new(),
+/// A simple FIFO scheduler.
+impl TaskManager {
+ ///Creat an empty TaskManager
+ pub fn new() -> Self {
+ Self {
+ ready_queue: VecDeque::new(),
}
}
- ///Add a task to `TaskManager`
- pub fn add(&mut self, task: Arc<TaskControlBlock>) {
- self.ready_queue.push_back(task);
+ ///Add a task to `TaskManager`
+ pub fn add(&mut self, task: Arc<TaskControlBlock>) {
+ self.ready_queue.push_back(task);
}
- ///Remove the first task and return it,or `None` if `TaskManager` is empty
- pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
- self.ready_queue.pop_front()
+ ///Remove the first task and return it,or `None` if `TaskManager` is empty
+ pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
+ self.ready_queue.pop_front()
}
}
-lazy_static! {
- pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
- unsafe { UPSafeCell::new(TaskManager::new()) };
+lazy_static! {
+ pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
+ unsafe { UPSafeCell::new(TaskManager::new()) };
}
-///Interface offered to add task
-pub fn add_task(task: Arc<TaskControlBlock>) {
- TASK_MANAGER.exclusive_access().add(task);
+///Interface offered to add task
+pub fn add_task(task: Arc<TaskControlBlock>) {
+ TASK_MANAGER.exclusive_access().add(task);
}
-///Interface offered to pop the first task
-pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
- TASK_MANAGER.exclusive_access().fetch()
+///Interface offered to pop the first task
+pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
+ TASK_MANAGER.exclusive_access().fetch()
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -
//! Task management implementation
-//!
-//! Everything about task management, like starting and switching tasks is
-//! implemented here.
-//!
-//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
-//! all the tasks in the whole operating system.
-//!
-//! A single global instance of [`Processor`] called `PROCESSOR` monitors running
-//! task(s) for each core.
-//!
-//! A single global instance of [`PidAllocator`] called `PID_ALLOCATOR` allocates
-//! pid for user apps.
-//!
-//! Be careful when you see `__switch` ASM function in `switch.S`. Control flow around this function
-//! might not be what you expect.
-mod context;
-mod manager;
-mod pid;
-mod processor;
-mod switch;
-#[allow(clippy::module_inception)]
-#[allow(rustdoc::private_intra_doc_links)]
-mod task;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+
//! Task management implementation
+//!
+//! Everything about task management, like starting and switching tasks is
+//! implemented here.
+//!
+//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
+//! all the tasks in the whole operating system.
+//!
+//! A single global instance of [`Processor`] called `PROCESSOR` monitors running
+//! task(s) for each core.
+//!
+//! A single global instance of [`PidAllocator`] called `PID_ALLOCATOR` allocates
+//! pid for user apps.
+//!
+//! Be careful when you see `__switch` ASM function in `switch.S`. Control flow around this function
+//! might not be what you expect.
+mod context;
+mod manager;
+mod pid;
+mod processor;
+mod switch;
+#[allow(clippy::module_inception)]
+#[allow(rustdoc::private_intra_doc_links)]
+mod task;
-use crate::fs::{open_file, OpenFlags};
-use alloc::sync::Arc;
-pub use context::TaskContext;
-use lazy_static::*;
-pub use manager::{fetch_task, TaskManager};
-use switch::__switch;
-use task::{TaskControlBlock, TaskStatus};
+use crate::fs::{open_file, OpenFlags};
+use crate::sbi::shutdown;
+use alloc::sync::Arc;
+pub use context::TaskContext;
+use lazy_static::*;
+pub use manager::{fetch_task, TaskManager};
+use switch::__switch;
+use task::{TaskControlBlock, TaskStatus};
-pub use manager::add_task;
-pub use pid::{pid_alloc, KernelStack, PidAllocator, PidHandle};
-pub use processor::{
- current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
- Processor,
+pub use manager::add_task;
+pub use pid::{pid_alloc, KernelStack, PidAllocator, PidHandle};
+pub use processor::{
+ current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
+ Processor,
};
-/// Suspend the current 'Running' task and run the next task in task list.
-pub fn suspend_current_and_run_next() {
- // There must be an application running.
- let task = take_current_task().unwrap();
+/// Suspend the current 'Running' task and run the next task in task list.
+pub fn suspend_current_and_run_next() {
+ // There must be an application running.
+ let task = take_current_task().unwrap();
- // ---- access current TCB exclusively
- let mut task_inner = task.inner_exclusive_access();
- let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
- // Change status to Ready
- task_inner.task_status = TaskStatus::Ready;
- drop(task_inner);
- // ---- release current PCB
+ // ---- access current TCB exclusively
+ let mut task_inner = task.inner_exclusive_access();
+ let task_cx_ptr = &mut task_inner.task_cx as *mut TaskContext;
+ // Change status to Ready
+ task_inner.task_status = TaskStatus::Ready;
+ drop(task_inner);
+ // ---- release current PCB
- // push back to ready queue.
- add_task(task);
- // jump to scheduling cycle
- schedule(task_cx_ptr);
+ // push back to ready queue.
+ add_task(task);
+ // jump to scheduling cycle
+ schedule(task_cx_ptr);
}
-/// pid of usertests app in make run TEST=1
-pub const IDLE_PID: usize = 0;
+/// pid of usertests app in make run TEST=1
+pub const IDLE_PID: usize = 0;
-#[cfg(feature = "board_qemu")]
-use crate::board::QEMUExit;
+/// Exit the current 'Running' task and run the next task in task list.
+pub fn exit_current_and_run_next(exit_code: i32) {
+ // take from Processor
+ let task = take_current_task().unwrap();
-/// Exit the current 'Running' task and run the next task in task list.
-pub fn exit_current_and_run_next(exit_code: i32) {
- // take from Processor
- let task = take_current_task().unwrap();
-
- #[cfg(feature = "board_qemu")]
- let pid = task.getpid();
- #[cfg(feature = "board_qemu")]
- if pid == IDLE_PID {
+ let pid = task.getpid();
+ if pid == IDLE_PID {
println!(
"[kernel] Idle process exit with exit_code {} ...",
- exit_code
+ exit_code
);
- if exit_code != 0 {
- //crate::sbi::shutdown(255); //255 == -1 for err hint
- crate::board::QEMU_EXIT_HANDLE.exit_failure();
- } else {
- //crate::sbi::shutdown(0); //0 for success hint
- crate::board::QEMU_EXIT_HANDLE.exit_success();
+ if exit_code != 0 {
+ //crate::sbi::shutdown(255); //255 == -1 for err hint
+ shutdown(true)
+ } else {
+ //crate::sbi::shutdown(0); //0 for success hint
+ shutdown(false)
}
}
- // **** access current TCB exclusively
- let mut inner = task.inner_exclusive_access();
- // Change status to Zombie
- inner.task_status = TaskStatus::Zombie;
- // Record exit code
- inner.exit_code = exit_code;
- // do not move to its parent but under initproc
+ // **** access current TCB exclusively
+ let mut inner = task.inner_exclusive_access();
+ // Change status to Zombie
+ inner.task_status = TaskStatus::Zombie;
+ // Record exit code
+ inner.exit_code = exit_code;
+ // do not move to its parent but under initproc
- // ++++++ access initproc TCB exclusively
- {
- let mut initproc_inner = INITPROC.inner_exclusive_access();
- for child in inner.children.iter() {
- child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
- initproc_inner.children.push(child.clone());
+ // ++++++ access initproc TCB exclusively
+ {
+ let mut initproc_inner = INITPROC.inner_exclusive_access();
+ for child in inner.children.iter() {
+ child.inner_exclusive_access().parent = Some(Arc::downgrade(&INITPROC));
+ initproc_inner.children.push(child.clone());
}
}
- // ++++++ release parent PCB
+ // ++++++ release parent PCB
- inner.children.clear();
- // deallocate user space
- inner.memory_set.recycle_data_pages();
- drop(inner);
- // **** release current PCB
- // drop task manually to maintain rc correctly
- drop(task);
- // we do not have to save task context
- let mut _unused = TaskContext::zero_init();
- schedule(&mut _unused as *mut _);
+ inner.children.clear();
+ // deallocate user space
+ inner.memory_set.recycle_data_pages();
+ drop(inner);
+ // **** release current PCB
+ // drop task manually to maintain rc correctly
+ drop(task);
+ // we do not have to save task context
+ let mut _unused = TaskContext::zero_init();
+ schedule(&mut _unused as *mut _);
}
-lazy_static! {
- ///Globle process that init user shell
- pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new({
- let inode = open_file("initproc", OpenFlags::RDONLY).unwrap();
- let v = inode.read_all();
- TaskControlBlock::new(v.as_slice())
+lazy_static! {
+ ///Globle process that init user shell
+ pub static ref INITPROC: Arc<TaskControlBlock> = Arc::new({
+ let inode = open_file("initproc", OpenFlags::RDONLY).unwrap();
+ let v = inode.read_all();
+ TaskControlBlock::new(v.as_slice())
});
}
-///Add init process to the manager
-pub fn add_initproc() {
- add_task(INITPROC.clone());
+///Add init process to the manager
+pub fn add_initproc() {
+ add_task(INITPROC.clone());
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -
//!Implementation of [`PidAllocator`]
-use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE};
-use crate::mm::{MapPermission, VirtAddr, KERNEL_SPACE};
-use crate::sync::UPSafeCell;
-use alloc::vec::Vec;
-use lazy_static::*;
-///Pid Allocator struct
-pub struct PidAllocator {
- current: usize,
- recycled: Vec<usize>,
+pid.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+
//!Implementation of [`PidAllocator`]
+use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE};
+use crate::mm::{MapPermission, VirtAddr, KERNEL_SPACE};
+use crate::sync::UPSafeCell;
+use alloc::vec::Vec;
+use lazy_static::*;
+///Pid Allocator struct
+pub struct PidAllocator {
+ current: usize,
+ recycled: Vec<usize>,
}
-impl PidAllocator {
- ///Create an empty `PidAllocator`
- pub fn new() -> Self {
- PidAllocator {
- current: 0,
- recycled: Vec::new(),
+impl PidAllocator {
+ ///Create an empty `PidAllocator`
+ pub fn new() -> Self {
+ PidAllocator {
+ current: 0,
+ recycled: Vec::new(),
}
}
- ///Allocate a pid
- pub fn alloc(&mut self) -> PidHandle {
- if let Some(pid) = self.recycled.pop() {
- PidHandle(pid)
- } else {
- self.current += 1;
- PidHandle(self.current - 1)
+ ///Allocate a pid
+ pub fn alloc(&mut self) -> PidHandle {
+ if let Some(pid) = self.recycled.pop() {
+ PidHandle(pid)
+ } else {
+ self.current += 1;
+ PidHandle(self.current - 1)
}
}
- ///Recycle a pid
- pub fn dealloc(&mut self, pid: usize) {
- assert!(pid < self.current);
+ ///Recycle a pid
+ pub fn dealloc(&mut self, pid: usize) {
+ assert!(pid < self.current);
assert!(
- !self.recycled.iter().any(|ppid| *ppid == pid),
+ !self.recycled.iter().any(|ppid| *ppid == pid),
"pid {} has been deallocated!",
- pid
+ pid
);
- self.recycled.push(pid);
+ self.recycled.push(pid);
}
}
-lazy_static! {
- pub static ref PID_ALLOCATOR: UPSafeCell<PidAllocator> =
- unsafe { UPSafeCell::new(PidAllocator::new()) };
+lazy_static! {
+ pub static ref PID_ALLOCATOR: UPSafeCell<PidAllocator> =
+ unsafe { UPSafeCell::new(PidAllocator::new()) };
}
-///Bind pid lifetime to `PidHandle`
-pub struct PidHandle(pub usize);
+///Bind pid lifetime to `PidHandle`
+pub struct PidHandle(pub usize);
-impl Drop for PidHandle {
- fn drop(&mut self) {
- //println!("drop pid {}", self.0);
- PID_ALLOCATOR.exclusive_access().dealloc(self.0);
+impl Drop for PidHandle {
+ fn drop(&mut self) {
+ //println!("drop pid {}", self.0);
+ PID_ALLOCATOR.exclusive_access().dealloc(self.0);
}
}
-///Allocate a pid from PID_ALLOCATOR
-pub fn pid_alloc() -> PidHandle {
- PID_ALLOCATOR.exclusive_access().alloc()
+///Allocate a pid from PID_ALLOCATOR
+pub fn pid_alloc() -> PidHandle {
+ PID_ALLOCATOR.exclusive_access().alloc()
}
-/// Return (bottom, top) of a kernel stack in kernel space.
-pub fn kernel_stack_position(app_id: usize) -> (usize, usize) {
- let top = TRAMPOLINE - app_id * (KERNEL_STACK_SIZE + PAGE_SIZE);
- let bottom = top - KERNEL_STACK_SIZE;
- (bottom, top)
+/// Return (bottom, top) of a kernel stack in kernel space.
+pub fn kernel_stack_position(app_id: usize) -> (usize, usize) {
+ let top = TRAMPOLINE - app_id * (KERNEL_STACK_SIZE + PAGE_SIZE);
+ let bottom = top - KERNEL_STACK_SIZE;
+ (bottom, top)
}
-///Kernelstack for app
-pub struct KernelStack {
- pid: usize,
+///Kernelstack for app
+pub struct KernelStack {
+ pid: usize,
}
-impl KernelStack {
- ///Create a kernelstack from pid
- pub fn new(pid_handle: &PidHandle) -> Self {
- let pid = pid_handle.0;
- let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(pid);
- KERNEL_SPACE.exclusive_access().insert_framed_area(
- kernel_stack_bottom.into(),
- kernel_stack_top.into(),
- MapPermission::R | MapPermission::W,
+impl KernelStack {
+ ///Create a kernelstack from pid
+ pub fn new(pid_handle: &PidHandle) -> Self {
+ let pid = pid_handle.0;
+ let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(pid);
+ KERNEL_SPACE.exclusive_access().insert_framed_area(
+ kernel_stack_bottom.into(),
+ kernel_stack_top.into(),
+ MapPermission::R | MapPermission::W,
);
- KernelStack { pid: pid_handle.0 }
+ KernelStack { pid: pid_handle.0 }
}
- #[allow(unused)]
- ///Push a value on top of kernelstack
- pub fn push_on_top<T>(&self, value: T) -> *mut T
- where
- T: Sized,
+ #[allow(unused)]
+ ///Push a value on top of kernelstack
+ pub fn push_on_top<T>(&self, value: T) -> *mut T
+ where
+ T: Sized,
{
- let kernel_stack_top = self.get_top();
- let ptr_mut = (kernel_stack_top - core::mem::size_of::<T>()) as *mut T;
- unsafe {
- *ptr_mut = value;
+ let kernel_stack_top = self.get_top();
+ let ptr_mut = (kernel_stack_top - core::mem::size_of::<T>()) as *mut T;
+ unsafe {
+ *ptr_mut = value;
}
- ptr_mut
+ ptr_mut
}
- ///Get the value on the top of kernelstack
- pub fn get_top(&self) -> usize {
- let (_, kernel_stack_top) = kernel_stack_position(self.pid);
- kernel_stack_top
+ ///Get the value on the top of kernelstack
+ pub fn get_top(&self) -> usize {
+ let (_, kernel_stack_top) = kernel_stack_position(self.pid);
+ kernel_stack_top
}
}
-impl Drop for KernelStack {
- fn drop(&mut self) {
- let (kernel_stack_bottom, _) = kernel_stack_position(self.pid);
- let kernel_stack_bottom_va: VirtAddr = kernel_stack_bottom.into();
- KERNEL_SPACE
- .exclusive_access()
- .remove_area_with_start_vpn(kernel_stack_bottom_va.into());
+impl Drop for KernelStack {
+ fn drop(&mut self) {
+ let (kernel_stack_bottom, _) = kernel_stack_position(self.pid);
+ let kernel_stack_bottom_va: VirtAddr = kernel_stack_bottom.into();
+ KERNEL_SPACE
+ .exclusive_access()
+ .remove_area_with_start_vpn(kernel_stack_bottom_va.into());
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -
//!Implementation of [`Processor`] and Intersection of control flow
-use super::__switch;
-use super::{fetch_task, TaskStatus};
-use super::{TaskContext, TaskControlBlock};
-use crate::sync::UPSafeCell;
-use crate::trap::TrapContext;
-use alloc::sync::Arc;
-use lazy_static::*;
-///Processor management structure
-pub struct Processor {
- ///The task currently executing on the current processor
- current: Option<Arc<TaskControlBlock>>,
- ///The basic control flow of each core, helping to select and switch process
- idle_task_cx: TaskContext,
+processor.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+
//!Implementation of [`Processor`] and Intersection of control flow
+use super::__switch;
+use super::{fetch_task, TaskStatus};
+use super::{TaskContext, TaskControlBlock};
+use crate::sync::UPSafeCell;
+use crate::trap::TrapContext;
+use alloc::sync::Arc;
+use lazy_static::*;
+///Processor management structure
+pub struct Processor {
+ ///The task currently executing on the current processor
+ current: Option<Arc<TaskControlBlock>>,
+ ///The basic control flow of each core, helping to select and switch process
+ idle_task_cx: TaskContext,
}
-impl Processor {
- ///Create an empty Processor
- pub fn new() -> Self {
- Self {
- current: None,
- idle_task_cx: TaskContext::zero_init(),
+impl Processor {
+ ///Create an empty Processor
+ pub fn new() -> Self {
+ Self {
+ current: None,
+ idle_task_cx: TaskContext::zero_init(),
}
}
- ///Get mutable reference to `idle_task_cx`
- fn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext {
- &mut self.idle_task_cx as *mut _
+ ///Get mutable reference to `idle_task_cx`
+ fn get_idle_task_cx_ptr(&mut self) -> *mut TaskContext {
+ &mut self.idle_task_cx as *mut _
+ }
+ ///Get current task in moving semanteme
+ pub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>> {
+ self.current.take()
}
- ///Get current task in moving semanteme
- pub fn take_current(&mut self) -> Option<Arc<TaskControlBlock>> {
- self.current.take()
- }
- ///Get current task in cloning semanteme
- pub fn current(&self) -> Option<Arc<TaskControlBlock>> {
- self.current.as_ref().map(Arc::clone)
+ ///Get current task in cloning semanteme
+ pub fn current(&self) -> Option<Arc<TaskControlBlock>> {
+ self.current.as_ref().map(Arc::clone)
}
}
-lazy_static! {
- pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe { UPSafeCell::new(Processor::new()) };
+lazy_static! {
+ pub static ref PROCESSOR: UPSafeCell<Processor> = unsafe { UPSafeCell::new(Processor::new()) };
}
-///The main part of process execution and scheduling
-///Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`
-pub fn run_tasks() {
- loop {
- let mut processor = PROCESSOR.exclusive_access();
- if let Some(task) = fetch_task() {
- let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
- // access coming task TCB exclusively
- let mut task_inner = task.inner_exclusive_access();
- let next_task_cx_ptr = &task_inner.task_cx as *const TaskContext;
- task_inner.task_status = TaskStatus::Running;
- drop(task_inner);
- // release coming task TCB manually
- processor.current = Some(task);
- // release processor manually
- drop(processor);
- unsafe {
- __switch(idle_task_cx_ptr, next_task_cx_ptr);
+///The main part of process execution and scheduling
+///Loop `fetch_task` to get the process that needs to run, and switch the process through `__switch`
+pub fn run_tasks() {
+ loop {
+ let mut processor = PROCESSOR.exclusive_access();
+ if let Some(task) = fetch_task() {
+ let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
+ // access coming task TCB exclusively
+ let mut task_inner = task.inner_exclusive_access();
+ let next_task_cx_ptr = &task_inner.task_cx as *const TaskContext;
+ task_inner.task_status = TaskStatus::Running;
+ drop(task_inner);
+ // release coming task TCB manually
+ processor.current = Some(task);
+ // release processor manually
+ drop(processor);
+ unsafe {
+ __switch(idle_task_cx_ptr, next_task_cx_ptr);
}
}
}
}
-///Take the current task,leaving a None in its place
-pub fn take_current_task() -> Option<Arc<TaskControlBlock>> {
- PROCESSOR.exclusive_access().take_current()
+///Take the current task,leaving a None in its place
+pub fn take_current_task() -> Option<Arc<TaskControlBlock>> {
+ PROCESSOR.exclusive_access().take_current()
}
-///Get running task
-pub fn current_task() -> Option<Arc<TaskControlBlock>> {
- PROCESSOR.exclusive_access().current()
+///Get running task
+pub fn current_task() -> Option<Arc<TaskControlBlock>> {
+ PROCESSOR.exclusive_access().current()
}
-///Get token of the address space of current task
-pub fn current_user_token() -> usize {
- let task = current_task().unwrap();
- let token = task.inner_exclusive_access().get_user_token();
- token
+///Get token of the address space of current task
+pub fn current_user_token() -> usize {
+ let task = current_task().unwrap();
+ let token = task.inner_exclusive_access().get_user_token();
+ token
}
-///Get the mutable reference to trap context of current task
-pub fn current_trap_cx() -> &'static mut TrapContext {
- current_task()
- .unwrap()
- .inner_exclusive_access()
- .get_trap_cx()
+///Get the mutable reference to trap context of current task
+pub fn current_trap_cx() -> &'static mut TrapContext {
+ current_task()
+ .unwrap()
+ .inner_exclusive_access()
+ .get_trap_cx()
}
-///Return to idle control flow for new scheduling
-pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
- let mut processor = PROCESSOR.exclusive_access();
- let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
- drop(processor);
- unsafe {
- __switch(switched_task_cx_ptr, idle_task_cx_ptr);
+///Return to idle control flow for new scheduling
+pub fn schedule(switched_task_cx_ptr: *mut TaskContext) {
+ let mut processor = PROCESSOR.exclusive_access();
+ let idle_task_cx_ptr = processor.get_idle_task_cx_ptr();
+ drop(processor);
+ unsafe {
+ __switch(switched_task_cx_ptr, idle_task_cx_ptr);
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -
//!Wrap `switch.S` as a function
-use super::TaskContext;
-use core::arch::global_asm;
+switch.rs - source //!Wrap `switch.S` as a function
+use super::TaskContext;
+use core::arch::global_asm;
global_asm!(include_str!("switch.S"));
-extern "C" {
- pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext);
+extern "C" {
+ pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext);
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -
//!Implementation of [`TaskControlBlock`]
-use super::TaskContext;
-use super::{pid_alloc, KernelStack, PidHandle};
-use crate::config::TRAP_CONTEXT;
-use crate::fs::{File, Stdin, Stdout};
-use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE};
-use crate::sync::UPSafeCell;
-use crate::trap::{trap_handler, TrapContext};
-use alloc::sync::{Arc, Weak};
-use alloc::vec;
-use alloc::vec::Vec;
-use core::cell::RefMut;
+task.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+
//!Implementation of [`TaskControlBlock`]
+use super::TaskContext;
+use super::{pid_alloc, KernelStack, PidHandle};
+use crate::config::TRAP_CONTEXT;
+use crate::fs::{File, Stdin, Stdout};
+use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE};
+use crate::sync::UPSafeCell;
+use crate::trap::{trap_handler, TrapContext};
+use alloc::sync::{Arc, Weak};
+use alloc::vec;
+use alloc::vec::Vec;
+use core::cell::RefMut;
-pub struct TaskControlBlock {
- // immutable
- pub pid: PidHandle,
- pub kernel_stack: KernelStack,
- // mutable
- inner: UPSafeCell<TaskControlBlockInner>,
+pub struct TaskControlBlock {
+ // immutable
+ pub pid: PidHandle,
+ pub kernel_stack: KernelStack,
+ // mutable
+ inner: UPSafeCell<TaskControlBlockInner>,
}
-pub struct TaskControlBlockInner {
- pub trap_cx_ppn: PhysPageNum,
- pub base_size: usize,
- pub task_cx: TaskContext,
- pub task_status: TaskStatus,
- pub memory_set: MemorySet,
- pub parent: Option<Weak<TaskControlBlock>>,
- pub children: Vec<Arc<TaskControlBlock>>,
- pub exit_code: i32,
- pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
+pub struct TaskControlBlockInner {
+ pub trap_cx_ppn: PhysPageNum,
+ pub base_size: usize,
+ pub task_cx: TaskContext,
+ pub task_status: TaskStatus,
+ pub memory_set: MemorySet,
+ pub parent: Option<Weak<TaskControlBlock>>,
+ pub children: Vec<Arc<TaskControlBlock>>,
+ pub exit_code: i32,
+ pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
}
-impl TaskControlBlockInner {
- pub fn get_trap_cx(&self) -> &'static mut TrapContext {
- self.trap_cx_ppn.get_mut()
+impl TaskControlBlockInner {
+ pub fn get_trap_cx(&self) -> &'static mut TrapContext {
+ self.trap_cx_ppn.get_mut()
}
- pub fn get_user_token(&self) -> usize {
- self.memory_set.token()
+ pub fn get_user_token(&self) -> usize {
+ self.memory_set.token()
}
- fn get_status(&self) -> TaskStatus {
- self.task_status
+ fn get_status(&self) -> TaskStatus {
+ self.task_status
}
- pub fn is_zombie(&self) -> bool {
- self.get_status() == TaskStatus::Zombie
+ pub fn is_zombie(&self) -> bool {
+ self.get_status() == TaskStatus::Zombie
}
- pub fn alloc_fd(&mut self) -> usize {
- if let Some(fd) = (0..self.fd_table.len()).find(|fd| self.fd_table[*fd].is_none()) {
- fd
- } else {
- self.fd_table.push(None);
- self.fd_table.len() - 1
- }
+ pub fn alloc_fd(&mut self) -> usize {
+ if let Some(fd) = (0..self.fd_table.len()).find(|fd| self.fd_table[*fd].is_none()) {
+ fd
+ } else {
+ self.fd_table.push(None);
+ self.fd_table.len() - 1
+ }
}
}
-impl TaskControlBlock {
- pub fn inner_exclusive_access(&self) -> RefMut<'_, TaskControlBlockInner> {
- self.inner.exclusive_access()
+impl TaskControlBlock {
+ pub fn inner_exclusive_access(&self) -> RefMut<'_, TaskControlBlockInner> {
+ self.inner.exclusive_access()
}
- pub fn new(elf_data: &[u8]) -> Self {
- // memory_set with elf program headers/trampoline/trap context/user stack
- let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
- let trap_cx_ppn = memory_set
- .translate(VirtAddr::from(TRAP_CONTEXT).into())
- .unwrap()
- .ppn();
- // alloc a pid and a kernel stack in kernel space
- let pid_handle = pid_alloc();
- let kernel_stack = KernelStack::new(&pid_handle);
- let kernel_stack_top = kernel_stack.get_top();
- let task_control_block = Self {
- pid: pid_handle,
- kernel_stack,
- inner: unsafe {
- UPSafeCell::new(TaskControlBlockInner {
- trap_cx_ppn,
- base_size: user_sp,
- task_cx: TaskContext::goto_trap_return(kernel_stack_top),
- task_status: TaskStatus::Ready,
- memory_set,
- parent: None,
- children: Vec::new(),
- exit_code: 0,
- fd_table: vec![
- // 0 -> stdin
- Some(Arc::new(Stdin)),
- // 1 -> stdout
- Some(Arc::new(Stdout)),
- // 2 -> stderr
- Some(Arc::new(Stdout)),
+ pub fn new(elf_data: &[u8]) -> Self {
+ // memory_set with elf program headers/trampoline/trap context/user stack
+ let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
+ let trap_cx_ppn = memory_set
+ .translate(VirtAddr::from(TRAP_CONTEXT).into())
+ .unwrap()
+ .ppn();
+ // alloc a pid and a kernel stack in kernel space
+ let pid_handle = pid_alloc();
+ let kernel_stack = KernelStack::new(&pid_handle);
+ let kernel_stack_top = kernel_stack.get_top();
+ let task_control_block = Self {
+ pid: pid_handle,
+ kernel_stack,
+ inner: unsafe {
+ UPSafeCell::new(TaskControlBlockInner {
+ trap_cx_ppn,
+ base_size: user_sp,
+ task_cx: TaskContext::goto_trap_return(kernel_stack_top),
+ task_status: TaskStatus::Ready,
+ memory_set,
+ parent: None,
+ children: Vec::new(),
+ exit_code: 0,
+ fd_table: vec![
+ // 0 -> stdin
+ Some(Arc::new(Stdin)),
+ // 1 -> stdout
+ Some(Arc::new(Stdout)),
+ // 2 -> stderr
+ Some(Arc::new(Stdout)),
],
})
},
};
- // prepare TrapContext in user space
- let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
- *trap_cx = TrapContext::app_init_context(
- entry_point,
- user_sp,
- KERNEL_SPACE.exclusive_access().token(),
- kernel_stack_top,
- trap_handler as usize,
+ // prepare TrapContext in user space
+ let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
+ *trap_cx = TrapContext::app_init_context(
+ entry_point,
+ user_sp,
+ KERNEL_SPACE.exclusive_access().token(),
+ kernel_stack_top,
+ trap_handler as usize,
);
- task_control_block
+ task_control_block
}
- pub fn exec(&self, elf_data: &[u8]) {
- // memory_set with elf program headers/trampoline/trap context/user stack
- let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
- let trap_cx_ppn = memory_set
- .translate(VirtAddr::from(TRAP_CONTEXT).into())
- .unwrap()
- .ppn();
+ pub fn exec(&self, elf_data: &[u8]) {
+ // memory_set with elf program headers/trampoline/trap context/user stack
+ let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
+ let trap_cx_ppn = memory_set
+ .translate(VirtAddr::from(TRAP_CONTEXT).into())
+ .unwrap()
+ .ppn();
- // **** access current TCB exclusively
- let mut inner = self.inner_exclusive_access();
- // substitute memory_set
- inner.memory_set = memory_set;
- // update trap_cx ppn
- inner.trap_cx_ppn = trap_cx_ppn;
- // initialize trap_cx
- let trap_cx = TrapContext::app_init_context(
- entry_point,
- user_sp,
- KERNEL_SPACE.exclusive_access().token(),
- self.kernel_stack.get_top(),
- trap_handler as usize,
+ // **** access current TCB exclusively
+ let mut inner = self.inner_exclusive_access();
+ // substitute memory_set
+ inner.memory_set = memory_set;
+ // update trap_cx ppn
+ inner.trap_cx_ppn = trap_cx_ppn;
+ // initialize trap_cx
+ let trap_cx = TrapContext::app_init_context(
+ entry_point,
+ user_sp,
+ KERNEL_SPACE.exclusive_access().token(),
+ self.kernel_stack.get_top(),
+ trap_handler as usize,
);
- *inner.get_trap_cx() = trap_cx;
- // **** release current PCB
- }
- pub fn fork(self: &Arc<TaskControlBlock>) -> Arc<TaskControlBlock> {
- // ---- hold parent PCB lock
- let mut parent_inner = self.inner_exclusive_access();
- // copy user space(include trap context)
- let memory_set = MemorySet::from_existed_user(&parent_inner.memory_set);
- let trap_cx_ppn = memory_set
- .translate(VirtAddr::from(TRAP_CONTEXT).into())
- .unwrap()
- .ppn();
- // alloc a pid and a kernel stack in kernel space
- let pid_handle = pid_alloc();
- let kernel_stack = KernelStack::new(&pid_handle);
- let kernel_stack_top = kernel_stack.get_top();
- // copy fd table
- let mut new_fd_table: Vec<Option<Arc<dyn File + Send + Sync>>> = Vec::new();
- for fd in parent_inner.fd_table.iter() {
- if let Some(file) = fd {
- new_fd_table.push(Some(file.clone()));
- } else {
- new_fd_table.push(None);
+ *inner.get_trap_cx() = trap_cx;
+ // **** release current PCB
+ }
+ pub fn fork(self: &Arc<TaskControlBlock>) -> Arc<TaskControlBlock> {
+ // ---- hold parent PCB lock
+ let mut parent_inner = self.inner_exclusive_access();
+ // copy user space(include trap context)
+ let memory_set = MemorySet::from_existed_user(&parent_inner.memory_set);
+ let trap_cx_ppn = memory_set
+ .translate(VirtAddr::from(TRAP_CONTEXT).into())
+ .unwrap()
+ .ppn();
+ // alloc a pid and a kernel stack in kernel space
+ let pid_handle = pid_alloc();
+ let kernel_stack = KernelStack::new(&pid_handle);
+ let kernel_stack_top = kernel_stack.get_top();
+ // copy fd table
+ let mut new_fd_table: Vec<Option<Arc<dyn File + Send + Sync>>> = Vec::new();
+ for fd in parent_inner.fd_table.iter() {
+ if let Some(file) = fd {
+ new_fd_table.push(Some(file.clone()));
+ } else {
+ new_fd_table.push(None);
}
}
- let task_control_block = Arc::new(TaskControlBlock {
- pid: pid_handle,
- kernel_stack,
- inner: unsafe {
- UPSafeCell::new(TaskControlBlockInner {
- trap_cx_ppn,
- base_size: parent_inner.base_size,
- task_cx: TaskContext::goto_trap_return(kernel_stack_top),
- task_status: TaskStatus::Ready,
- memory_set,
- parent: Some(Arc::downgrade(self)),
- children: Vec::new(),
- exit_code: 0,
- fd_table: new_fd_table,
+ let task_control_block = Arc::new(TaskControlBlock {
+ pid: pid_handle,
+ kernel_stack,
+ inner: unsafe {
+ UPSafeCell::new(TaskControlBlockInner {
+ trap_cx_ppn,
+ base_size: parent_inner.base_size,
+ task_cx: TaskContext::goto_trap_return(kernel_stack_top),
+ task_status: TaskStatus::Ready,
+ memory_set,
+ parent: Some(Arc::downgrade(self)),
+ children: Vec::new(),
+ exit_code: 0,
+ fd_table: new_fd_table,
})
},
});
- // add child
- parent_inner.children.push(task_control_block.clone());
- // modify kernel_sp in trap_cx
- // **** access child PCB exclusively
- let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
- trap_cx.kernel_sp = kernel_stack_top;
- // return
- task_control_block
- // **** release child PCB
- // ---- release parent PCB
- }
- pub fn getpid(&self) -> usize {
- self.pid.0
- }
+ // add child
+ parent_inner.children.push(task_control_block.clone());
+ // modify kernel_sp in trap_cx
+ // **** access child PCB exclusively
+ let trap_cx = task_control_block.inner_exclusive_access().get_trap_cx();
+ trap_cx.kernel_sp = kernel_stack_top;
+ // return
+ task_control_block
+ // **** release child PCB
+ // ---- release parent PCB
+ }
+ pub fn getpid(&self) -> usize {
+ self.pid.0
+ }
}
-#[derive(Copy, Clone, PartialEq)]
-pub enum TaskStatus {
- Ready,
- Running,
- Zombie,
+#[derive(Copy, Clone, PartialEq)]
+pub enum TaskStatus {
+ Ready,
+ Running,
+ Zombie,
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -
//! RISC-V timer-related functionality
+timer.rs - source //! RISC-V timer-related functionality
-use crate::config::CLOCK_FREQ;
-use crate::sbi::set_timer;
-use riscv::register::time;
+use crate::config::CLOCK_FREQ;
+use crate::sbi::set_timer;
+use riscv::register::time;
-const TICKS_PER_SEC: usize = 100;
-const MSEC_PER_SEC: usize = 1000;
-///get current time
-pub fn get_time() -> usize {
- time::read()
+const TICKS_PER_SEC: usize = 100;
+const MSEC_PER_SEC: usize = 1000;
+///get current time
+pub fn get_time() -> usize {
+ time::read()
}
-/// get current time in microseconds
-pub fn get_time_ms() -> usize {
- time::read() / (CLOCK_FREQ / MSEC_PER_SEC)
+/// get current time in microseconds
+pub fn get_time_ms() -> usize {
+ time::read() / (CLOCK_FREQ / MSEC_PER_SEC)
}
-/// set the next timer interrupt
-pub fn set_next_trigger() {
- set_timer(get_time() + CLOCK_FREQ / TICKS_PER_SEC);
+/// set the next timer interrupt
+pub fn set_next_trigger() {
+ set_timer(get_time() + CLOCK_FREQ / TICKS_PER_SEC);
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -
//! Implementation of [`TrapContext`]
-use riscv::register::sstatus::{self, Sstatus, SPP};
+context.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
//! Implementation of [`TrapContext`]
+use riscv::register::sstatus::{self, Sstatus, SPP};
-#[repr(C)]
-#[derive(Debug)]
-///trap context structure containing sstatus, sepc and registers
-pub struct TrapContext {
- /// general regs[0..31]
- pub x: [usize; 32],
- /// CSR sstatus
- pub sstatus: Sstatus,
- /// CSR sepc
- pub sepc: usize,
- /// Addr of Page Table
- pub kernel_satp: usize,
- /// kernel stack
- pub kernel_sp: usize,
- /// Addr of trap_handler function
- pub trap_handler: usize,
+#[repr(C)]
+#[derive(Debug)]
+///trap context structure containing sstatus, sepc and registers
+pub struct TrapContext {
+ /// general regs[0..31]
+ pub x: [usize; 32],
+ /// CSR sstatus
+ pub sstatus: Sstatus,
+ /// CSR sepc
+ pub sepc: usize,
+ /// Addr of Page Table
+ pub kernel_satp: usize,
+ /// kernel stack
+ pub kernel_sp: usize,
+ /// Addr of trap_handler function
+ pub trap_handler: usize,
}
-impl TrapContext {
- ///set stack pointer to x_2 reg (sp)
- pub fn set_sp(&mut self, sp: usize) {
- self.x[2] = sp;
+impl TrapContext {
+ ///set stack pointer to x_2 reg (sp)
+ pub fn set_sp(&mut self, sp: usize) {
+ self.x[2] = sp;
}
- ///init app context
- pub fn app_init_context(
- entry: usize,
- sp: usize,
- kernel_satp: usize,
- kernel_sp: usize,
- trap_handler: usize,
- ) -> Self {
- let mut sstatus = sstatus::read();
- // set CPU privilege to User after trapping back
- sstatus.set_spp(SPP::User);
- let mut cx = Self {
- x: [0; 32],
- sstatus,
- sepc: entry,
- kernel_satp,
- kernel_sp,
- trap_handler,
+ ///init app context
+ pub fn app_init_context(
+ entry: usize,
+ sp: usize,
+ kernel_satp: usize,
+ kernel_sp: usize,
+ trap_handler: usize,
+ ) -> Self {
+ let mut sstatus = sstatus::read();
+ // set CPU privilege to User after trapping back
+ sstatus.set_spp(SPP::User);
+ let mut cx = Self {
+ x: [0; 32],
+ sstatus,
+ sepc: entry,
+ kernel_satp,
+ kernel_sp,
+ trap_handler,
};
- cx.set_sp(sp);
- cx
+ cx.set_sp(sp);
+ cx
}
}
-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -
//! Trap handling functionality
-//!
-//! For rCore, we have a single trap entry point, namely `__alltraps`. At
-//! initialization in [`init()`], we set the `stvec` CSR to point to it.
-//!
-//! All traps go through `__alltraps`, which is defined in `trap.S`. The
-//! assembly language code does just enough work restore the kernel space
-//! context, ensuring that Rust code safely runs, and transfers control to
-//! [`trap_handler()`].
-//!
-//! It then calls different functionality based on what exactly the exception
-//! was. For example, timer interrupts trigger task preemption, and syscalls go
-//! to [`syscall()`].
-mod context;
+mod.rs - source 1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+
//! Trap handling functionality
+//!
+//! For rCore, we have a single trap entry point, namely `__alltraps`. At
+//! initialization in [`init()`], we set the `stvec` CSR to point to it.
+//!
+//! All traps go through `__alltraps`, which is defined in `trap.S`. The
+//! assembly language code does just enough work restore the kernel space
+//! context, ensuring that Rust code safely runs, and transfers control to
+//! [`trap_handler()`].
+//!
+//! It then calls different functionality based on what exactly the exception
+//! was. For example, timer interrupts trigger task preemption, and syscalls go
+//! to [`syscall()`].
+mod context;
-use crate::config::{TRAMPOLINE, TRAP_CONTEXT};
-use crate::syscall::syscall;
-use crate::task::{
- current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next,
+use crate::config::{TRAMPOLINE, TRAP_CONTEXT};
+use crate::syscall::syscall;
+use crate::task::{
+ current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next,
};
-use crate::timer::set_next_trigger;
-use core::arch::{asm, global_asm};
-use riscv::register::{
- mtvec::TrapMode,
- scause::{self, Exception, Interrupt, Trap},
- sie, stval, stvec,
+use crate::timer::set_next_trigger;
+use core::arch::{asm, global_asm};
+use riscv::register::{
+ mtvec::TrapMode,
+ scause::{self, Exception, Interrupt, Trap},
+ sie, stval, stvec,
};
global_asm!(include_str!("trap.S"));
-/// initialize CSR `stvec` as the entry of `__alltraps`
-pub fn init() {
- set_kernel_trap_entry();
+/// initialize CSR `stvec` as the entry of `__alltraps`
+pub fn init() {
+ set_kernel_trap_entry();
}
-fn set_kernel_trap_entry() {
- unsafe {
- stvec::write(trap_from_kernel as usize, TrapMode::Direct);
+fn set_kernel_trap_entry() {
+ unsafe {
+ stvec::write(trap_from_kernel as usize, TrapMode::Direct);
}
}
-fn set_user_trap_entry() {
- unsafe {
- stvec::write(TRAMPOLINE as usize, TrapMode::Direct);
+fn set_user_trap_entry() {
+ unsafe {
+ stvec::write(TRAMPOLINE as usize, TrapMode::Direct);
}
}
-/// enable timer interrupt in sie CSR
-pub fn enable_timer_interrupt() {
- unsafe {
- sie::set_stimer();
+/// enable timer interrupt in sie CSR
+pub fn enable_timer_interrupt() {
+ unsafe {
+ sie::set_stimer();
}
}
-#[no_mangle]
-/// handle an interrupt, exception, or system call from user space
-pub fn trap_handler() -> ! {
- set_kernel_trap_entry();
- let scause = scause::read();
- let stval = stval::read();
- match scause.cause() {
- Trap::Exception(Exception::UserEnvCall) => {
- // jump to next instruction anyway
- let mut cx = current_trap_cx();
- cx.sepc += 4;
- // get system call return value
- let result = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]);
- // cx is changed during sys_exec, so we have to call it again
- cx = current_trap_cx();
- cx.x[10] = result as usize;
+#[no_mangle]
+/// handle an interrupt, exception, or system call from user space
+pub fn trap_handler() -> ! {
+ set_kernel_trap_entry();
+ let scause = scause::read();
+ let stval = stval::read();
+ match scause.cause() {
+ Trap::Exception(Exception::UserEnvCall) => {
+ // jump to next instruction anyway
+ let mut cx = current_trap_cx();
+ cx.sepc += 4;
+ // get system call return value
+ let result = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]);
+ // cx is changed during sys_exec, so we have to call it again
+ cx = current_trap_cx();
+ cx.x[10] = result as usize;
}
- Trap::Exception(Exception::StoreFault)
- | Trap::Exception(Exception::StorePageFault)
- | Trap::Exception(Exception::InstructionFault)
- | Trap::Exception(Exception::InstructionPageFault)
- | Trap::Exception(Exception::LoadFault)
- | Trap::Exception(Exception::LoadPageFault) => {
+ Trap::Exception(Exception::StoreFault)
+ | Trap::Exception(Exception::StorePageFault)
+ | Trap::Exception(Exception::InstructionFault)
+ | Trap::Exception(Exception::InstructionPageFault)
+ | Trap::Exception(Exception::LoadFault)
+ | Trap::Exception(Exception::LoadPageFault) => {
println!(
"[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.",
- scause.cause(),
- stval,
- current_trap_cx().sepc,
+ scause.cause(),
+ stval,
+ current_trap_cx().sepc,
);
- // page fault exit code
- exit_current_and_run_next(-2);
+ // page fault exit code
+ exit_current_and_run_next(-2);
}
- Trap::Exception(Exception::IllegalInstruction) => {
+ Trap::Exception(Exception::IllegalInstruction) => {
println!("[kernel] IllegalInstruction in application, kernel killed it.");
- // illegal instruction exit code
- exit_current_and_run_next(-3);
+ // illegal instruction exit code
+ exit_current_and_run_next(-3);
}
- Trap::Interrupt(Interrupt::SupervisorTimer) => {
- set_next_trigger();
- suspend_current_and_run_next();
+ Trap::Interrupt(Interrupt::SupervisorTimer) => {
+ set_next_trigger();
+ suspend_current_and_run_next();
}
- _ => {
+ _ => {
panic!(
"Unsupported trap {:?}, stval = {:#x}!",
- scause.cause(),
- stval
+ scause.cause(),
+ stval
);
}
}
- //println!("before trap_return");
- trap_return();
+ //println!("before trap_return");
+ trap_return();
}
-#[no_mangle]
-/// set the new addr of __restore asm function in TRAMPOLINE page,
-/// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
-/// finally, jump to new addr of __restore asm function
-pub fn trap_return() -> ! {
- set_user_trap_entry();
- let trap_cx_ptr = TRAP_CONTEXT;
- let user_satp = current_user_token();
- extern "C" {
- fn __alltraps();
- fn __restore();
+#[no_mangle]
+/// set the new addr of __restore asm function in TRAMPOLINE page,
+/// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
+/// finally, jump to new addr of __restore asm function
+pub fn trap_return() -> ! {
+ set_user_trap_entry();
+ let trap_cx_ptr = TRAP_CONTEXT;
+ let user_satp = current_user_token();
+ extern "C" {
+ fn __alltraps();
+ fn __restore();
}
- let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE;
- unsafe {
+ let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE;
+ unsafe {
asm!(
"fence.i",
"jr {restore_va}",
- restore_va = in(reg) restore_va,
- in("a0") trap_cx_ptr,
- in("a1") user_satp,
- options(noreturn)
+ restore_va = in(reg) restore_va,
+ in("a0") trap_cx_ptr,
+ in("a1") user_satp,
+ options(noreturn)
);
}
}
-#[no_mangle]
-/// Unimplement: traps/interrupts/exceptions from kernel mode
-/// Todo: Chapter 9: I/O device
-pub fn trap_from_kernel() -> ! {
- use riscv::register::sepc;
- println!("stval = {:#x}, sepc = {:#x}", stval::read(), sepc::read());
- panic!("a trap {:?} from kernel!", scause::read().cause());
+#[no_mangle]
+/// Unimplement: traps/interrupts/exceptions from kernel mode
+/// Todo: Chapter 9: I/O device
+pub fn trap_from_kernel() -> ! {
+ use riscv::register::sepc;
+ println!("stval = {:#x}, sepc = {:#x}", stval::read(), sepc::read());
+ panic!("a trap {:?} from kernel!", scause::read().cause());
}
-pub use context::TrapContext;
-
-
fn:
) to \
+ restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
+ enum
, trait
, type
, macro
, \
+ and const
.","Search functions by type signature (e.g., vec -> usize
or \
+ -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
+ your request: \"string\"
","Look for functions that accept or return \
+ slices and \
+ arrays by writing \
+ square brackets (e.g., -> [u8]
or [] -> Option
)","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="${value.replaceAll(" ", " ")}
`}else{error[index]=value}});output+=`