Page 1 of 1

.rodata trouble

Posted: Sun Mar 21, 2010 11:39 am
by aout
Hi,

I'm currently in trouble with my bootloader stage 2.

What is hapenning:

on stage 2 I setup A20 and GDT, load the kernel (binary image) to address 0x3000 (RM addressing)

and later I copy the kernel image from 0x3000 to 0x10000 (PM addressing) and finally I pass the control to the flat kernel code on 0x10000 (eg: call 0x8:0x10000, the "kernel loader")

this kernel loader (in assembly) setups the DATA SEGMENT and stack to 0x90000 and calls the c function kmain(). On kmain() I call some function to print informations on the screen but when I explicit pass the string to the function (constant probably in rodata) [kinfo(0,0,"fooinfo")] it's doesn't works, but when I set the string to some char [] and pass the (char *) [kinfo(0,0,msg)] it works.

On my ld script I joined the rodata on text section,

something like:

...
SECTION
{
. = 0x100000;
.text : {
*(.text)
*(.rodata)
}
}
...

What's I'm forgetting? What's wrong?! Somebody can help me?

Thanks

Re: .rodata trouble

Posted: Mon Mar 22, 2010 2:56 am
by qw
Perhaps the section is called ".rdata" instead of ".rodata"? You should check where the string is actually stored.

Re: .rodata trouble

Posted: Mon Mar 22, 2010 3:29 am
by Solar
aout wrote:...constant probably in rodata...
DNA - do not assume. Or at least, check your assumptions. Use objdump (or a similar tool) to verify if the string is in the object file, and in which section. Then check if the string is in the resulting binary, and in which section. Chances are you nailed that bug by that time already.

Re: .rodata trouble

Posted: Mon Mar 22, 2010 7:22 am
by aout
No, it's named "rodata" because I'm using gcc. I already compile with option -S and the asm code generated shows the string in ".rodata", so...

And now I'm telling to the linker by the script to put rodata with text in same section. If it was problem, by null hypothesis, should be solved, no?

Something points to rodata problem 'cause I done what Solar suggested in another thread: I wrote some function to only put a single char on the screen and it works, so I put *(rodata*) inside text section -> text : AT(0x00100000) { *(text) (*rodata) }
Physically the string is there on the generated image. But the updated linker script don't solves the problem.

After some tries (totally empirc tries :P) I got a single "S" on top of the screen (with the string printer function), but nothing about my string.

I assumed use elf instead of binary but the problem remains and more bizarre is that I don't need to parse the elf, I just load and call from the start point (probably "ELF ") and my screen is cleared (by my clear function, without assumed, if I commented it, the screen stays "dirty") but the string isn't shown.

I think at least in elf I need to points to address entry (relative offset 24 from start point where the data was loading, no?)

could be bochs screwing up my string? due to some misconfiguration?

Thanks again!

Re: .rodata trouble

Posted: Tue Mar 23, 2010 10:12 pm
by aout
Hello,

I was read elf with readelf and the string passed on (k_echo("foo")) is on .data and instead of in .text section, look my link script:

OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
INPUT(kld.o main.o pvideo.o)
phys = 0x00100000;

SECTIONS {

.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata*)
}

.data : AT(phys + (data - code))
{
data = .;
*(.data)
}

.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
}

end = .;

}

I was replaced "*(.rodata*)" by "(.rodata)" and still don't works...

it's weird!

Re: .rodata trouble

Posted: Tue Mar 23, 2010 10:22 pm
by aout
I forgot, I'm using this options on GCC:

-O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -fwritable-strings -c -o

Re: .rodata trouble

Posted: Wed Mar 24, 2010 12:49 am
by xenos
aout wrote:-O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -fwritable-strings -c -o
The -fwritable-strings causes strings to be placed in .data rather than in .rodata, since .rodata is a read only section while .data is writeable.

Re: .rodata trouble

Posted: Wed Mar 24, 2010 1:27 am
by Solar
-fwritable-strings is not standard compliant, and no longer supported in GCC 4.*. I think you should alter your code accordingly...

