📄 setup.htm
字号:
<a name=L108 href="source/boot/setup.s#L108">108</a> <a name=L109 href="source/boot/setup.s#L109">109</a> cli ! no interrupts allowed !<a name=L110 href="source/boot/setup.s#L110">110</a> <a name=L111 href="source/boot/setup.s#L111">111</a> ! first we move the system to it's rightful place<a name=L112 href="source/boot/setup.s#L112">112</a> <a name=L113 href="source/boot/setup.s#L113">113</a> mov ax,#0x0000<a name=L114 href="source/boot/setup.s#L114">114</a> cld ! 'direction'=0, movs moves forward<a name=L115 href="source/boot/setup.s#L115">115</a> do_move:<a name=L116 href="source/boot/setup.s#L116">116</a> mov es,ax ! destination segment<a name=L117 href="source/boot/setup.s#L117">117</a> add ax,#0x1000<a name=L118 href="source/boot/setup.s#L118">118</a> cmp ax,#0x9000<a name=L119 href="source/boot/setup.s#L119">119</a> jz end_move<a name=L120 href="source/boot/setup.s#L120">120</a> mov ds,ax ! source segment<a name=L121 href="source/boot/setup.s#L121">121</a> sub di,di<a name=L122 href="source/boot/setup.s#L122">122</a> sub si,si<a name=L123 href="source/boot/setup.s#L123">123</a> mov cx,#0x8000<a name=L124 href="source/boot/setup.s#L124">124</a> rep<a name=L125 href="source/boot/setup.s#L125">125</a> movsw<a name=L126 href="source/boot/setup.s#L126">126</a> jmp do_move<a name=L127 href="source/boot/setup.s#L127">127</a> <a name=L128 href="source/boot/setup.s#L128">128</a> ! then we load the segment descriptors<a name=L129 href="source/boot/setup.s#L129">129</a> <a name=L130 href="source/boot/setup.s#L130">130</a> end_move:<a name=L131 href="source/boot/setup.s#L131">131</a> mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)<a name=L132 href="source/boot/setup.s#L132">132</a> mov ds,ax<a name=L133 href="source/boot/setup.s#L133">133</a> lidt idt_48 ! load idt with 0,0<a name=L134 href="source/boot/setup.s#L134">134</a> lgdt gdt_48 ! load gdt with whatever appropriate<a name=L135 href="source/boot/setup.s#L135">135</a> <a name=L136 href="source/boot/setup.s#L136">136</a> ! that was painless, now we enable A20<a name=L137 href="source/boot/setup.s#L137">137</a> <a name=L138 href="source/boot/setup.s#L138">138</a> call empty_8042<a name=L139 href="source/boot/setup.s#L139">139</a> mov al,#0xD1 ! command write<a name=L140 href="source/boot/setup.s#L140">140</a> out #0x64,al<a name=L141 href="source/boot/setup.s#L141">141</a> call empty_8042<a name=L142 href="source/boot/setup.s#L142">142</a> mov al,#0xDF ! A20 on<a name=L143 href="source/boot/setup.s#L143">143</a> out #0x60,al<a name=L144 href="source/boot/setup.s#L144">144</a> call empty_8042<a name=L145 href="source/boot/setup.s#L145">145</a> <a name=L146 href="source/boot/setup.s#L146">146</a> ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(<a name=L147 href="source/boot/setup.s#L147">147</a> ! we put them right after the intel-reserved hardware interrupts, at<a name=L148 href="source/boot/setup.s#L148">148</a> ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really<a name=L149 href="source/boot/setup.s#L149">149</a> ! messed this up with the original PC, and they haven't been able to<a name=L150 href="source/boot/setup.s#L150">150</a> ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,<a name=L151 href="source/boot/setup.s#L151">151</a> ! which is used for the internal hardware interrupts as well. We just<a name=L152 href="source/boot/setup.s#L152">152</a> ! have to reprogram the 8259's, and it isn't fun.<a name=L153 href="source/boot/setup.s#L153">153</a> <a name=L154 href="source/boot/setup.s#L154">154</a> mov al,#0x11 ! initialization sequence<a name=L155 href="source/boot/setup.s#L155">155</a> out #0x20,al ! send it to 8259A-1<a name=L156 href="source/boot/setup.s#L156">156</a> .word 0x00eb,0x00eb ! jmp $+2, jmp $+2<a name=L157 href="source/boot/setup.s#L157">157</a> out #0xA0,al ! and to 8259A-2<a name=L158 href="source/boot/setup.s#L158">158</a> .word 0x00eb,0x00eb<a name=L159 href="source/boot/setup.s#L159">159</a> mov al,#0x20 ! start of hardware int's (0x20)<a name=L160 href="source/boot/setup.s#L160">160</a> out #0x21,al<a name=L161 href="source/boot/setup.s#L161">161</a> .word 0x00eb,0x00eb<a name=L162 href="source/boot/setup.s#L162">162</a> mov al,#0x28 ! start of hardware int's 2 (0x28)<a name=L163 href="source/boot/setup.s#L163">163</a> out #0xA1,al<a name=L164 href="source/boot/setup.s#L164">164</a> .word 0x00eb,0x00eb<a name=L165 href="source/boot/setup.s#L165">165</a> mov al,#0x04 ! 8259-1 is master<a name=L166 href="source/boot/setup.s#L166">166</a> out #0x21,al<a name=L167 href="source/boot/setup.s#L167">167</a> .word 0x00eb,0x00eb<a name=L168 href="source/boot/setup.s#L168">168</a> mov al,#0x02 ! 8259-2 is slave<a name=L169 href="source/boot/setup.s#L169">169</a> out #0xA1,al<a name=L170 href="source/boot/setup.s#L170">170</a> .word 0x00eb,0x00eb<a name=L171 href="source/boot/setup.s#L171">171</a> mov al,#0x01 ! 8086 mode for both<a name=L172 href="source/boot/setup.s#L172">172</a> out #0x21,al<a name=L173 href="source/boot/setup.s#L173">173</a> .word 0x00eb,0x00eb<a name=L174 href="source/boot/setup.s#L174">174</a> out #0xA1,al<a name=L175 href="source/boot/setup.s#L175">175</a> .word 0x00eb,0x00eb<a name=L176 href="source/boot/setup.s#L176">176</a> mov al,#0xFF ! mask off all interrupts for now<a name=L177 href="source/boot/setup.s#L177">177</a> out #0x21,al<a name=L178 href="source/boot/setup.s#L178">178</a> .word 0x00eb,0x00eb<a name=L179 href="source/boot/setup.s#L179">179</a> out #0xA1,al<a name=L180 href="source/boot/setup.s#L180">180</a> <a name=L181 href="source/boot/setup.s#L181">181</a> ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't<a name=L182 href="source/boot/setup.s#L182">182</a> ! need no steenking BIOS anyway (except for the initial loading :-).<a name=L183 href="source/boot/setup.s#L183">183</a> ! The BIOS-routine wants lots of unnecessary data, and it's less<a name=L184 href="source/boot/setup.s#L184">184</a> ! "interesting" anyway. This is how REAL programmers do it.<a name=L185 href="source/boot/setup.s#L185">185</a> !<a name=L186 href="source/boot/setup.s#L186">186</a> ! Well, now's the time to actually move into protected mode. To make<a name=L187 href="source/boot/setup.s#L187">187</a> ! things as simple as possible, we do no register set-up or anything,<a name=L188 href="source/boot/setup.s#L188">188</a> ! we let the gnu-compiled 32-bit programs do that. We just jump to<a name=L189 href="source/boot/setup.s#L189">189</a> ! absolute address 0x00000, in 32-bit protected mode.<a name=L190 href="source/boot/setup.s#L190">190</a> <a name=L191 href="source/boot/setup.s#L191">191</a> mov ax,#0x0001 ! protected mode (PE) bit<a name=L192 href="source/boot/setup.s#L192">192</a> lmsw ax ! This is it!<a name=L193 href="source/boot/setup.s#L193">193</a> jmpi 0,8 ! jmp offset 0 of segment 8 (cs)<a name=L194 href="source/boot/setup.s#L194">194</a> <a name=L195 href="source/boot/setup.s#L195">195</a> ! This routine checks that the keyboard command queue is empty<a name=L196 href="source/boot/setup.s#L196">196</a> ! No timeout is used - if this hangs there is something wrong with<a name=L197 href="source/boot/setup.s#L197">197</a> ! the machine, and we probably couldn't proceed anyway.<a name=L198 href="source/boot/setup.s#L198">198</a> empty_8042:<a name=L199 href="source/boot/setup.s#L199">199</a> .word 0x00eb,0x00eb<a name=L200 href="source/boot/setup.s#L200">200</a> in al,#0x64 ! 8042 status port<a name=L201 href="source/boot/setup.s#L201">201</a> test al,#2 ! is input buffer full?<a name=L202 href="source/boot/setup.s#L202">202</a> jnz empty_8042 ! yes - loop<a name=L203 href="source/boot/setup.s#L203">203</a> ret<a name=L204 href="source/boot/setup.s#L204">204</a> <a name=L205 href="source/boot/setup.s#L205">205</a> gdt:<a name=L206 href="source/boot/setup.s#L206">206</a> .word 0,0,0,0 ! dummy<a name=L207 href="source/boot/setup.s#L207">207</a> <a name=L208 href="source/boot/setup.s#L208">208</a> .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)<a name=L209 href="source/boot/setup.s#L209">209</a> .word 0x0000 ! base address=0<a name=L210 href="source/boot/setup.s#L210">210</a> .word 0x9A00 ! code read/exec<a name=L211 href="source/boot/setup.s#L211">211</a> .word 0x00C0 ! granularity=4096, 386<a name=L212 href="source/boot/setup.s#L212">212</a> <a name=L213 href="source/boot/setup.s#L213">213</a> .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)<a name=L214 href="source/boot/setup.s#L214">214</a> .word 0x0000 ! base address=0<a name=L215 href="source/boot/setup.s#L215">215</a> .word 0x9200 ! data read/write<a name=L216 href="source/boot/setup.s#L216">216</a> .word 0x00C0 ! granularity=4096, 386<a name=L217 href="source/boot/setup.s#L217">217</a> <a name=L218 href="source/boot/setup.s#L218">218</a> idt_48:<a name=L219 href="source/boot/setup.s#L219">219</a> .word 0 ! idt limit=0<a name=L220 href="source/boot/setup.s#L220">220</a> .word 0,0 ! idt base=0L<a name=L221 href="source/boot/setup.s#L221">221</a> <a name=L222 href="source/boot/setup.s#L222">222</a> gdt_48:<a name=L223 href="source/boot/setup.s#L223">223</a> .word 0x800 ! gdt limit=2048, 256 GDT entries<a name=L224 href="source/boot/setup.s#L224">224</a> .word 512+gdt,0x9 ! gdt base = 0X9xxxx<a name=L225 href="source/boot/setup.s#L225">225</a> <a name=L226 href="source/boot/setup.s#L226">226</a> .text<a name=L227 href="source/boot/setup.s#L227">227</a> endtext:<a name=L228 href="source/boot/setup.s#L228">228</a> .data<a name=L229 href="source/boot/setup.s#L229">229</a> enddata:<a name=L230 href="source/boot/setup.s#L230">230</a> .bss<a name=L231 href="source/boot/setup.s#L231">231</a> endbss:</pre><hr><div align=center> [<b><i>source navigation</i></b>] [<a href="diff/boot/setup.s">diff markup</a>] [<a href="ident">identifier search</a>] [<a href="search">freetext search</a>] [<a href="find">file search</a>] </div><hr>This page was automatically generated by the <a href="http:blurb.html">LXR engine</a>.<br>Visit the <a href="http://lxr.linux.no/">LXR main site</a> for moreinformation.</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -