Linker issues

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
balthasar
Member
Member
Posts: 30
Joined: Mon Mar 31, 2008 8:39 pm
Contact:

Linker issues

Post by balthasar »

Im having issues linking after my VESA mode swicher using real mode was added

heres the link.ld file

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 = .;
}
heres vesa.s (The VESA Mode Swicher as well as the unreal mode swichers)

Code: Select all

; Diclonius VESA Mode Swicher
[GLOBAL _set_vesa]

[SECTION .vesa]
; set_vesa: C-Prototype: void set_vesa ();

[BITS 32]

_set_vesa:
	
	sgdt	[saved_gdt]
	sidt	[saved_idt]

	mov	[saved_esp], esp
	
	lgdt  [gdtr]			       ; Load the GDT descriptor

	cli
    
	jmp 	RM_Code_Sel:pmode_16bit

[BITS 16]	 
pmode_16bit:
	
	mov 	ax,RM_Data_Sel
	mov 	ss,ax
	mov	ds,ax

	;lidt 	[ridtr]

	mov 	eax, cr0
  	and  	al,0xfe
	mov	cr0, eax

 	mov   sp,0xFFFE

    mov   bx,[RealModeCS]
	push  bx
	lea   bx,[do_rm]
	push  bx

	retf

do_rm:

	mov	ax,cs
	mov 	ds,ax
	mov 	ss,ax
	nop
	mov 	es,ax
	mov 	fs,ax
	mov 	gs,ax

	lidt 	[ridtr]

	sti

	mov	ax,0x700		;put struct to 0x7000
	mov	es,ax
	mov	di,0x0		;Put to 0x7000 with offset 0x0
	mov	eax,'VBE2'	;tell VESA-BIOS that we want VBE 2 rather than VBE 1
	mov	[es:di],eax
	mov	ax,0x4F00	;Function to get VBE Controller Information
	int	0x10
	cmp	al,0x4F		;Is Function supported?
	jne	continue_cga
	cmp	ah,0x00		;successful?
	jne	continue_cga

	mov	ax,0x800		;position for VBE Mode Information struct
	mov	es,ax
	mov	ax,0x4F01	;function call for VBE Mode Information
	mov	cx,[0x8200]	;getting VBE Mode number
	mov	di,0x0	
	int	0x10
	cmp	al,0x4F
	jne	continue_cga
	cmp	ah,0x00
	jne	continue_cga
	
	;jmp	continue_cga

	mov 	ax,0x4F02	;loading VBE mode-setting-function
	mov	bx,[0x8200]	;getting VBE Mode number
	or		bx,0x4000	;enable linear Buffering
	int	0x10			;go for it
	jmp 	activate_pm

continue_cga:

activate_pm:
	
	cli
	lgdt	[gdtr]
	mov	eax,cr0
	or		al,0x01
	mov	cr0,eax
	jmp	PM_Code_Sel:do_pm

do_pm:

	mov	ax,0x10
	mov	ds,ax
	mov	es,ax
	mov	fs,ax
	mov	gs,ax
	mov 	ss,ax
	mov	ds,ax

[BITS 32]
	
	mov	esp,[saved_esp]
	
	lidt	[saved_idt]
	lgdt	[saved_gdt]
	

[SECTION .DATA]

ridtr:	 
	dw 0xFFFF		; limit=0xFFFF
	dd 0				; base=0

RealModeCS:
	dw	0x0

gdtr:	
	dw gdt_end-1
	dd gdt

gdt:

	dw	0,0,0,0				;null desrciptor

PM_Code_Sel equ $-gdt
	dw	0xFFFF
	dw	0x0000
	dw	0x9A00
	dw	0x00CF

PM_Data_Sel	equ $-gdt
	dw	0xFFFF
	dw	0x0000
	dw	0x9200
	dw	0x00CF

RM_Code_Sel equ $-gdt
	dw	0xFFFF
	dw	0x0000
	dw	0x9A00
	dw	0x0000

RM_Data_Sel	equ $-gdt
	dw	0xFFFF
	dw 0x0000
	dw 0x9200
	dw 0x0000

gdt_end: 

saved_gdt:
	dw	0
	dd	0

saved_idt:
	dw	0
	dd	0

saved_esp:
	dw	0

saved_gdtr:
	dw	0
