Page 1 of 1
kernel working on some emulators only
Posted: Thu Oct 13, 2005 11:00 pm
by CyberP1708
First, hello, this is my first post here !
So, this is my problem (I hope you will find a solution because I didn't) :
my os is working with bochs, vmware, but not with microsoft virtual pc nor in real.
Well, it doesn't really work with vmware as it tells me that I am using some floppy functions not implemented in it (he didn't tell me that at the begining of the project but it was still not working in real at the begining).
With "jmp $" instructions placed a bit everywhere, I discovered that the error (with microsoft virtual pc there is an error message box and in real it just reboots) is after calling a function (more generally, using a "call" opcode).
I checked out what was happening here but there is nothing that could cause such a problem. The only thing that could go wrong is that the kernel could not be loaded at the good address, but I'm using a bios interruption so there shouldn't be any bug.
(sorry for my bad english, I'm trying to do my best)
Re: kernel working on some emulators only
Posted: Thu Oct 13, 2005 11:00 pm
by dave
Firstly, your code would be helpful in diagnosing the problem
Secondly, if your code is not working on a real pc then this means you are definitely doing something incorrect. Trust the real pc over all the emulators as certain things don't work on emulators but work on a pc and vice versa.
Dave
Re: kernel working on some emulators only
Posted: Thu Oct 13, 2005 11:00 pm
by CyberP1708
Well, the kernel is written in C. Here is something I was testing :
That's my main function (called by the bootloader)
Code: Select all
void main() {
// system
gdt_initialisate();
idt_initialisate();
exceptions_initialisate();
drivers_initialisate();
irq_initialisate();
// main drivers
display_text_initialisate();
keyboard_initialisate();
// other drivers
buzzer_initialisate();
floppy_initialisate();
mouse_initialisate();
time_initialisate();
// last drivers to be loaded
//processes_initialisate();
shell_start();
_asm { cli }
_asm { hlt }
}
If I put "jmp $" just at the beginning of the function, it works (everything stops but at least it doesn't crash).
That's the first called function :
Code: Select all
void gdt_initialisate() {
_asm { jmp $ }
gdt_table[0].hlimit = 0; gdt_table[0].hlbase = 0; gdt_table[0].lbase = 0;
gdt_table[0].type_llimit = 0; gdt_table[0].hbase = 0;
gdt_modify(1, 0x0, 0xFFFFF, gdt_present + gdt_not_system + gdt_code_segment + gdt_read_writable + gdt_great_limit + gdt_32_bits + gdt_dpl0);
gdt_modify(2, 0x0, 0xFFFFF, gdt_present + gdt_not_system + gdt_data_segment + gdt_read_writable + gdt_great_limit + gdt_32_bits + gdt_dpl0);
gdt_modify(3, 0x0, 0xFFFFF, gdt_present + gdt_not_system + gdt_code_segment + gdt_read_writable + gdt_great_limit + gdt_32_bits + gdt_dpl3);
gdt_descriptor.limit = 8 * gdt_size;
gdt_descriptor.base = (u32)((void*)&gdt_table);
_asm {
lgdt [gdt_descriptor]
mov ax, 16
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
}
}
Here it crashes even if I put the "jmp $" so the crash is just when the CPU is trying to jump to the function.
I am compiling this with Visual C++ (with the configuration given by mega-tokyo.com's giant faq which has stopped working since yesturday)
Should I try another compiler ? I disassembled the binary but everything seems correct (it just does a short call and then there is directly the "jmp $" because I tested it with "void _declspec(naked) gdt_initialisate()" which removes everything added by the compilation)
I tried to push something at the beginning of the main function (and put "jmp $" just after) and it works... so... I have no idea of what could cause this (else I wouldn't post this here)
Re: kernel working on some emulators only
Posted: Thu Oct 13, 2005 11:00 pm
by dave
A few of reasons I could see the cpu faulting is:
1. Do you have your setup your stack properly. If it is not call a function will lead to all kinds of problems
2. Loading the GDT via C is asking for trouble. If the slightest thing is wrong with your GDT the cpu will more then likely triple fault leaving you with nothing to go. Since different C compilers have differenct values for char, int , long, etc. It really is better to try and keep this to assembly.
3. Your kernel may not be linked correctly. This would cause problems with variables and may be even code locations not being correct ( although code being incorrect is probably unlikely since they all should be near jumps at this point, I hope ).
Hopefully this will help you find your problem most likely it is number 2 or 3
Dave
Re: kernel working on some emulators only
Posted: Thu Oct 13, 2005 11:00 pm
by CyberP1708
Ok thank you very much
First I am going to change my compiler as with PE I am going to have some problems (Visual C++ only compilates in PE which is window's format with a header, different segments, etc.)
This may also correct bugs caused by your number 3 (I am going to use ld just like everybody does)
And if it still doesn't work I will make my GDT creation in assembly. But I think there aren't problems with this because I have been trying to change DPL and it was working.
Re: kernel working on some emulators only
Posted: Sat Oct 15, 2005 11:00 pm
by CyberP1708
So it still doesn't work...
Well it's very strange... if I call an empty function (in C) it doesn't work, but if I disassemble, copy its content to an other function (in asm) and call it, then it works !
If someone has an idea...
here is my code (start is the kernel entry point which is situated at the entry of the file) :
Code: Select all
start:
call start2 ; if I put _kernel_start here, the kernel crashes
jmp $
start2:
nop
nop
nop
nop
nop
push ebp
mov ebp, esp
pop ebp
ret
And here is the rest:
If I disassemble the "kernel_start" function, I see the content of my "start2" function (I also checked if it was the same in hexadecimal and it is)
Re: kernel working on some emulators only
Posted: Sat Oct 15, 2005 11:00 pm
by dave
It sounds like you haven't setup your stack properly. As "call" pushes the return address onto the stack.
Are you in protected mode when your C code starts?
Is your asm code in protected mode or real mode?
Re: kernel working on some emulators only
Posted: Sat Oct 15, 2005 11:00 pm
by CyberP1708
I'm in protected mode in the whole kernel (including the asm file)
But it doesn't explain why it doesn't crash when I put "call start2"
I'll try to see if the entire kernel is loaded in memory (because the only difference between start2 and kernel_start is their position in the memory)
Re: kernel working on some emulators only
Posted: Sat Oct 15, 2005 11:00 pm
by CyberP1708
Well I think I have discovered the problem
Here is my modified code:
Code: Select all
start:
mov eax, [_kernel_start]
add eax, '0'
mov [0xB8000], al
mov byte [0xB8001], 0x7
shr eax, 8
add eax, '0'
mov [0xB8002], al
mov byte [0xB8003], 0x7
shr eax, 8
add eax, '0'
mov [0xB8004], al
mov byte [0xB8005], 0x7
shr eax, 8
add eax, '0'
mov [0xB8006], al
mov byte [0xB8007], 0x7
;call _kernel_start
jmp $
which is telling what is written on the offset of the "kernel_start" function
And guess what: with bochs, everything is ok, with a real pc, it tells me "0000"
This proves that the kernel is not entirely loaded (but I don't know why)
Re: kernel working on some emulators only
Posted: Fri Oct 21, 2005 11:00 pm
by earlz
if you wrote your own bootloader make sure to change cylinders if your kernels greater than 18 sectors as it wont read more than 18 in one int
Re: kernel working on some emulators only
Posted: Sat Oct 22, 2005 11:00 pm
by CyberP1708
well I though it was able to read more...
it doesn't matter as I am going to separate the kernel from the drivers, so it will probably be less than 9 kB at the end
thank you