Beginner Problem with executing functions

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.
Post Reply
User avatar
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

Beginner Problem with executing functions

Post by Ameise »

Having an odd problem - haven't done a disassembly yet because I'm simply not good at it, but if I must then I will.

Basically, if I do this, it works fine:

Code: Select all

static char * sVideoAddress = 0x000b8000;

__declspec(noreturn)
	void kernel::boot::kloader (multiboot::multiboot_info *multibootheader, unsigned long signature)
{
	char *addr = (char*)sVideoAddress;
	for (int i = 0; i < 80 * 25 * 2; ++i)
		*addr++ = 0;

	__asm { hlt }
}
If I do this, it fails (no rendering done):

Code: Select all

static char * sVideoAddress = 0x000b8000;

void * memset (void *dst, int val, int len)
{
	char *dest = (char*)dst;
	for (int i = 0; i < len; ++i)
		*dest++ = val;
	return dst;
}

void cls ()
{
	memset(sVideoAddress, 0, 80 * 25 * 2);
}

__declspec(noreturn)
	void kernel::boot::kloader (multiboot::multiboot_info *multibootheader, unsigned long signature)
{
	cls();
}
Any thoughts as to why? This is a PE binary with a multiboot header.
Last edited by Ameise on Fri Jul 16, 2010 11:21 am, edited 1 time in total.
User avatar
blobmiester
Member
Member
Posts: 45
Joined: Fri Jul 16, 2010 9:49 am

Re: Beginner Problem with executing functions

Post by blobmiester »

First off, you need to be a bit more specific when asking questions:
  • Is that all the code?
  • Is there another loader that gets called first? Are you setting up in the stack in this loader (if not you need to be)?
  • What compiler are you using (though I think I can tell it's Visual C++, the less the person responding needs to think about it - the more likely they are to answer)?
Now, to answer your question: I don't have any clue as to why simply adding two functions in the source file (that aren't being called) would fail (another thing, how does it fail? Any helpful error messages?).

The only thing I can suggest is have you read the wiki on Visual C++? There are a ton of settings that need to be changed in order for a kernel to be loaded right.

One last thing: How are you booting your kernel? Custom, grub, ... ?
User avatar
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

Re: Beginner Problem with executing functions

Post by Ameise »

My computer isn't with me, so I can't post source, but I will when I get home.

There is a true entry point that starts with the multiboot loader (same as any tutorial). There are other source files that ARE compiled, but they aren't referenced and just take up code space.

Visual Studio 2010 / C++ would be the compiler that I'm using, and the project SHOULD be set up properly. By failing, it doesn't clear the screen. Can't tell if it's actually died or not... it doesn't clear the GRUB screen, I continuously see 'Starting Kernel' or so.

The stack appears to be set up, as it is in one of the tutorials,

Code: Select all

__declspec(naked) void __multiboot_entry__(void)
{
          __asm {
          
          multiboot_header:
                    dd(0x1BADB002)               ; magic
                    dd(1 << 16)                    ; flags
                    dd(-(0x1BADB002 + (1 << 16)))     ; checksum
                    dd(0x00101000)               ; header_addr
                    dd(0x00101000)               ; load_addr
                    dd(0x0010200F)               ; load_end_addr
                    dd(0x0010200F)               ; bss_end_addr
                    dd(0x00101030)               ; entry_addr
                    dd(0x00000000)               ; mode_type
                    dd(0x00000000)               ; width
                    dd(0x00000000)               ; height
                    dd(0x00000000)               ; depth

          kernel_entry:
                    mov     esp,     KERNEL_STACK

                    xor     ecx,     ecx
                    push     ecx
                    popf

                    push     eax
                    push     ebx
                    call     kernel::boot::kloader

                    jmp     $
          }
}
is fairly equivalent to my header.


An odd thing to note is that other times, when I had fewer/different functions in my source files, it would work, even calling functions. Then I add one more function, and it fails. The file itself, compiled, is 12KiB.


I also made a mistake on the code above... second block should be

Code: Select all

static char * sVideoAddress = 0x000b8000;

void * memset (void *dst, int val, int len)
{
	char *dest = (char*)dst;
	for (int i = 0; i < len; ++i)
		*dest++ = val;
	return dst;
}

void cls ()
{
	memset(sVideoAddress, 0, 80 * 25 * 2);
}

__declspec(noreturn)
	void kernel::boot::kloader (multiboot::multiboot_info *multibootheader, unsigned long signature)
{
	cls();
}
I left out the cls() call. And if I put the clearing loop after cls(), it still fails.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Beginner Problem with executing functions

Post by neon »

Hello,

Your multiboot header structure looks weird. header address is same as load address; entry point hard coded; adding additional functions can move these addresses around. I am not aware of what tutorial you used but this doesnt look right.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

Re: Beginner Problem with executing functions

Post by Ameise »

User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Beginner Problem with executing functions

Post by neon »

Hello,

May I suggest trying the method outlined in this thread? I use a variant of this method and never ran into issues.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

Re: Beginner Problem with executing functions

Post by Ameise »

What guarantees that it will be at the beginning of the .text segment, and some other variable won't be put before it?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Beginner Problem with executing functions

Post by neon »

Hello,

Its a little tricky. You should know how section naming works in MSVC to better understand how it works. The section name (.a$0) is what guarantees that its before .text, please see the 6th post for info.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Fanael
Member
Member
Posts: 38
Joined: Fri Oct 16, 2009 9:20 am

Re: Beginner Problem with executing functions

Post by Fanael »

You can also place the multiboot header inside MZ header, it's toolchain-independent (but somewhat hackish instead ;)) and works fine (at least for me ;)).

Sorry for self-advertisement ;)
Post Reply