Page 1 of 1

Keyboard Driver - Keymap problem

Posted: Fri May 30, 2014 6:22 pm
by DaeFennek
Hi,

I'm working on a basic keyboard driver for my small 32 bit kernel (working GDT, IDT)
Now I have a problem with my keyboard ASCII array.

if I declare my key array the following way:

Code: Select all

static unsigned char keymap[128] =  { /* keys*/ };
or

Code: Select all

const unsigned char keymap[128] =  { /* keys*/ };
then the corresponding key will be printed out correctly to the console. But if I try to define the array without "static" or "const" then no chars will be printed.

I checked .o file with objdump and with "static" or "const" the variable will be moved to the .rodata section. Without "static" or "const" it will moved to the .data section.

So is there a problem with my .data section?

linker:

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(RealMode)
entryPoint = 0x00008000;
SECTIONS
{
  .text entryPoint : {
    *(.text)
  }
  .rodata : {
	*(.rodata)
  }
  .data : {
    *(.data)
  }
  .bss :  { 					
    *(.bss)
  }
}

Re: Keyboard Driver - Keymap problem

Posted: Fri May 30, 2014 9:08 pm
by alexfru
Is that array local to a function? If it is, it will reside on the stack if it's not static and likely if it's not const. And if it's initialized via

Code: Select all

= {/*initializer list*/}
the compiler must generate a bit of code to copy the constant initializers from .rodata (or wherever) to where the array ends up on the stack. One possible problem here is that DS doesn't match SS and the copy goes to the wrong location. Are your segments and the stack properly set up? Can you see in the compiler's output the code that does the copy and the initializers?

Re: Keyboard Driver - Keymap problem

Posted: Sat May 31, 2014 9:20 am
by DaeFennek
No, the array is a global variable in a .c file.
If I move the entire array to a function then it works fine even without "static" or "const"

Code: Select all

unsigned char FetchAndAnalyzeScancode()
{

	unsigned char keymap[128] = { /* keys */};
   // print char works fine ..

}

I found another strange behavior in my second stage bootloader. After I jumped to protected mode I print a small debug message (stored in .text section) to screen, clear the screen and jump to the C main function. That's works very well. But now I tried to move the debug message to .data section. After that nothing will be printed to the screen.
If I change the bootloader that the C main fuction won't be called again everything works well.

Works -> entire C main wasn't linked in the kernel:

Code: Select all

section .text
[BITS 32]
;[extern main] ; c main

ProtectedMode:
	
	.main:	
		mov ax, 0x10
		mov ds, ax
		mov ss, ax 
		mov es, ax
		xor eax, eax
		mov fs, ax
		mov gs, ax
		mov esp, 0x200000 ; set stack below 2 MB limit
				
		call clrscr_32

		mov esi, runningProtectedMode
		call PutStr_32 ; <-- Print debug message - works
		; dont jump to c main
		;call main 
		jmp $		

PutStr_32:      
    mov edi, [PutStr_Ptr]
.nextchar:
    lodsb
    test al, al          
    jz .end      
    stosw
    jmp .nextchar  
  .end:
    mov [PutStr_Ptr], edi
    ret 

clrscr_32:
    mov edi, 0xb8000
    mov [PutStr_Ptr], edi
    mov ecx, 40 * 25
    mov eax, 0x07200720 ; two times: 0x07 => white text & black background 0x20 => Space
    rep stosd
    ret

section .data
PutStr_Ptr dd 0xb8000
runningProtectedMode db "Running in 32 Bit ..", 0 ; <-- Debug Message 
won't work -> entire C main linked in the kernel:

Code: Select all

section .text
[BITS 32]
;[extern main] ; c main

ProtectedMode:
	
	.main:	
		mov ax, 0x10
		mov ds, ax
		mov ss, ax 
		mov es, ax
		xor eax, eax
		mov fs, ax
		mov gs, ax
		mov esp, 0x200000 ; set stack below 2 MB limit
				
		call clrscr_32

		mov esi, runningProtectedMode
		call PutStr_32 <-- print debug message - won't work
		; jump to c main
		call main 
		jmp $		

PutStr_32:      
    mov edi, [PutStr_Ptr]
.nextchar:
    lodsb
    test al, al          
    jz .end      
    stosw
    jmp .nextchar  
  .end:
    mov [PutStr_Ptr], edi
    ret 

clrscr_32:
    mov edi, 0xb8000
    mov [PutStr_Ptr], edi
    mov ecx, 40 * 25
    mov eax, 0x07200720 ; two times: 0x07 => white text & black background 0x20 => Space
    rep stosd
    ret

section .data
PutStr_Ptr dd 0xb8000
runningProtectedMode db "Running in 32 Bit ..", 0 ; <-- Debug Message 
Therefore I think there is a problem in my linker script :(

Re: Keyboard Driver - Keymap problem

Posted: Sun Jun 01, 2014 12:01 pm
by DaeFennek
I solved the problem.
In my stage 1 bootloader I only read 10 sectors, but my kernel is 5,68 KB big. So in the end, the entire .data section wasn't written into memory.