Debugger must use CPU memory functions now, in preparation for paging
This commit is contained in:
parent
380db6ef7d
commit
f36b79cd25
4 changed files with 138 additions and 31 deletions
|
|
@ -1513,10 +1513,10 @@ if (DEBUGGER) {
|
||||||
{
|
{
|
||||||
this.println("id physaddr blkaddr used size type");
|
this.println("id physaddr blkaddr used size type");
|
||||||
this.println("-------- --------- -------- ------ ------ ----");
|
this.println("-------- --------- -------- ------ ------ ----");
|
||||||
for (var i = 0; i < this.bus.aMemBlocks.length; i++) {
|
for (var i = 0; i < this.cpu.aMemBlocks.length; i++) {
|
||||||
var block = this.bus.aMemBlocks[i];
|
var block = this.cpu.aMemBlocks[i];
|
||||||
if (block.type === Memory.TYPE.NONE) continue;
|
if (block.type === Memory.TYPE.NONE) continue;
|
||||||
this.println(str.toHex(block.id) + " %" + str.toHex(i << this.bus.blockShift) + ": " + str.toHex(block.addr) + " " + str.toHexWord(block.used) + " " + str.toHexWord(block.size) + " " + Memory.TYPE.NAMES[block.type]);
|
this.println(str.toHex(block.id) + " %" + str.toHex(i << this.cpu.blockShift) + ": " + str.toHex(block.addr) + " " + str.toHexWord(block.used) + " " + str.toHexWord(block.size) + " " + Memory.TYPE.NAMES[block.type]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1636,7 +1636,7 @@ if (DEBUGGER) {
|
||||||
for (var sField in Debugger.aTSSFields) {
|
for (var sField in Debugger.aTSSFields) {
|
||||||
var off = Debugger.aTSSFields[sField];
|
var off = Debugger.aTSSFields[sField];
|
||||||
var ch = (sField.length < 8? ' ' : '');
|
var ch = (sField.length < 8? ' ' : '');
|
||||||
var w = this.bus.getShortDirect(seg.base + off);
|
var w = this.cpu.getShort(seg.base + off);
|
||||||
if (sDump) sDump += '\n';
|
if (sDump) sDump += '\n';
|
||||||
sDump += str.toHexWord(off) + " " + sField + ": " + ch + str.toHexWord(w);
|
sDump += str.toHexWord(off) + " " + sField + ": " + ch + str.toHexWord(w);
|
||||||
}
|
}
|
||||||
|
|
@ -2450,7 +2450,7 @@ if (DEBUGGER) {
|
||||||
*/
|
*/
|
||||||
if (nState >= 0 && this.aaOpcodeCounts.length) {
|
if (nState >= 0 && this.aaOpcodeCounts.length) {
|
||||||
this.cInstructions++;
|
this.cInstructions++;
|
||||||
var bOpcode = this.bus.getByteDirect(addr);
|
var bOpcode = this.cpu.getByte(addr);
|
||||||
this.aaOpcodeCounts[bOpcode][1]++;
|
this.aaOpcodeCounts[bOpcode][1]++;
|
||||||
var a = this.aOpcodeHistory[this.iOpcodeHistory];
|
var a = this.aOpcodeHistory[this.iOpcodeHistory];
|
||||||
a[0] = this.cpu.getIP();
|
a[0] = this.cpu.getIP();
|
||||||
|
|
@ -2602,8 +2602,7 @@ if (DEBUGGER) {
|
||||||
/**
|
/**
|
||||||
* getByte(aAddr, inc)
|
* getByte(aAddr, inc)
|
||||||
*
|
*
|
||||||
* getByte() should be used for all Debugger memory reads (eg, doDump, doUnassemble), to ensure
|
* We must route all our memory requests through the CPU now, in case paging is enabled.
|
||||||
* all notification handlers are bypassed for physical addresses.
|
|
||||||
*
|
*
|
||||||
* @this {Debugger}
|
* @this {Debugger}
|
||||||
* @param {Array} aAddr
|
* @param {Array} aAddr
|
||||||
|
|
@ -2615,8 +2614,9 @@ if (DEBUGGER) {
|
||||||
var b = 0xff;
|
var b = 0xff;
|
||||||
var addr = this.getAddr(aAddr, false, 1);
|
var addr = this.getAddr(aAddr, false, 1);
|
||||||
if (addr !== X86.ADDR_INVALID) {
|
if (addr !== X86.ADDR_INVALID) {
|
||||||
b = this.bus.getByteDirect(addr);
|
this.nSuppress++;
|
||||||
this.assert((b == (b & 0xff)), "invalid byte (" + b + ") at address: " + this.hexAddr(aAddr));
|
b = this.cpu.getByte(addr);
|
||||||
|
this.nSuppress--;
|
||||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
|
|
@ -2651,8 +2651,9 @@ if (DEBUGGER) {
|
||||||
var w = 0xffff;
|
var w = 0xffff;
|
||||||
var addr = this.getAddr(aAddr, false, 2);
|
var addr = this.getAddr(aAddr, false, 2);
|
||||||
if (addr !== X86.ADDR_INVALID) {
|
if (addr !== X86.ADDR_INVALID) {
|
||||||
w = this.bus.getShortDirect(addr);
|
this.nSuppress++;
|
||||||
this.assert((w == (w & 0xffff)), "invalid word (" + w + ") at address: " + this.hexAddr(aAddr));
|
w = this.cpu.getShort(addr);
|
||||||
|
this.nSuppress--;
|
||||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
|
|
@ -2671,7 +2672,9 @@ if (DEBUGGER) {
|
||||||
var l = -1;
|
var l = -1;
|
||||||
var addr = this.getAddr(aAddr, false, 4);
|
var addr = this.getAddr(aAddr, false, 4);
|
||||||
if (addr !== X86.ADDR_INVALID) {
|
if (addr !== X86.ADDR_INVALID) {
|
||||||
l = this.bus.getLongDirect(addr);
|
this.nSuppress++;
|
||||||
|
l = this.cpu.getLong(addr);
|
||||||
|
this.nSuppress--;
|
||||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
|
|
@ -2680,10 +2683,6 @@ if (DEBUGGER) {
|
||||||
/**
|
/**
|
||||||
* setByte(aAddr, b, inc)
|
* setByte(aAddr, b, inc)
|
||||||
*
|
*
|
||||||
* setByte() should be used for all Debugger memory writes (eg, doAssemble, doEdit), to insure
|
|
||||||
* all memory notification handlers are bypassed; in addition, we want the Debugger to be able to
|
|
||||||
* change the contents of the simulated ROM images.
|
|
||||||
*
|
|
||||||
* @this {Debugger}
|
* @this {Debugger}
|
||||||
* @param {Array} aAddr
|
* @param {Array} aAddr
|
||||||
* @param {number} b
|
* @param {number} b
|
||||||
|
|
@ -2693,7 +2692,9 @@ if (DEBUGGER) {
|
||||||
{
|
{
|
||||||
var addr = this.getAddr(aAddr, true, 1);
|
var addr = this.getAddr(aAddr, true, 1);
|
||||||
if (addr !== X86.ADDR_INVALID) {
|
if (addr !== X86.ADDR_INVALID) {
|
||||||
this.bus.setByteDirect(addr, b);
|
this.nSuppress++;
|
||||||
|
this.cpu.setByte(addr, b);
|
||||||
|
this.nSuppress--;
|
||||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||||
this.cpu.updateCPU();
|
this.cpu.updateCPU();
|
||||||
}
|
}
|
||||||
|
|
@ -2711,7 +2712,9 @@ if (DEBUGGER) {
|
||||||
{
|
{
|
||||||
var addr = this.getAddr(aAddr, true, 2);
|
var addr = this.getAddr(aAddr, true, 2);
|
||||||
if (addr !== X86.ADDR_INVALID) {
|
if (addr !== X86.ADDR_INVALID) {
|
||||||
this.bus.setShortDirect(addr, w);
|
this.nSuppress++;
|
||||||
|
this.cpu.setShort(addr, w);
|
||||||
|
this.nSuppress--;
|
||||||
if (inc !== undefined) this.incAddr(aAddr, inc);
|
if (inc !== undefined) this.incAddr(aAddr, inc);
|
||||||
this.cpu.updateCPU();
|
this.cpu.updateCPU();
|
||||||
}
|
}
|
||||||
|
|
@ -2738,6 +2741,7 @@ if (DEBUGGER) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.aBreakWrite = ["write"];
|
this.aBreakWrite = ["write"];
|
||||||
|
this.nSuppress = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2921,6 +2925,8 @@ if (DEBUGGER) {
|
||||||
*/
|
*/
|
||||||
Debugger.prototype.checkBreakpoint = function(addr, aBreak, fTemp)
|
Debugger.prototype.checkBreakpoint = function(addr, aBreak, fTemp)
|
||||||
{
|
{
|
||||||
|
if (this.nSuppress) return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Time to check for execution breakpoints; note that this should be done BEFORE updating frequency
|
* Time to check for execution breakpoints; note that this should be done BEFORE updating frequency
|
||||||
* or history data (see checkInstruction), since we might not actually execute the current instruction.
|
* or history data (see checkInstruction), since we might not actually execute the current instruction.
|
||||||
|
|
@ -3536,8 +3542,8 @@ if (DEBUGGER) {
|
||||||
*/
|
*/
|
||||||
Debugger.prototype.parseAddr = function(sAddr, type)
|
Debugger.prototype.parseAddr = function(sAddr, type)
|
||||||
{
|
{
|
||||||
|
var aAddr;
|
||||||
var aAddrNext = (type == Debugger.ADDR_DATA? this.aAddrNextData : this.aAddrNextCode);
|
var aAddrNext = (type == Debugger.ADDR_DATA? this.aAddrNextData : this.aAddrNextCode);
|
||||||
|
|
||||||
var off = aAddrNext[0], seg = aAddrNext[1], addr = aAddrNext[2];
|
var off = aAddrNext[0], seg = aAddrNext[1], addr = aAddrNext[2];
|
||||||
|
|
||||||
if (sAddr !== undefined) {
|
if (sAddr !== undefined) {
|
||||||
|
|
@ -3549,7 +3555,7 @@ if (DEBUGGER) {
|
||||||
addr = 0;
|
addr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var aAddr = this.findSymbolAddr(sAddr);
|
aAddr = this.findSymbolAddr(sAddr);
|
||||||
if (aAddr && aAddr.length) return aAddr;
|
if (aAddr && aAddr.length) return aAddr;
|
||||||
|
|
||||||
var iColon = sAddr.indexOf(":");
|
var iColon = sAddr.indexOf(":");
|
||||||
|
|
@ -3567,7 +3573,8 @@ if (DEBUGGER) {
|
||||||
addr = null;
|
addr = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var aAddr = [off, seg, addr];
|
|
||||||
|
aAddr = [off, seg, addr];
|
||||||
this.checkLimit(aAddr);
|
this.checkLimit(aAddr);
|
||||||
return aAddr;
|
return aAddr;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3643,7 +3643,7 @@ X86.fnPageFault = function(addr, fPresent, fWrite)
|
||||||
X86.fnFaultMessage = function(nFault, nError, fHalt)
|
X86.fnFaultMessage = function(nFault, nError, fHalt)
|
||||||
{
|
{
|
||||||
var bitsMessage = Messages.FAULT;
|
var bitsMessage = Messages.FAULT;
|
||||||
var bOpcode = this.bus.getByteDirect(this.regLIP);
|
var bOpcode = this.getByte(this.regLIP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OS/2 1.0 uses an INT3 (0xCC) opcode in conjunction with an invalid IDT to trigger a triple-fault
|
* OS/2 1.0 uses an INT3 (0xCC) opcode in conjunction with an invalid IDT to trigger a triple-fault
|
||||||
|
|
|
||||||
|
|
@ -605,6 +605,13 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
||||||
var fGate, regPSMask, nFaultError, regSP;
|
var fGate, regPSMask, nFaultError, regSP;
|
||||||
var rpl = sel & X86.SEL.RPL;
|
var rpl = sel & X86.SEL.RPL;
|
||||||
var dpl = (acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;
|
var dpl = (acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;
|
||||||
|
|
||||||
|
if (selMasked && !(acc & X86.DESC.ACC.PRESENT)) {
|
||||||
|
if (!fSuppress) X86.fnFault.call(cpu, X86.EXCEPTION.NP_FAULT, sel);
|
||||||
|
base = X86.ADDR_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we are X86Seg.ID.CODE, we can use this.cpl instead of the more generic cpu.segCS.cpl
|
* Since we are X86Seg.ID.CODE, we can use this.cpl instead of the more generic cpu.segCS.cpl
|
||||||
*/
|
*/
|
||||||
|
|
@ -713,7 +720,12 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
||||||
}
|
}
|
||||||
else if (this.id == X86Seg.ID.DATA) {
|
else if (this.id == X86Seg.ID.DATA) {
|
||||||
if (selMasked) {
|
if (selMasked) {
|
||||||
if (type < X86.DESC.ACC.TYPE.DATA_READONLY || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {
|
if (!(acc & X86.DESC.ACC.PRESENT)) {
|
||||||
|
if (!fSuppress) X86.fnFault.call(cpu, X86.EXCEPTION.NP_FAULT, sel);
|
||||||
|
base = X86.ADDR_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {
|
||||||
/*
|
/*
|
||||||
* OS/2 1.0 triggers this "Empty Descriptor" GP_FAULT multiple times during boot; eg:
|
* OS/2 1.0 triggers this "Empty Descriptor" GP_FAULT multiple times during boot; eg:
|
||||||
*
|
*
|
||||||
|
|
@ -742,7 +754,12 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fSuppress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this.id == X86Seg.ID.STACK) {
|
else if (this.id == X86Seg.ID.STACK) {
|
||||||
if (!selMasked || type < X86.DESC.ACC.TYPE.DATA_READONLY || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {
|
if (!(acc & X86.DESC.ACC.PRESENT)) {
|
||||||
|
if (!fSuppress) X86.fnFault.call(cpu, X86.EXCEPTION.SS_FAULT, sel);
|
||||||
|
base = X86.ADDR_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!selMasked || type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.WRITABLE)) != X86.DESC.ACC.TYPE.WRITABLE) {
|
||||||
if (!fSuppress) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel, true);
|
if (!fSuppress) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel, true);
|
||||||
base = X86.ADDR_INVALID;
|
base = X86.ADDR_INVALID;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,32 @@ DPL2 equ 2
|
||||||
DPL3 equ 3
|
DPL3 equ 3
|
||||||
|
|
||||||
ACC_TYPE_SEG equ 0x1000
|
ACC_TYPE_SEG equ 0x1000
|
||||||
|
ACC_PRESENT equ 0x8000
|
||||||
ACC_TYPE_CODE equ 0x0800
|
ACC_TYPE_CODE equ 0x0800
|
||||||
ACC_TYPE_READABLE equ 0x0200
|
ACC_TYPE_READABLE equ 0x0200
|
||||||
ACC_TYPE_WRITABLE equ 0x0200
|
ACC_TYPE_WRITABLE equ 0x0200
|
||||||
ACC_TYPE_CODE_READABLE equ 0x1a00
|
ACC_TYPE_CODE_READABLE equ (0x1a00 | ACC_PRESENT)
|
||||||
ACC_TYPE_DATA_WRITABLE equ 0x1200
|
ACC_TYPE_DATA_WRITABLE equ (0x1200 | ACC_PRESENT)
|
||||||
|
|
||||||
EXT_BIG equ 0x0040
|
EXT_BIG equ 0x0040
|
||||||
|
|
||||||
|
;
|
||||||
|
; We build some data structures in the first page (0x0000-0x0fff) of RAM:
|
||||||
|
;
|
||||||
|
; 0x0000-0x03ff Real-mode IDT (256*4)
|
||||||
|
; 0x0400-0x0bff Prot-mode IDT (256*8)
|
||||||
|
; 0x0c00-0x0cff GDT (enough room for 32 selectors)
|
||||||
|
; 0x0d00-0x0d07 IDTR
|
||||||
|
; 0x0d08-0x0d0f GDTR
|
||||||
|
; 0x0d10-0x0fff reserved
|
||||||
|
;
|
||||||
|
; And in the second page (0x1000-0x1fff), let's build a page directory, followed by a single page table that
|
||||||
|
; will allow us to map up to 4Mb (although we'll only create entries for the first 1Mb).
|
||||||
|
;
|
||||||
|
RAM_GDT equ 0x0c00
|
||||||
|
RAM_IDTR equ 0x0d00
|
||||||
|
RAM_GDTR equ 0x0d08
|
||||||
|
|
||||||
CSEG_REAL equ 0xf000
|
CSEG_REAL equ 0xf000
|
||||||
CSEG_PROT equ 0x0008
|
CSEG_PROT equ 0x0008
|
||||||
DSEG_PROT equ 0x0010
|
DSEG_PROT equ 0x0010
|
||||||
|
|
@ -29,22 +47,77 @@ DSEG_PROT equ 0x0010
|
||||||
CR0_MSW_PE equ 0x0001
|
CR0_MSW_PE equ 0x0001
|
||||||
|
|
||||||
;
|
;
|
||||||
; descDT defines a descriptor, given a base (%1), limit (%2), type (%3), dpl (%4), and ext (%5)
|
; set initializes a register to the specified value (eg, "set eax,0")
|
||||||
;
|
;
|
||||||
%macro defDesc 1-5 0,0,0,0
|
%macro set 2
|
||||||
|
%if %2 = 0
|
||||||
|
sub %1,%1
|
||||||
|
%else
|
||||||
|
mov %1,%2
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
;
|
||||||
|
; defDesc defines a descriptor, given a base (%1), limit (%2), type (%3), dpl (%4), and ext (%5)
|
||||||
|
;
|
||||||
|
%macro defDesc 1-4 0,0,0,0
|
||||||
dw (%2 & 0x0000ffff)
|
dw (%2 & 0x0000ffff)
|
||||||
dw (%1 & 0x0000ffff)
|
dw (%1 & 0x0000ffff)
|
||||||
dw ((%1 & 0x00ff0000) >> 16) | %3 | (%4 << 13)
|
dw ((%1 & 0x00ff0000) >> 16) | %3 | (%4 << 13)
|
||||||
dw ((%2 & 0x000f0000) >> 16) | %5 | ((%1 & 0xff000000) >> 16)
|
dw ((%2 & 0x000f0000) >> 16) | %5 | ((%1 & 0xff000000) >> 16)
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
;
|
||||||
|
; setDesc creates a descriptor, given a base (%1), limit (%2), type (%3), dpl (%4), and ext (%5)
|
||||||
|
;
|
||||||
|
%assign selDesc 0
|
||||||
|
%macro setDesc 1-4 0,0,0,none
|
||||||
|
set ebx,%1
|
||||||
|
set ecx,%2
|
||||||
|
set edx,%3
|
||||||
|
call storeDesc
|
||||||
|
%assign %4 selDesc
|
||||||
|
%assign selDesc selDesc+8
|
||||||
|
%endmacro
|
||||||
|
|
||||||
start: mov eax,0x44332211
|
start: cli ; disable all interrupts
|
||||||
|
mov al,0xff ; and ensure that no hardware interrupts can sneak in
|
||||||
|
out 0x21,al ; if interrupts become enabled later
|
||||||
|
out 0xa1,al
|
||||||
|
|
||||||
|
sub ax,ax
|
||||||
|
mov ds,ax
|
||||||
|
mov es,ax
|
||||||
|
mov ss,ax
|
||||||
|
mov sp,0x1000
|
||||||
|
|
||||||
|
mov eax,0x44332211
|
||||||
|
mov ebx,eax
|
||||||
mov ecx,0x88776655
|
mov ecx,0x88776655
|
||||||
mul ecx
|
mul ecx
|
||||||
div ecx
|
div ecx
|
||||||
jnz near goProt ; apparently we have to tell NASM "near" because this is a forward reference
|
cmp eax,ebx
|
||||||
|
je near initRAM ; apparently we have to tell NASM "near" because this is a forward reference
|
||||||
times 32768 nop ; lots of NOPs to force a 16-bit conditional jump
|
times 32768 nop ; lots of NOPs to force a 16-bit conditional jump
|
||||||
|
;
|
||||||
|
; storeDesc(EBX=base, ECX=limit, EDX=type, EDI=target)
|
||||||
|
;
|
||||||
|
storeDesc:
|
||||||
|
cld
|
||||||
|
mov ax,cx
|
||||||
|
stosw ; store the low 16 bits of limit from ECX
|
||||||
|
mov ax,bx
|
||||||
|
stosw ; store the low 16 bits of base from EBX
|
||||||
|
mov ax,dx
|
||||||
|
shr ebx,16
|
||||||
|
mov al,bl
|
||||||
|
stosw
|
||||||
|
shr ecx,16
|
||||||
|
mov al,cl
|
||||||
|
and al,0xf
|
||||||
|
mov ah,bh
|
||||||
|
stosw
|
||||||
|
ret
|
||||||
|
|
||||||
addrGDT:dw romGDTEnd - romGDT - 1 ; 16-bit limit of romGDT
|
addrGDT:dw romGDTEnd - romGDT - 1 ; 16-bit limit of romGDT
|
||||||
dw romGDT, 0xffff ; 32-bit base address of romGDT (works as long as we're aliased at 0xffff0000)
|
dw romGDT, 0xffff ; 32-bit base address of romGDT (works as long as we're aliased at 0xffff0000)
|
||||||
|
|
@ -54,7 +127,17 @@ romGDT: defDesc 0 ; the first descriptor in any descriptor table is always a d
|
||||||
defDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE
|
defDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE
|
||||||
romGDTEnd:
|
romGDTEnd:
|
||||||
|
|
||||||
goProt: o32 lgdt [cs:addrGDT]
|
initRAM:
|
||||||
|
set edi,RAM_GDT
|
||||||
|
mov [RAM_GDTR+2],edi
|
||||||
|
setDesc 0,0,0,NULL
|
||||||
|
setDesc 0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,CSEG_PROT
|
||||||
|
setDesc 0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE,DSEG_PROT
|
||||||
|
sub edi,RAM_GDT
|
||||||
|
dec edi
|
||||||
|
mov [RAM_GDTR],di
|
||||||
|
|
||||||
|
goProt: o32 lgdt [RAM_GDTR]
|
||||||
mov eax,cr0
|
mov eax,cr0
|
||||||
or eax,CR0_MSW_PE
|
or eax,CR0_MSW_PE
|
||||||
mov cr0,eax
|
mov cr0,eax
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue