Confused Noob - why is the value not being set?

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
nigelren
Posts: 5
Joined: Thu Nov 29, 2012 4:13 pm

Confused Noob - why is the value not being set?

Post by nigelren »

I haven't really programmed much in C for some time, so I've been using the JamesM's tutorial to try and play with a new kernel. I have changed it to be a 64 bit binary and most things seem to work, except global variables don't seem to be able to retain their value. The simplest test code I came up with is.

Code: Select all

// main.c -- Defines the C-code kernel entry point, calls initialisation routines.
//           Made for JamesM's tutorials <www.jamesmolloy.co.uk>

#include "monitor.h"
#include "multiboot.h"

u8int cursor_x1 = 1;

void temp_write(u16int *videoOut, u32int n)	{

    s32int tmp;
    char noZeroes = 1;
    int i;
    for (i = 28; i > 0; i -= 4)
    {
        tmp = (n >> i) & 0xF;
        if (!tmp && noZeroes)
        {
            continue;
        }

        if (tmp >= 0xA)
        {
            noZeroes = 0;
            *videoOut++ = (tmp-0xA+'a') + (0x1e<<8);
        }
        else
        {
            noZeroes = 0;
            *videoOut++ = (tmp+'0') + (0x1e<<8);
        }
    }

    tmp = n & 0xF;
    if (tmp >= 0xA)
    {
    	*videoOut++ = (tmp-0xA+'a') + (0x1e<<8);
    }
    else
    {
    	*videoOut++ = (tmp+'0') + (0x1e<<8);
    }
}

int main(struct multiboot_info *mboot_ptr)
{
	temp_write((u16int *)0xB8000+400, cursor_x1++);
	temp_write((u16int *)0xB8000+420, cursor_x1++);
   return 0;
}

The problem I have is that cursor_x1 always comes out as 0. However if I make it a local variable, it works OK. I'm really confused as to what I'm doing and would appreciate it if anyone can point to what I'm doing wrong.

I'm compiling with Eclipse and it uses...
gcc -I/usr/src/linux-headers-3.2.0-33 -O0 -g3 -Wall -c -fmessage-length=0 -ffreestanding -m64 -nostdlib -mno-red-zone -Map=out.map -MMD -MP -MF"srcOriginal/main.d" -MT"srcOriginal/main.d" -o "srcOriginal/main.o" "../srcOriginal/

The link script is

Code: Select all

ENTRY(start)
SECTIONS
{

    .text 0x100000 :
    {
        code = .; _code = .; __code = .;
        *(.text)
        . = ALIGN(4096);
    }

    .data :
    {
        data = .; _data = .; __data = .;
        *(.data)
        *(.rodata)
        . = ALIGN(4096);
    }

    .bss :
    {
        bss = .; _bss = .; __bss = .;
        *(.bss)
        . = ALIGN(4096);
    }

    end = .; _end = .; __end = .;
}
If there is anything else that would be useful, I can easily add it.

Thanks!
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: Confused Noob - why is the value not being set?

Post by dozniak »

You're not handling the case

Code: Select all

tmp = (n >> 0) & 0xF;
Learn to read.
nigelren
Posts: 5
Joined: Thu Nov 29, 2012 4:13 pm

Re: Confused Noob - why is the value not being set?

Post by nigelren »

I've stripped the code down even further to avoid anything else potentially interfering.

Code: Select all

// main.c -- Defines the C-code kernel entry point, calls initialisation routines.
//           Made for JamesM's tutorials <www.jamesmolloy.co.uk>

#include "monitor.h"
#include "multiboot.h"
//#include "console.h"

u8int cursor_x1 = 1;

int main(struct multiboot_info *mboot_ptr)
{
        // u8int cursor_x1 = 1;  // It works if I use this variable instead

	u16int *video = (u16int *)0xB8000;
	video[0] = (cursor_x1+'0') + (0x1e << 8);
	cursor_x1++;
	video = (u16int *)0xB8000+80;
	video[0] = (cursor_x1+'0') + (0x1e << 8);

   return 0;
}

This still only displays the value as being 0 and 0.
If I put the declaration of cursor_x1 as a local variable for main - it displays 1 & 2 - which shows the display is working correctly.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Confused Noob - why is the value not being set?

Post by bluemoon »

objdump and see what's the actual code for "global variable version" and where it want to access.
video[0] = (cursor_x1+'0') + (0x1e << 8);
Note the datatype remain as uint8_t on the RHS, a sane compiler should generate an overflow warning.
gcc -I/usr/src/linux-headers-3.2.0-33 ...
By the way, this is not a good idea to drag the monster into your OS, you never know if it feel like injecting any static object to your kernel.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Confused Noob - why is the value not being set?

Post by Gigasoft »

video[0] = (cursor_x1+'0') + (0x1e << 8) ;
Note the datatype remain as uint8_t on the RHS, a sane compiler should generate an overflow warning.
No, '0' is an int, so cursor_x1 is promoted to int. 0x1e and 8 are also ints. The result of the calculation is an int ranging from 0x1e30 to 0x1f2f, so there can't be an overflow. Or if this was C++, we would have an int ranging from 0x1e00 to 0x1eff.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Confused Noob - why is the value not being set?

Post by bluemoon »

or it can be promoted to unsigned int and give you surprise, anyway that is not a cool coding style.
nigelren
Posts: 5
Joined: Thu Nov 29, 2012 4:13 pm

Re: Confused Noob - why is the value not being set?

Post by nigelren »

I managed to find that it was loading the .data section at 101000, and the hex dump looked 'right' ( i.e. the values I was expecting to see - were there ).
I still couldn't get the values to work - and it all seems to do with being a 64bit executable. I've changed back to 32 bit and it all seems to work OK.
I'm using grub2 to load the executable - is there an example set of code somewhere which I can read through to work out what I might be doing wrong.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Confused Noob - why is the value not being set?

Post by Combuster »

I suggest you compile yourself a copy of bochs+debugger, and go single step through the code to see what the effective differences are.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply