OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 16, 2024 2:45 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 7:48 am 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
Hi,

I'm working on the second stage loader(in C).
When I switch to the protected mode, an initialized global variables don't work (.data section).
This code doesn't work:
Code:
unsigned short* vmem = (unsigned short*)0xb8000;

void lmain()
{
   for (unsigned int i = 0; i < 80 * 24; i++)
      vmem[i] = 0;

   while (1);
}

But this code works perfectly:
Code:
unsigned short* vmem;

void lmain()
{
   vmem = (unsigned short*)0xb8000;

   for (unsigned int i = 0; i < 80 * 24; i++)
      vmem[i] = 0;

   while (1);
}

I'm compiling using x86_64-elf cross-compiler with these flags:
Code:
-Wall -std=gnu99 -mcmodel=large -ffreestanding -fno-builtin -mno-red-zone -g -fno-stack-protector -fomit-frame-pointer
.
Here's my linker script:
Code:
OUTPUT_FORMAT("binary")

ENTRY(start)

SECTIONS
{
   . = 0x7c00;

   .text : ALIGN(0x200)
   {
      *(.entry)
      *(.text)
   }

   .rodata : ALIGN(0x200)
   {
      *(.rodata)
   }

   .data : ALIGN(0x200)
   {
      *(.data)
   }

   .bss : ALIGN(0x200)
   {
      *(.bss)
   }

   loader_end = .;
}

Help me please! Thanks in advance.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:05 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
And what is the first stage loader? BIOS? MBR? Judging from your linker script it is one of these. If it is then you should know that BIOS and MBR loader only loads one sector of data (512 bytes). Since your sections are 512 byte aligned only first section (.text) gets loaded. That would explain why initialized data is not there. Change your section alignment to 1 and see if it helps. BTW. I don't think C is a good language choice for this.

EDIT: Ohh… and when do you switch to protected mode? Custom MBR or something?


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:12 am 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
pvc wrote:
And what is the first stage loader? BIOS? MBR? Judging from your linker script it is one of these. If it is then you should know that BIOS and MBR loader only loads one sector of data (512 bytes). Since your sections are 512 byte aligned only first section (.text) gets loaded. That would explain why initialized data is not there. Change your section alignment to 1 and see if it helps. BTW. I don't think C is a good language choice for this.

The first stage loader is an MBR. It reads first sector from the active partition and jumps to the VBR.
The VBR is loading remaining sectors and switches to protected mode.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:20 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
Ok. That changes things a little bit. But I would still suggest that you change section alignment to 1 byte to see what happens. Also, are you sure your start address (0x7C00) is right? If your code is linked for that address and you load it somewhere else it may not work since absolute adresses are simply wrong.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:29 am 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
pvc wrote:
Ok. That changes things a little bit. But I would still suggest that you change section alignment to 1 byte to see what happens. Also, are you sure your start address (0x7C00) is right? If your code is linked for that address and you load it somewhere else it may not work since absolute adresses are simply wrong.

Changed section alignment to 1 and start address to 0x8000 but nothing changed.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:36 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
It would help to see your loader code.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:41 am 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
Here it is:
Code:
extern loader_end
extern lmain

section .entry
bits 16

global start
start:
   mov ecx, [bx + 8]

   cli
   xor ax, ax
   mov ds, ax
   mov es, ax
   mov ss, ax
   mov fs, ax
   mov gs, ax

   mov eax, [loader_size]
   shr eax, 9
   inc eax
   mov [dap.sectors], ax

   mov eax, ecx
   inc eax
   mov [dap.lba], eax

   mov [driveid], dl

   mov sp, 0x8000

   mov ah, 0x42
   mov si, dap
   int 0x13
   jc .error

   in al, 0x92
   or al, 2
   out 0x92, al

   cli
   lgdt [GDT32.Pointer]

   mov eax, cr0
   or eax, 1
   mov cr0, eax

   jmp 0x08:start32
.error:
   mov si, disk_error
   call print
   jmp $

print:
   lodsb
   or al, al
   jz .print_done
   mov ah, 0x0e
   int 0x10
   jmp print
.print_done:
   ret

loader_size dd loader_end - 0x8000
driveid db 0

dap:
   .size db 0x10
   .reserved db 0
   .sectors dw 1
   .offset dw 0x8200
   .segment dw 0
   .lba dd 0, 0

disk_error db 'Error: disk read failure!', 13, 10, 0

