Page 1 of 1
final piece of work finished and entered pmode with INT en-d
Posted: Mon Dec 28, 2015 12:40 am
by ggodw000
Today was major milestone: did a final pieces of work today toward entering pmode with interrupts enabled but system froze, so any help will be hugely appreciated because once I get over this, I can virtually move on to my main project:
(NOTE that the same code that enters and exits protected-mode with interrupts DISABLED works perfectly)
- Created Interrupt Descriptor Table with 256 entries.
- First 32 entries are initialized as 386 interrupt gates
- Rest are initialized as 386 trap-gates with 'present flag' set to 0.
- Translated all 32 Interrupt vector 16:16 addresses into flat 0:32 addresses and installed onto Descriptor entries and segment selectors are set to FLAT code segment (#01 on GDT)
- Finally installed Interrupt Descriptor Table base into GDT #03 descriptor
- GDT #3 entry is declared as IDT descriptor with limit 07ffh
I verified huge amount of time to make sure all of the above data structs are initialized correctly, I commented out cli and sti instruction and entered protected-mode with interrupts enabled.
The machine froze so far, but no triple fault is seen in hyper-v events.
Time for troubleshooting.
Anything missing from checklists above?
The only thing I am not sure of is declaring INT and TRAP gates as 386 rather than 286, basically I used the
types 1110b and 1111b
SYS_DESC_386_INT_GATE = 1110b
SYS_DESC_386_TRAP_GATE = 1111b
The Intel manual describes following types:
SYS_DESC_INVALID_0 = 0000b
SYS_DESC_AVAIL_286_TSS = 0001b
SYS_DESC_LDT = 0010b
SYS_DESC_BUSY_286_TSS = 0011B
SYS_DESC_286_CALL_GATE = 0100b
SYS_DESC_TASK_GATE = 0101b
SYS_DESC_286_INT_GATE = 0110b
SYS_DESC_286_TRAP_GATE = 0111b
SYS_DESC_INVALID_1 = 1000b
SYS_DESC_AVAIL_386_TSS = 1001b
SYS_DESC_RSVD_0 = 1010b
SYS_DESC_BUSY_386_TSS = 1011b
SYS_DESC_386_CALL_GATE = 1100b
SYS_DESC_RSVD_1 = 1101b
SYS_DESC_386_INT_GATE = 1110b
SYS_DESC_386_TRAP_GATE = 1111b
But another book defines the 386 INT and TRAP gates as 32-bit and 286 as 16-bit, since I am using 16-bit developments, I am not sure this is the cause.
THanks.,
Re: final piece of work finished and entered pmode with INT
Posted: Mon Dec 28, 2015 2:06 am
by ggodw000
it was working, there was a jmp $ instruction placed, once removed, it all worked. still has not quite believed it worked!
Re: final piece of work finished and entered pmode with INT
Posted: Mon Dec 28, 2015 2:10 am
by iansjack
I can't see any mention of your use of the LIDT instruction anywhere to load the IDTR register.
For reference purposes use the Intel manual rather than any other source.
Re: final piece of work finished and entered pmode with INT
Posted: Mon Dec 28, 2015 2:25 am
by ggodw000
ouch, yes i commented that out too. Put back the lidt, and system hang. Nice, what a roller coaster ride was.
here is so far:
either enable or disable the interrupt, now hang is happening. Must be something in the IDT wrong.
Re: final piece of work finished and entered pmode with INT
Posted: Mon Dec 28, 2015 2:58 am
by iansjack
Invalid stack or SS register is another possibility. Does your interrupt handler get called at all?
Re: final piece of work finished and entered pmode with INT
Posted: Mon Dec 28, 2015 3:07 am
by ggodw000
that was my next milestone actually. I should have done the SS stack descriptor beforehand. I will spend the rest of today and tomorrow to get it working. Thanks for pointer!
Re: final piece of work finished and entered pmode with INT
Posted: Tue Dec 29, 2015 2:19 pm
by ggodw000
Ok, before stack segment setup, I really think it is necessary to determine the available system memory and as usual, decided to use e820 map to get available ranges and allocate stack segment descriptor from this range. For simplicity in my development, I am only going to use, memory above 1MB and below 4GB as allocatable and define any descriptor except flat code and data within this range including stack segment itself. Also later on kernel and user stack, and program spaces.
By doing so, I also have to make sure, that those allocated memory ranges will not conflict with the loaded kernel itself, but that does not seem to be issue here, because the kernel binary itself loads in real mode into <1MB spaces so as long as I dont use <1MB below for any descriptors that should be OK. There is also concern that kernel itself becomes too big to fit in <1MB, and in which case, I have to think of ways to bootstrap itself into extended memory.
So I went ahead and created memmgr (memory manager module) to oversee all memory related stuff, alloc, dealloc and some other functions that took several days. I am going to see what happens once it is up and running.
Re: final piece of work finished and entered pmode with INT
Posted: Wed Dec 30, 2015 12:08 am
by Antti
ggodw000 wrote:There is also concern that kernel itself becomes too big to fit in <1MB, and in which case, I have to think of ways to bootstrap itself into extended memory.
It may be that the kernel size is never going to be a problem. I would assume that at some point you want to have an "initial RAM disk" that contains all kind of system files. That is one reason you should not limit it to below 1 MiB but make it possible to use the whole 32-bit memory space. Skipping 64-bit addresses is acceptable in a BIOS-based boot loader. The second reason is more fuzzy: being able to do it is likely to increase your loader code quality even if you never really need that feature.
Re: final piece of work finished and entered pmode with INT
Posted: Wed Dec 30, 2015 12:34 am
by ggodw000
Yes it may be not, but i would rather play it safe. Right now I am launching the kernel from DOS during initial dev stage but later on make it bootable from MBR. I dont know if DOS will check the available memory size upon loading program (big ?), but if it does not and memory wraps around when it exceeds 1MB nasty things could happen obviously. I actually did this my project before in real-mode only and once started loading the executables and jamming into user space in tiny space below 1MB, the 1MB was crossed and bad things happened. This is the reason, this time, I am trying to implemented fully functional protected mode environment.
Re: final piece of work finished and entered pmode with INT
Posted: Thu Dec 31, 2015 1:36 am
by ggodw000
OK, i finally setup the stack segment and still not working. same as before, as soon as it loads the IDT using LIDT the system resets.
Here are the overall sequence of steps:
Initialize IDT and set GDT's IDT descriptor entry.
Allocate 2k memory for stack segment
Initialize another descriptor in GDT for stack segment with this segment.
perform LGDT and LIDT <-- here it is crashing and rebooting, if LIDT not performed and interrupts remain disabled, system is stable.
Save real-mode stack pointer in memory (from this point on do not change the SS:SP until it loads with pmode values)
Disable interrupts (cli)
Set CR[0]
load DS with flat data
load SS:SP with p-mode stack segment data
Enable interrupts (sti)
(do the p-mode) stuff
Disable back interrupts (cli) (from this point on do not change SS:SP are restored with real mode values previously saved)
Unset CR[0]
restore SS:SP (real-mode)
Enable interrupts (sti)
Since system is resetting when doing LIDT, I think obvious candidate to look for is something might have gotten initialized incorrecly in IDT may be?
I just put the first 4 IVT entries and corresponding IDT entries conversion here that the debug code spits out:
Code: Select all
IVT# at: 0000:0000 (SEG:OFF): FFFF:00CC
IVT# at: 0000:0004 (SEG:OFF): 0070:042B
IVT# at: 0000:0008 (SEG:OFF): F000:E2C3
IVT# at: 0000:000C (SEG:OFF): 0070:042B
==============
Descriptor No 00
===============:
IDT Descriptor Info:
---------------:
008EFFFF:00CC0008
Offset: FFFF:00CC
Desc type=TRAP GATE : 02
Rx07-06: FFFF - Offset 31:16
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4:0]: 0E - Descriptor type (Task/Int/Trap:00101b/0D110/0D111)
Rx04[7:5]: 00 - 000 (must be zero).
Rx04[4:0]: 00 - Reserved.
Rx03-02: 0008 - segment selector.
Rx01-00: 00CC - Offset 15:0.
==============
Descriptor No 01
===============:
IDT Descriptor Info:
---------------:
008E0070:042B0008
Offset: 0070:042B
Desc type=TRAP GATE : 02
Rx07-06: 0070 - Offset 31:16
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4:0]: 0E - Descriptor type (Task/Int/Trap:00101b/0D110/0D111)
Rx04[7:5]: 00 - 000 (must be zero).
Rx04[4:0]: 00 - Reserved.
Rx03-02: 0008 - segment selector.
Rx01-00: 042B - Offset 15:0.
==============
Descriptor No 02
===============:
IDT Descriptor Info:
---------------:
008EF000:E2C30008
Offset: F000:E2C3
Desc type=TRAP GATE : 02
Rx07-06: F000 - Offset 31:16
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4:0]: 0E - Descriptor type (Task/Int/Trap:00101b/0D110/0D111)
Rx04[7:5]: 00 - 000 (must be zero).
Rx04[4:0]: 00 - Reserved.
Rx03-02: 0008 - segment selector.
Rx01-00: E2C3 - Offset 15:0.
==============
Descriptor No 03
===============:
IDT Descriptor Info:
---------------:
008E0070:042B0008
Offset: 0070:042B
Desc type=TRAP GATE : 02
Rx07-06: 0070 - Offset 31:16
Rx05[7]: 01 - Present bit: (0: not present, 1: present):
Rx05[6:5]: 00 - DPL(desc.priv.lvl)
Rx05[4:0]: 0E - Descriptor type (Task/Int/Trap:00101b/0D110/0D111)
Rx04[7:5]: 00 - 000 (must be zero).
Rx04[4:0]: 00 - Reserved.
Rx03-02: 0008 - segment selector.
Rx01-00: 042B - Offset 15:0.
update on this post: 1/2/16
yesterday i made lot of overhauling in the code and found mainly two places it is causing a reset:
once stack is loaded with pmode specific values
once LIDT is executed.
Made switch variable to turn both or either off and of either of them are turned on, system will reset. Still looking.
Re: final piece of work finished and entered pmode with INT
Posted: Wed Jan 06, 2016 11:38 pm
by ggodw000
There was bug i found that when translating IVT address (SEG:OFF) to IDT 0:32 address, the conversation did not take place and IDT adddress still remained at SEG:OFF format due to macro bug which i used to translate. After fix, i went ahead and enabled the 2 sections of code: preparing stack segment descriptor and loading SS:SP with this segment, IDT preparation and loading (LIDT). It looks like it is working. But not going to get excited too early (as it happened to me in the past
) For the rest of today, I am going to do more checks to make sure it is really working.