Size limit???

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Size limit???

Post by LordMage »

I have been trying to get paging working but I am having a problem that i think is outside of that problem. I have noticed in the past and now that anytime my kernel gets larger than 12k, even 12.5k I run into problems. the second stage bootloader just doesn't seem to load the kernel when it is that big. I will gladly post my code if I need to, but has anyone else had that problem?? Any suggestions?
Getting back in the game.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

What bootloader are you using? Perhaps it's only allocating 3 pages for the .text section?
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

Paging isn't enabled in the bootloader, but the bootloader is from www.brokenthorn.com neon's OS development tutorial. It uses NASM for compiling
Getting back in the game.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

Hey,

If possible, would you mind uploading the Kernel image (*.dll); PMing or e-mailing it to me? If so, I can test it, and see what the problem may be.

Is it crashing at the loading of the kernel, or executing the kernel?

In MSVC++, you may need to explicately state what function to link to at the entry point address to insure it will be executed correctly. I have not explained this in the tutorial (It is planned on the next revision though.) If you have not, I can show you it here ;)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

I am to the point where I want to start using paging, I can load the kernel image and install irqs and my exceptions are working. So as far as I can tell the actual loading of the kernel and operation of the kernel works just fine, but if I try to load paging my kernel size goes from 11.5k to 12.5k and that is my limit. I have tested this to make sure the problem is not related to my attempt at paging, I can remove my keyboard controller and the size drops to 10.5k and then the kernel loads and operates just fine up to the paging portion since this isn't working yet I either get a page not present from bochs or my exception handling gives me a GPF or double exception. Not sure why my exception handling doesn't tell me when there is a page fault other than if paging is doing what I think it is then my kernel doesn't know where it is. I am not worried about the paging so much as I am about the GPF that fires at the end of my stage2 bootloader when my kernel is larger than 12k, so like 12.5k it is setup on a 512 boundary. I have disabled the cr3 and cr0 operations of my paging to show that that is not the problem. I have also included 2 copies of the kernel. hoskrn.sys is the nonfunctioning one that I think stops at the jmp call to start reading the instructions inside the file, the second is a working copy of the same kernel with just the keyboard interrupt taken out since this drops the size down low enough for it to work.

EDIT: After further investigation, VMWare calls my oversize problem a stack fault error. VirtualPC just says invalid bootdisk or media at somepoint during the file load. VPC doesn't actually get to the blue screen I have in place after the kernel is loaded it stops as far as I can tell during file load. and VMWare looks like it stops mid screen wipe. don't know if that helps but there it is
Attachments
kernel.zip
both files are in there. then one with (2) works with neons bootloader, the other one doesn't
(9.34 KiB) Downloaded 23 times
Getting back in the game.
sigler
Posts: 15
Joined: Wed Oct 31, 2007 11:37 am

Post by sigler »

This is probably not the reason (I bring it up is because you say the problem occurs when the size of the kernel grows), but if you read from floppy, you cannot read across a 64k boundary. That is, if you place the kernel at memory address 63K, you cannot ask the floppy to load 2K, you must ask it for 1K twice instead.

--
Sigurd Lerstad
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

Well, I was goofing off with the project properties and changed some settings I didn't understand and now if the kernel is 12.5k it has the same old error, but if the kernel is 13k it does not have an error??? I am fairly confused about this but I am hoping for the moment that the problem only exists at the 12.5k boundary. I am going to try to move on from here but any solution to the original problem would be welcome.

EDIT: problem exists right after the 13k spot too, 13.5 and 14 are screwed. the error from bochs looks like this

Code: Select all


write_virtual_checks(): no write access to seg

then it shows the dump, CR0 ends is 0x00000011 and all the other CRs are all 0s

CS is 0008
DS is 0010

FS and GS are 07c0

the final bit of asm that shows is:

add byte ptr cs:[eax], al : 2E0000

and it ends with a GPF

any ideas
Getting back in the game.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Do you know how FS and GS are getting set? That value is not a legal segment value, is it? On occasion, all segment registers are checked for validity -- like during an IRET. You'll definitely get a GPF and crash the next time an interrupt is processed, if those values of FS and GS are illegal.
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

nope, I have no idea how they get set. I don't think that they are specifically set during the initial GDT setup. I will check and see about it.

so they should be set just like DS, ES, and the others

EDIT:

I have added them to the stage2 bootloader, no change in performance still errors out. I just wish I knew what the problem was.
Last edited by LordMage on Fri Nov 16, 2007 3:07 pm, edited 1 time in total.
Getting back in the game.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Post by egos »

Code: Select all


CS is 0008
DS is 0010

FS and GS are 07c0

Set up FS and DS with valid values for PM, e.g. FS=GS=0x0010.

Code: Select all


add byte ptr cs:[eax], al : 2E0000

and it ends with a GPF

That's right... for processor, but not for you! This instruction writes into memory and uses cs-prefix, but in PM the code segment is executable and possibly readable, not writable!
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

I with you, I stepped through bochs and what you say makes sense but that code is executed after the jmp to my c++ kernel is called, so how do I fix the problem. I am not really changing anything in the program except for it's size (all of the functions work just fine until the size hits 12.5k) so how can I fix this problem?

I'm using VC++ so maybe there is a setting inside of that I am not aware of, I have tried messing with them though and it is not helping.
Getting back in the game.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

I had this problem with an early kernel and forget what fixed it, but here are some things you *may* not have considered:

1) Look at your linker script. Could one of the other binary segments possibly be overwriting the stack, and ending up running an odd instruction?

2) Objdump your kernel. Are you linking in the correct order? i.e. if you are using a flat binary, the entry point *must* be the first instruction in the binary - sometimes, even when your linker script specifies the entry symbol, odd things happen if your asm stub is not the first file linked. I would suggest using a format such as ELF, where the desired entry point is specified.

3) What is EIP on the failure - can we see the full Bochs register dump? What does eax point to - I bet the instruction mov cs:[eax], al does not appear anywhere in your dissassembly. This implies the large size causes something to overwrite something else.

I'll post other things if I think of them :)

Cheers,
Adam
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Post by egos »

LordMage wrote:so how can I fix this problem?
Perhaps your bootloader not supported "that big" kernels :) Use another.
I'm using VC++ so maybe there is a setting inside of that I am not aware of, I have tried messing with them though and it is not helping.
I'm not using VC++ for osdev. That is why I have full control over my code.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

Hey,
Perhaps your bootloader not supported "that big" kernels :) Use another.
It does. The bootloader completely loads the kernel PE image file off disk--it has been tested and verified to work.

Code: Select all

add byte ptr cs:[eax], al : 2E0000 
This almost always happens if the processor is executing random instructions (For example, a jump to a random location in memory.)

Take your paging code completely out, and test it without paging, keeping the current kernel image size of 11.5KB, and let me know what happens.

Also, please post the log output from Bochs for us all to see. (We only need the output from where the PANIC error is at.)

Also, FS and GS do not HAVE to be set to the data descriptor offset within the gdt. However, directly or indirectly using them when they point to an invalid descriptor will GPF, so I recommend setting them to the data descriptor offset into the gdt (Normally offset 0x10 bytes from start.)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

Here is the stuff from bochs, I removed the paging stuff and it is still happening, if my kernel is around 13k I get the following, if it is around 15k I get a LOCK prefix unallowed.

here is the stuff I get right now.

Code: Select all


00002082069i[BIOS ] Booting from 0000:7C00
00004370024e[CPU0 ] write_virtual_checks(): no write access to seg
00004370024i[CPU0 ] protected mode
00004370024i[CPU0 ] CS.d_b = 32 bit
00004370024i[CPU0 ] SS.d_b = 32 bit
00004370024i[CPU0 ] EFER   = 0x00000000
00004370024i[CPU0 ] | RAX=00000000000001cb  RBX=00000000001000e4
00004370024i[CPU0 ] | RCX=0000000000000006  RDX=0000000000000fff
00004370024i[CPU0 ] | RSP=0000000000090000  RBP=0000000000000010
00004370024i[CPU0 ] | RSI=00000000ffff0898  RDI=0000000000080005
00004370024i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00004370024i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00004370024i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00004370024i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00004370024i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf AF PF CF
00004370024i[CPU0 ] | SEG selector     base    limit G D
00004370024i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00004370024i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00004370024i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00004370024i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00004370024i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00004370024i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00004370024i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00004370024i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00004370024i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00004370024i[CPU0 ] | RIP=0000000000100139 (0000000000100139)
00004370024i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00004370024i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00004370024i[CPU0 ] >> add byte ptr cs:[eax], al : 2E0000
00004370024e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
 status is 00h, resetting
00004370024i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00004370024i[APIC0] local apic in CPU 0 initializing
00004370024e[CPU0 ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=4370024
(0) [0x00100139] 0008:100139 (unk. ctxt): add byte ptr cs:[eax], al ; 2e0000

hope that helps some.
Getting back in the game.
Post Reply