linking files ?

Programming, for all ages and all languages.
Post Reply
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

linking files ?

Post by Sam111 »

Ok , I have been at this for hours.

I am trying to run this code.

load2.asm

Code: Select all


global main
[BITS 32]

jmp main
hello	db	'This is sector 2!',13d,10d,'$' ;Put any data here!


main:
mov ax , 0
mov ds , ax 
mov es , ax

mov ax , 0x1110
mov ss , ax
mov sp , ax


mov ax , 600h       ; clear screen scroll up function
mov bh , 7h         ; white on black background
mov ch , 0h         ;upper line (top)
mov cl , 0h         ;left col (far left)
mov dh , 18h        ;bottom 
mov dl , 4Fh        ;far right
int 10h             ;do the clearing 

; display the string This is sector 2 on the screen
;mov ax , 0
;mov es , ax

mov ah , 13h
mov al , 01h 
mov bh , 0h
mov bl , 0Fh
mov dh , 5h
mov dl , 3h
mov cx , hello
mov bp , cx
mov cx , 16d
int 10h
; loop forever
extern _sound
call _sound

endsss:
jmp endsss

sound.c

Code: Select all


void sound();
static void play_sound(long int) ;
static void nosound();
void beep() ;
unsigned char inb (unsigned short ) ;
void outb (unsigned short , unsigned char ) ;


void sound()
{
int i = 1 ;
while( i == 1 )
{
beep() ;
}

}


 //Play sound using built in speaker
 static void play_sound(long int nFrequence) {
 	long int Div;
 	unsigned char tmp;
 
        //Set the PIT to the desired frequency
 	Div = 1193180 / nFrequence;
 	outb(0x43, 0xb6);
 	outb(0x42, (unsigned char) (Div) );
 	outb(0x42, (unsigned char) (Div >> 8));
 
        //And play the sound using the PC speaker
 	tmp = inb(0x61);
  	if (tmp != (tmp | 3)) {
 		outb(0x61, tmp | 3);
 	}
 }
 
 //make it shutup
 static void nosound() {
 	unsigned char tmp = (inb(0x61) & 0xFC);
 
 	outb(0x61, tmp);
 }
 
 //Make a beep
 void beep() {
 	 play_sound(1000);
 	 //timer_wait(10);
 	 nosound();
          //set_PIT_2(old_frequency);
 }
 
 
unsigned char inb (unsigned short _port)
{
    unsigned char rv;
    __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
    return rv;
}

void outb (unsigned short _port, unsigned char _data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}

everything compiles perfect
and I can link it perfectly to
ld -T link.ld load2.o sound.o -o kernel.bin

but the problem is it is not running correctly.

in my link.ld script

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(main)
phys = 0x00008000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    load2.o (.text);
    sound.o (.text);
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
I have used this load2 to boot before and I physically copied the kernel.bin to the second sector of my floppy as well as having my load2 copied to the first sector with the AA55 at the end.

objdump gives

Code: Select all

load2.o:     file format a.out-i386

Contents of section .text:
 0000 e9140000 00546869 73206973 20736563  .....This is sec
 0010 746f7220 32210d0a 2466b800 008ed88e  tor 2!..$f......
 0020 c066b810 118ed066 89c466b8 0006b707  .f.....f..f.....
 0030 b500b100 b618b24f cd10b413 b001b700  .......O........
 0040 b30fb605 b20366b9 05006689 cd66b910  ......f...f..f..
 0050 00cd10e8 a8ffffff ebfe9090           ............
Contents of section .data:

Contents of section .text:
 0000 55575653 bdb6ffff ffbf4200 0000be42  UWVS......B....B
 0010 000000bb 61000000 b9610000 0089e8e6  ....a....a......
 0020 43b0a989 faeeb004 89f2ee89 daec88c2  C...............
 0030 83ca0338 d0740488 d0e66189 caec83e0  ...8.t....a.....
 0040 fce661b8 01000000 83f80174 d05b5e5f  ..a........t.[^_
 0050 5dc383ec 1868e803 0000e821 000000e4  ]....h.....!....
 0060 6183e0fc e66183c4 1cc38b54 2404ec25  a....a.....T$..%
 0070 ff000000 c3908b54 24048a44 2408eec3  .......T$..D$...
 0080 83ec04b9 dc341200 89ca89c8 c1fa1ff7  .....4..........
 0090 7c240889 c1b0b6e6 4388c8e6 4289c8c1  |$......C...B...
 00a0 e808e642 e46188c2 83ca0338 d0740488  ...B.a.....8.t..
 00b0 d0e66183 c404c390 90909090 90909090  ..a.............
Contents of section .comment:
 00c0 4743433a 2028474e 55292033 2e310000  GCC: (GNU) 3.1..

as well as -h option

Code: Select all


sound.o:     file format coff-go32

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000c0  00000000  00000000  000000b4  2**4
                  CONTENTS, ALLOC, LOAD, CODE
  1 .data         00000000  000000c0  000000c0  00000000  2**4
                  ALLOC, LOAD, DATA
  2 .bss          00000000  000000c0  000000c0  00000000  2**2
                  ALLOC
  3 .comment      00000010  000000c0  000000c0  00000174  2**2
                  CONTENTS, DEBUGGING



load2.o:     file format a.out-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000005c  00000000  00000000  00000020  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .data         00000000  0000005c  0000005c  0000007c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000005c  0000005c  00000000  2**2
                  ALLOC

I just have no clue on why the jmp main is not at address 0000:8000h because if it is then the program that I use on the MBR should boot and jmp to the main.

Basically this is the MBR code

Code: Select all

org 0x7C00
BITS 16
jmp start
greetings	    db	'Greetings and welcome ',13d,10d,'$' 
BOOTLOADER_NAME db 'Nates BootLoader Stage 1' ,13d,10d,'$'
STARTSECTOR     db  2            ;start sector to load
LOADADDRESS     dw  8000h       ; where to load the sectors into memory
NUMBEROFSECTORS db  1           ; number of bytes to load begining at STARTSECTOR

clear_screen:
mov ax , 600h      ; clear screen scroll up function
mov bh , 7h        ; white on black background
mov ch , 0h        ;upper line (top)
mov cl , 0h        ;left col (far left)
mov dh , 18h       ;bottom 
mov dl , 4Fh       ;far right
int 10h  ;                          do the clearing 
ret


readsectors_into_memory:
mov ah , 02h                    ; read function
mov al , 01h ;NUMBEROFSECTORS        ; number  of sectors to read
mov ch , 0h                     ; cylinder number
mov cl , 02h;STARTSECTOR            ; starting sector to begin reading from
mov dh , 0h                     ; head number
mov dl , 00h                    ;drive for floppy
mov bx , 8000h ; LOADADDRESS            ; es:bx-> buffer for where the sectors will be loaded in this case 0000:8000h

int 13h                          ; execute the interrupt for reading into memory
ret


start:
mov ax , 0x9100 ;set the stack to some random address
mov ss , ax
mov sp , 0x9000 ; set the stack pointer to some random address
xor ax , ax
mov ds , ax     ;data segment is at segment zero 
mov es , ax     ; exta segment is at segment zero now.

call clear_screen

mov ah , 13h
mov al , 01h 
mov bh , 0h
mov bl , 0Fh
mov dh , 5h
mov dl , 3h
mov cx , greetings
mov bp , cx
mov cx , 22d
int 10h


mov cx , BOOTLOADER_NAME
mov bp , cx
mov cx , 24d
mov dh , 10h
mov dl , 0h
int 10h

readData:
call readsectors_into_memory
jc readData


;so whatever is on the second sector of the floppy gets put in memory 0000:8000h
;then we jump to it. But when I jump to the kernel.bin  it doesn't work ... however it works with mostly all other programs so their must be something in the kernel.bin that is causeing this
jmp 0000:8000h
Also I am not sure about the algn = 2**4 or 2**2 and what it should be?
I can probably change this with my linker script but I don't know what I should have it at.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: linking files ?

Post by Sam111 »

I fix it by changing bits 32 to 16 in load2 that is how I originally had it.
But what I would like to know is what this alignment stuff is when I did an
objdump -h on the load2.o file I got that it changed from 2**2 to 2**3 ?

Code: Select all

C:\KERNEL~1>objdump -h load2.o

load2.o:     file format a.out-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000050  00000000  00000000  00000020  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, CODE
  1 .data         00000000  00000050  00000050  00000070  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000050  00000050  00000000  2**3
                  ALLOC




sound.o:     file format coff-go32

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000c0  00000000  00000000  000000b4  2**4
                  CONTENTS, ALLOC, LOAD, CODE
  1 .data         00000000  000000c0  000000c0  00000000  2**4
                  ALLOC, LOAD, DATA
  2 .bss          00000000  000000c0  000000c0  00000000  2**2
                  ALLOC
  3 .comment      00000010  000000c0  000000c0  00000174  2**2
                  CONTENTS, DEBUGGING

I am assuming 2**2 means 4bytes and 2**3 means 8bytes alignment.
What exactly is this for and when would you need to use it.
In my link.ld the only line I don't understand is ALIGN(4096) what is this 4096 and why is it so important???

Thanks.
User avatar
KotuxGuy
Member
Member
Posts: 96
Joined: Wed Nov 25, 2009 1:28 pm
Location: Somewhere within 10ft of my favorite chubby penguin!

Re: linking files ?

Post by KotuxGuy »

First off, bootloaders always start in real mode(16-bit), as that is how the processor starts up, and is why your bootloader wouldn't work as 32-bit(protected mode) code.
As for the ALIGN(4096)..

With the Intel x86 32-bit processors, a pages size is fixed at 4KB. 4096 bytes = 4KB. That way, when you enable paging, your code and variables aren't mangled.

But honestly, RTFM!!
Give a man Linux, you feed the nearest optician ( Been staring at the PC too long again? ).
Give a man OS X, you feed the nearest NVidia outlet ( I need more GPU power!! )
Give a man Windows, you feed the entire Tylenol company ( Self explanatory :D )
Post Reply