bits 32
GDT32:
.Null: equ $ - GDT32
   dw 0
   dw 0
   db 0
   db 0
   db 0
   db 0
.Code: equ $ - GDT32
   dw 0xFFFF
   dw 0
   db 0
   db 10011010b
   db 11001111b
   db 0
.Data: equ $ - GDT32
   dw 0xFFFF
   dw 0
   db 0
   db 10010010b
   db 11001111b
   db 0
.Code16: equ $ - GDT32
   dw 0xFFFF
   dw 0
   db 0
   db 10011010b
   db 10001111b
   db 0
.Data16: equ $ - GDT32
   dw 0xFFFF
   dw 0
   db 0
   db 10010010b
   db 00001111b
   db 0
.Pointer:
   dw $ - GDT32 - 1
   dd GDT32

section .text
start32:
   xor eax, eax
   mov ax, 0x10
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax

   mov esp, 0x8000

   call lmain
   jmp $


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:54 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
I am trying to test your code and I ran into something like this:
Code:
cc1: error: code model ‘large’ not supported in the 32 bit mode

when compiling the .c file with options you provided. I've added -m32 option because my compiler generates 64 bit code by default. Also -mno-red-zone is used for x86-64.
Are you sure you are generating 32 bit code?


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 8:59 am 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
pvc wrote:
I am trying to test your code and I ran into something like this:
Code:
cc1: error: code model ‘large’ not supported in the 32 bit mode

when compiling the .c file with options you provided. I've added -m32 option because my compiler generates 64 bit code by default. Also -mno-red-zone is used for x86-64.
Are you sure you are generating 32 bit code?

Should I generate exactly 32-bit code?
I'm planning to load a 64-bit kernel.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 9:06 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
Yes. You should be generating 32 bit protected mode code for now. You have to get this working before you can switch to 64 bit long mode.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 9:08 am 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
AlexKuz wrote:
pvc wrote:
I am trying to test your code and I ran into something like this:
Code:
cc1: error: code model ‘large’ not supported in the 32 bit mode

when compiling the .c file with options you provided. I've added -m32 option because my compiler generates 64 bit code by default. Also -mno-red-zone is used for x86-64.
Are you sure you are generating 32 bit code?

Should I generate exactly 32-bit code?
I'm planning to load a 64-bit kernel.


That depends on just what mode you are in at this point of the loader. It sounds as if you have already switched to protected mode, but you would still need to switch again into long mode to run a 64-bit kernel. To the best of my knowledge, you cannot go directly from real mode to long mode; you need to switch to 32-bit protected mode first, then bump to long mode.

Comments and corrections welcome.

EDIT: hanzo'ed. Oh well.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 9:17 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
@Schol-R-LEA It is possible to do 16->64 bit switch but it's a little bit tricky. It's easier to go 16->32->64.


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 9:20 am 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
pvc wrote:
@Schol-R-LEA It is possible to do 16->64 bit switch but it's a little bit tricky. It's easier to go 16->32->64.

Before switching to long mode, I need to do some things(e.g. load initrd, setup paging, set videomode).


Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 9:34 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
Actually setting up paging is mandatory for long mode to work.

Personally, I would suggest you to use GRUB. It gets you to stable protected mode environment, allows to load initird, changes video mode for you if you want to and what's most important… allows you to use multiboot image (which is plain old ELF with some extra header in it). What I do myself for testing is to use grub-mkrescue to make .iso image of my OS using files stored in a single directory.

EDIT: Here is a little something for you. You can use it if you want to.


Attachments:
File comment: Template project files.
long_mode_barebones.tar.gz [1.58 KiB]
Downloaded 23 times
Top
 Profile  
 
 Post subject: Re: GCC wrong .data addresses
PostPosted: Thu Mar 22, 2018 1:01 pm 
Offline

Joined: Thu Mar 22, 2018 7:16 am
Posts: 8
pvc wrote:
Actually setting up paging is mandatory for long mode to work.

Personally, I would suggest you to use GRUB. It gets you to stable protected mode environment, allows to load initird, changes video mode for you if you want to and what's most important… allows you to use multiboot image (which is plain old ELF with some extra header in it). What I do myself for testing is to use grub-mkrescue to make .iso image of my OS using files stored in a single directory.

EDIT: Here is a little something for you. You can use it if you want to.

Thank you, but I want to write my own bootloader.
Maybe better to look aside UEFI?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: 0xY and 648 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group