Re: .rodata trouble

Posted: Wed Mar 24, 2010 6:21 am
by aout
#-o Ok, I will do this.

Thanks!

Re: .rodata trouble

Posted: Wed Mar 24, 2010 9:51 pm
by aout
It don't works, now "readelf -x n elf" is show me the .rodata inside text section, but it don't has effect...

Even with: nasm -f aout loader.s, or nasm -f elf loader.s

Re: .rodata trouble

Posted: Thu Mar 25, 2010 1:47 am
by Combuster
Your offsets might be skewed, which means that code works (relative addresses), but not data (absolute addresses). Did you check that you are parsing the kernel correctly (especially since it appears to be an ELF file)

Re: .rodata trouble

Posted: Thu Mar 25, 2010 3:19 pm
by aout
I will check my code, but even with a kernel binary image it don't works...

Thanks!

Re: .rodata trouble

Posted: Thu Mar 25, 2010 9:39 pm
by aout
I checked the code and the kernel copy from real address to protected address
is not correct.

If I remove the copy instructions the kernel still is (partially) loaded.

the code:

Code: Select all

SECTOR: db 0
HEAD: db 0
TRACK: db 0

___s_lba2chs: ; lba em ax
    xor dx, dx
    push bx
    mov bx, 18 ; floppy sectors per track
    div word bx
    inc dl
    mov byte [SECTOR], dl
    xor dx, dx
    mov bx, 2 ; floppy heads per cilynder
    div word bx
    mov byte [HEAD], dl
    mov byte [TRACK], al
    pop bx
    ret

(...)

%define KERNEL_LOCATION 0x3000
%define KERNEL_LOCATION_PM 0x10000
%define KERNEL_CHUNKS_SIZE 512
%define KERNEL_CHUNKS_NR 1;21
 
my disk layout: (bootstrapping[512b]|stage1[this code, 1024b]|kernel[512b])

(...)

___s_lv1_read_kernel_image: ; reads n sectors from disk at ES:BX (OFFSET:BASE)
	mov dl, 0x00 ; drive number
	call ___s_lba2chs	
	push cx
	inc ax
	mov dh, [HEAD] ; headr nr
	mov ch, [TRACK] ; track nr
	mov cl, [SECTOR] ; sector nr
	mov al, 1 ; número de setores à serem lidos
	mov ah, 0x02
	int 0x13	
	jc ___s_lv1_read_kernel_image
	pop cx	
	dec cx
	cmp cx, 0x00
	add bx, 512 ; next 512 byte kernel chunk
	push cx
	mov ecx, PROGRESS ; bogus "."
	call ___s_real_mode_print 
	pop cx
	cmp cx, 0x00
	jne ___s_lv1_read_kernel_image	
	push ecx
	mov ecx, KRNL_LD ; bogus message
	call ___s_real_mode_print
	pop ecx
	ret

load:

	mov ax, KERNEL_LOCATION
	mov es, ax
	mov bx, 0x0000
	mov cx, KERNEL_CHUNKS_NR
	mov ax, 0x0003
	call ___s_lv1_read_kernel_image

(...)
	
now's the copy (gdt configured, pmode active, 32 bit code reached by jmp code_desc:___lv2):

bits 32
___lv2:

	mov ax, DATA_DESC ; 0x10
	mov ds, ax
	mov ss, ax
	mov es, ax	           
	mov esp, 0x90000
	
	;
	; kernel image copy from rm to
	;
	
	mov eax, KERNEL_CHUNKS_SIZE
	mov dx, KERNEL_CHUNKS_NR
	movzx ebx, dx
	mul ebx
	mov ebx, 4
	div ebx
	cld
	xor bx, bx
	mov dx, DATA_DESC
	mov esi, KERNEL_LOCATION
	mov edi, KERNEL_LOCATION_PM
	mov ecx, eax
	rep movsd

	cli
	call CODE_DESC:KERNEL_LOCATION_PM ; code_desc -> 0x08

By tests there's some errors but I'm not getting notice this.


Some suggestions?