GDT help please! [SOLVED]

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.
nolag
Posts: 16
Joined: Tue Sep 21, 2010 11:57 am

GDT help please! [SOLVED]

Post by nolag »

Hi all, I am using http://www.osdever.net/bkerndev/Docs/gdt.htm as a tutorial on how to make the GDT table. It seems very similar to this site's tutorial but with an example. I have an odd linker error though and I am stuck! It says that it can not find gdt_flush. I have tried renaming it from _gdt_flush to gdt_flush (since I needed to remove the initial _ in everything I extern to C for example it says extern _cmain I use extern cmain or it complains) but still no luck! Weird thing that does happen though (did this by mistake) is if I move it to after the .bss and with no _ it finds it (but the system keeps crashing because it should not be there). Any help provided would be greatly appreciated.

Looking forward to responses
nolag
Last edited by nolag on Fri Oct 01, 2010 3:37 pm, edited 1 time in total.
nolag
Posts: 16
Joined: Tue Sep 21, 2010 11:57 am

Re: GDT help please!

Post by nolag »

Sorry, I was at work when I posted and did not have much of the info on me.
This is from the tutorial I posted earlier and is what I was using

Code: Select all

global gdt_flush     ; Allows the C code to link to this
extern gp            ; Says that '_gp' is in another file
gdt_flush:
    lgdt [gp]        ; Load the GDT with our '_gp' which is a special pointer
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!
flush2:
    ret    

is the code. I currently have that under my call to my kernel.

LDFLAGS := -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000

this is in my make file
kernel.bin: start.o main.o asmc.o print.o string.o
ld -m elf_i386 -T link.ld -o kernel.bin start.o main.o asmc.o print.o string.o

start.o

and

main.o: In function `gdt_install':
main.c:(.text+0x125): undefined reference to `gdt_flush'
make: *** [kernel.bin] Error 1

