天天看點

Bootmgr Part1 - SakiProject

之前說過Bootmgr要負責切換CPU到保護模式甚至長模式,是以我們肯定要碰到GDT的設定,而GDT表項的結構異常複雜,于是我就直接寫了一個小工具算GDT,之前使用的是nasm的宏,但是其實GDT沒必要每次編譯都算,我記得Linux也是寫死的,是以我就打算直接算出來然後寫死。今天這個Part就是這個小工具的源代碼,用node.js寫的。

I said before that bootmgr will be responsible for switching the CPU into protected mode or even long mode, so we should set GDT first. Since the GDT is very complex, so I just write a tool to calculate GDT directly. I used to use the macro in nasm to calculate GDT, but I think it's not necessary to calculate GDT when compiling, and even Linux hard coded the GDT, so I decide to do the same way. This part is the source code of the small tool, written in node.js.

#!/usr/local/bin/node
(function(){
  var fs=require("fs");
  var fd=fs.openSync("/dev/stdin","rs");
  global.readLine=function(){
    var buffer=new Buffer(1);
    var string="";
    while(true){
      fs.readSync(fd, buffer, 0, 1);
      if(buffer[0]==10){
        break;
      }
      string+=String.fromCharCode(buffer[0]);
    }
    return string;
  }
  global.print=function(x){process.stdout.write(x);}
  global.prompt=function(x, def){
    print(x+ " ["+def+"]: ");
    var input=readLine();
    if(!input)input=def;
    return input;
  }
})();

function GDT(base, limit, ext){
  ext|=0x80;  // Present
  ext|=0x10;  // Code/Data
  ext|=0x2;   // Read/Write
  
  function trunc(x){
    x="00000000"+x;
    return x.substring(x.length-8);
  }

  if(limit>1<<20){
    limit>>=12;
    ext|=0x8000;
  }
  ext|=(limit&0xF0000)>>8;
  var w1=(base&0xFF000000)|(ext<<8)|((base>>16)&0xFF);
  var w2=((base&0xFFFF)<<16)|(limit&0xFFFF);
  return trunc(w1.toString(16))+trunc(w2.toString(16));
}

var base, limit, ext;

console.log("GDT Calculator: ");
base=parseInt(prompt("Base", "0"));
limit=parseInt(prompt("Limit", "0xFFFFFFFF"));
ext|=(prompt("Code", "y")=="y"?8:0);
{var bits=prompt("Bits", 32);ext|=bits==32?0x4000:(bits==16?0:0x2000)}
ext|=parseInt(prompt("Ring", "0"))<<5;
console.log(GDT(base, limit, ext));
           

繼續閱讀