And the errors i get on compile (the 1 thing i don't understand in C is linker issues)

Code: Select all

i386-elf-ld -Tlink.ld -o dicloniu.s32 boot.o vesa.o main.o monitor.o common.o descriptor_tables.o isr.o interrupt.o gdt.o timer.o kheap
.o paging.o ordered_array.o fs.o initrd.o task.o process.o serial.o keyboard.o drawing.o syscall.o console.o
vesa.o: In function `pmode_16bit':
vesa.s:(.vesa+0x37): relocation truncated to fit: R_386_16 against `.DATA'
vesa.s:(.vesa+0x3c): relocation truncated to fit: R_386_16 against `.vesa'
vesa.o: In function `do_rm':
vesa.s:(.vesa+0x50): relocation truncated to fit: R_386_16 against `.DATA'
vesa.o: In function `activate_pm':
vesa.s:(.vesa+0xa1): relocation truncated to fit: R_386_16 against `.DATA'
vesa.s:(.vesa+0xac): relocation truncated to fit: R_386_16 against `.vesa'
vesa.o: In function `gdtr':
vesa.s:(.DATA+0x8): relocation truncated to fit: R_386_16 against `.DATA'
make: *** [link] Error 1
My OS: NasuTek Ensemble http://code.google.com/p/ensemble/
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Re: Linker issues

Post by suthers »

I think that only one of your problems is fixable: you need to change 'dw gdt_end-1' into 'dw gdt_end - gdt - 1', that will fixe it, because currently a 32bit value is been stored in 16bits so the linker is truncating it to fit...
You have the same problems with the others, but they are because your vesa switcher is loaded to high in memory, some of the memory locations require 32bits to be stored, again causing truncation issues....
So the best thing to do is to load it lower in memory....
Jules
User avatar
balthasar
Member
Member
Posts: 30
Joined: Mon Mar 31, 2008 8:39 pm
Contact:

Re: Linker issues

Post by balthasar »

Ok so it needs to be loaded in lower memory now how do i do this?

My assembly skills are ... juck :oops:
My OS: NasuTek Ensemble http://code.google.com/p/ensemble/
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Re: Linker issues

Post by suthers »

balthasar wrote:Ok so it needs to be loaded in lower memory now how do i do this?

My assembly skills are ... juck :oops:
Juck? :lol:
It's not a question of using assembly really...
Try assembling this into a single standalone binary, putting it in a separate file to your kernel, then loading it into memory somewhere else....
That would be the best option....
Jules
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Re: Linker issues

Post by inflater »

Simple. To copy your kernel, use

Code: Select all

pushad
mov esi,Where your kernel is loaded (ORG)
mov ecx,Size of your kernel in bytes
mov edi,Where to load to
rep movsb
popad

jmp [edi]
I'm unsure of the last line. Try jmp sys_code:[edi] or

Code: Select all

push dword[sys_code]
push dword[edi]
retf
sys code = CS selector. (Be sure to use this in pmode environment, before the rmode switch.)

But I think it's best to use your boot sector/bootloader to load at lower addresses (0x1000 or such, then don't forget to update your text and code section numbers), like suthers said.

BTW Does your toolchain support 16-bit?

Regards
inflater
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Re: Linker issues

Post by suthers »

But he doesn't want to relocate his whole kernel just to be able to use vesa....
Jules
User avatar
balthasar
Member
Member
Posts: 30
Joined: Mon Mar 31, 2008 8:39 pm
Contact:

Re: Linker issues

Post by balthasar »

suthers wrote:
balthasar wrote:Ok so it needs to be loaded in lower memory now how do i do this?

My assembly skills are ... juck :oops:
Juck? :lol:
It's not a question of using assembly really...
Try assembling this into a single standalone binary, putting it in a separate file to your kernel, then loading it into memory somewhere else....
That would be the best option....
Jules
lol i need to use a spell checker more often :P

anyway is it possible to link it as a standalone binary and use it as a GRUB Module or does that write in high memory?

and do i need a linker script for the standalone binary? and if so how is that one need to be written?
My OS: NasuTek Ensemble http://code.google.com/p/ensemble/
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: Linker issues

Post by Combuster »

The thing you should be aware of with real mode code, is that it executes in real mode addressing, i.e. segment+offset. Code must be below the 1M to be in the allowable range, grub always loads your code above 1M.

So you will have to copy your code, and then you will have to consider whether all the addresses you are using are still valid in that different location and that different addressing scheme.

All instances of 'truncated to fit' indicate that real mode code is accessing something where it can't access in reality. You will either have to move the data in question to where it can be reached, or to explicitly tell the processor to use 32 bit addresses (unreal or protected mode required)
"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