that is my error. If I add an _ it is still there, if I move the code to under my bss section it will link it (don't know why) but then it will crash (I get that).
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: GDT help please!

Post by gerryg400 »

I'm not sure what system you are using. Which LD is it ?

Try using GCC instead of LD for linking. You will need to modify the command line a bit. Sometimes the result is different. Also you seem to have an LDFLAGS that you are not using.
If a trainstation is where trains stop, what is a workstation ?
nolag
Posts: 16
Joined: Tue Sep 21, 2010 11:57 am

Re: GDT help please!

Post by nolag »

Thank you bothfor your replies, I will post the whole code tonight when I get home if I can't fix it with GCC's linking. It is odd that the linker did not find the symobl when I moved it (in the same file) though eh!
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: GDT help please!

Post by thepowersgang »

Just checking, I assume you are using NASM for your assembly, so do you have [section .text] before your code in the assembly file?
I have observed that if there are multiple sections in a NASM file, they must all be explicitly named (it doesn't seem to implicitly put un-sectioned code into .text).
This may be the source of your issue.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: GDT help please!

Post by Chandra »

Since you are linking under elf output format, the linker cannot reference functions and variables with leading underscore. That's normal.
One option might be to link under flat binary format (--oformat-binary). But make sure you donot ommit a leading underscore as long as you reference external variables and functions.
If this works then the problem is with the output format you are linking to.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: GDT help please!

Post by thepowersgang »

@Chandra: ???

There should be no issue with or without leading underscores in modern linkers.
According to the errors, there is no issue with the name of the symbol, just that it is not showing up.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: GDT help please!

Post by JamesM »

Hi,
Chandra wrote:Since you are linking under elf output format, the linker cannot reference functions and variables with leading underscore. That's normal.
One option might be to link under flat binary format (--oformat-binary). But make sure you donot ommit a leading underscore as long as you reference external variables and functions.
If this works then the problem is with the output format you are linking to.
Nowhere in the posted code does the assembly symbol have a leading underscore.

OP: I'm actually wondering in which file you placed that GDT asm code. Are you definately actually including it on the link line?

Assuming so, please post the output of "file $MY_ASM_OBJECT_FILE" and "nm $MY_ASM_OBJECT_FILE".
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: GDT help please!

Post by Chandra »

JamesM wrote:Hi,
Chandra wrote:Since you are linking under elf output format, the linker cannot reference functions and variables with leading underscore. That's normal.
One option might be to link under flat binary format (--oformat-binary). But make sure you donot ommit a leading underscore as long as you reference external variables and functions.
If this works then the problem is with the output format you are linking to.
Nowhere in the posted code does the assembly symbol have a leading underscore.
That's because as he said he has removed all the leading underscores which should have been as in Bran's tutorial. My concern is not with the leading underscores though, I was just suggesting to test out the flat binary output format. This might work.

@thepowersgang:

Sometime back I was using gcc under linux. And ld always complained symbol not found whenever I used the leading underscore as seen in most of the tutorials here(which reference external C functions in assembly). So I was just wondering if he had encountered similar problems. Not a big issue though. My actual concern was with the flat binary format. Never Mind.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
nolag
Posts: 16
Joined: Tue Sep 21, 2010 11:57 am

Re: GDT help please!

Post by nolag »

I tried allowing GCC to do it and I get the same error. I have the following code

Code: Select all

; This is the kernel's entry point. We could either call main here,
; or we can use this to setup the stack or other nice stuff, like
; perhaps setting up the GDT and segments. Please note that interrupts
; are disabled at this point.
[BITS 32]
global start
start:
    mov esp, _sys_stack     ; This points the stack to our new stack area
    jmp stublet

; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
ALIGN 4
mboot:
    ; Multiboot macros to make a few lines later more readable
    MULTIBOOT_PAGE_ALIGN	equ 1<<0
    MULTIBOOT_MEMORY_INFO	equ 1<<1
    MULTIBOOT_HEADER_MAGIC	equ 0x1BADB002
    MULTIBOOT_HEADER_FLAGS	equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
    MULTIBOOT_CHECKSUM	equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

    ; This is the GRUB Multiboot header. A boot signature
    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd MULTIBOOT_CHECKSUM
    
; A call to main (the C kernel) followed by an infinite loop (jmp $)
stublet:
	cli
 	EXTERN cmain 		; start of our kernel
 	call cmain
	jmp $		;if something goes wrong, call kernel again


global gdt_flush     ; Allows the C code to link to this
extern gp            ; Says that '_gp' is in another file
gdt_flush:
    lgdt [gp]        ; Load the GDT with our '_gp' which is a special pointer
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!
flush2:
    ret  

; Here is the definition of our BSS section. Right now, we'll use
; it just to store the stack. Remember that a stack actually grows
; downwards, so we declare the size of the data before declaring
; the identifier '_sys_stack'
SECTION .bss
    resb 8192               ; This reserves 8KBytes of memory here
_sys_stack:

Make file is as follows

Code: Select all

CFLAGS  := -m32 -std=c99 -fno-stack-protector -fno-builtin -nostdinc -O2 -Wall -I.
LDFLAGS := -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000 -T link.ld
CC = gcc
OBJECTS = start.o main.o asmc.o print.o string.o
EXEC = kernel.bin

${EXEC}: ${OBJECTS}
	${CC} ${LDFLAGS} ${CFLAGS} ${OBJECTS} -o ${EXEC}
	
run: kernel.bin
	qemu -kernel kernel.bin

start.o: ../kernel/start.asm
	nasm  -f elf -o start.o ../kernel/start.asm

main.o: ../kernel/main.c ../kernel/system.h ../kernel/string.h
	gcc $(CFLAGS) -c -o main.o ../kernel/main.c

print.o: ../kernel/print.c ../kernel/system.h ../kernel/string.h
	gcc  $(CFLAGS) -c -o print.o ../kernel/print.c
	
string.o: ../kernel/string.c ../kernel/string.h
	gcc  $(CFLAGS) -c -o string.o ../kernel/string.c

asmc.o: ../kernel/asmc.c ../kernel/system.h ../kernel/string.h
	gcc  $(CFLAGS) -c -o asmc.o ../kernel/asmc.c
	
clean: 
	rm -f *.o *.binnel.bin
If I move the function to BSS section it still links. I have the following for my linker (link.ld)

ENTRY(start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}


I have also tried the following for my make file (same error)

Code: Select all

CFLAGS  := -m32 -std=c99 -fno-stack-protector -fno-builtin -nostdinc -O2 -Wall -I.
LDFLAGS := -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000

run: kernel.bin
	qemu -kernel kernel.bin

kernel.bin:	start.o main.o asmc.o print.o string.o
	ld  -m elf_i386 -T link.ld -o kernel.bin start.o main.o asmc.o print.o string.o

start.o: ../kernel/start.asm
	nasm  -f elf -o start.o ../kernel/start.asm

main.o: ../kernel/main.c ../kernel/system.h ../kernel/string.h
	gcc $(CFLAGS) -c -o main.o ../kernel/main.c

print.o: ../kernel/print.c ../kernel/system.h ../kernel/string.h
	gcc  $(CFLAGS) -c -o print.o ../kernel/print.c
	
string.o: ../kernel/string.c ../kernel/string.h
	gcc  $(CFLAGS) -c -o string.o ../kernel/string.c

asmc.o: ../kernel/asmc.c ../kernel/system.h ../kernel/string.h
	gcc  $(CFLAGS) -c -o asmc.o ../kernel/asmc.c
	
clean: 
	rm -f *.o *.bin
I added --oformat-binary to the LDFLAGS but still same error :'(. Thank you all for responding, hope someone can figure it out (I am confused :P).
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: GDT help please!

Post by gerryg400 »

You don't have a text segment in your assembler file. This is the potential problem that thepowersgang pointed out. You said it works when you move the code after the .bss, but it's actually working because you are moving it into the .bss and thus making it visible to the linker.
If a trainstation is where trains stop, what is a workstation ?
nolag
Posts: 16
Joined: Tue Sep 21, 2010 11:57 am

Re: GDT help please!

Post by nolag »

gerryg400 wrote:You don't have a text segment in your assembler file. This is the potential problem that thepowersgang pointed out. You said it works when you move the code after the .bss, but it's actually working because you are moving it into the .bss and thus making it visible to the linker.
I did not realize that I needed to put the .text there I thought that if there was nothing the linker would know to just fill it. Thanks, where do I put it in the asm file?

I knew it had to be something silly :P. I am really into OS programming I just am not into as much of the processor specific stuff, more the concepts and the stuff that can be used everywhere.
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: GDT help please!

Post by gravaera »

Hi:
I did not realize that I needed to put the .text there I thought that if there was nothing the linker would know to (1)just fill it. Thanks, (2)where do I put it in the asm file?

I knew it had to be something silly :P. I am really into OS programming I just (3)am not into as much of the processor specific stuff, more the concepts and the stuff that can be used everywhere.
1. ...? The linker does not decide where to put bytes of code or data. You do that at the assembly script level by specifying section directives. Your linker combines the already put together sections from your assembly output into a binary.
2. At the top of the code/data which should be part of that section. This is universal with all assemblers. Read the manual for your chosen assembler and learn its syntax.
3. So why are you here?
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
nolag
Posts: 16
Joined: Tue Sep 21, 2010 11:57 am

Re: GDT help please!

Post by nolag »

gravaera wrote:Hi:
I did not realize that I needed to put the .text there I thought that if there was nothing the linker would know to (1)just fill it. Thanks, (2)where do I put it in the asm file?

I knew it had to be something silly :P. I am really into OS programming I just (3)am not into as much of the processor specific stuff, more the concepts and the stuff that can be used everywhere.
1. ...? The linker does not decide where to put bytes of code or data. You do that at the assembly script level by specifying section directives. Your linker combines the already put together sections from your assembly output into a binary.
2. At the top of the code/data which should be part of that section. This is universal with all assemblers. Read the manual for your chosen assembler and learn its syntax.
3. So why are you here?

1)Yeah, I know that the linker would ot decide where to put it but I assumed that when I had .text in my link.ld file it would know the 1st part was by default text (guess I was wrong)
2) Thank you :D
3) I am interested in the processor stuff just not as much (but still interested)as the other parts. So I will be happy when I get that done and can do most of the rest of my coding in C. Also I want to learn as much as I can on OS dev because I have a class coming up for school (granted it is an ARM I think), but the basic concepts should be similar.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: GDT help please!

Post by JamesM »

Yeah, I know that the linker would ot decide where to put it but I assumed that when I had .text in my link.ld file it would know the 1st part was by default text (guess I was wrong)
Remember that assumption is the mother of all fuckups ;)
Post Reply