OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 8:34 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 2:59 am 
Offline
Member
Member
User avatar

Joined: Sun Feb 12, 2017 1:50 am
Posts: 26
I've written a very simple kernel based in part on the Bare Bones tutorial. My working directory looks like
Code:
boot.s   link.ld   kernel.c   terminal.h   terminal.c   Makefile

I am able to boot and run everything as expected until I include a static variable in either kernel.c or terminal.c, which causes the 'Trying to execute code outside RAM' error. My initial guess was that that static variable was messing up / overwriting the EIP somehow but I'm not sure how that would be possible. If I understand correctly static variables should get put on .bss which shouldn't mess with eip in any way at all.

**Edit**
I oversimplified things yesterday trying to reduce the problem down to a forum post friendly format. I failed to notice that including "terminal.h" and attempting to call a function from it is required to reproduce the error. The nature of the function called does not look to effect the error. Currently terminal.h declares a single function and terminal.c consists of two lines, one including terminal.h and an empty function definition for the function declared in terminal.h.

A static variable declared in either terminal.c or kernel.c causes the error to occur.
Code:
//terminal.h
#ifndef TERM_HEADER
#define TERM_HEADER
void some_function_from_terminal_h();
#endif

Code:
//terminal.c
#include "terminal.h"
void some_function_from_terminal_h(){}

My next guess was that a compile flag might be causing some weird behavior but after looking everything up I'm not so sure.
**Double Edit - I've also tried using a cross compiler but the issue is not resolved.**
Compiling with
Code:
gcc -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector \
           -nostartfiles -nodefaultlibs -c

and
Code:
as --32

****

Anything to help me understand what is going on is greatly appreciated.

crash dump
Code:
qemu: fatal: Trying to execute code outside RAM or ROM at 0xc36620e6
EAX=2badb002 EBX=00010000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=20b0c366 ESP=fffffff0
EIP=c36620e6 EFL=00200086 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0010 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00100380 00000020
IDT=     00000000 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000008 CCD=fffffff0 CCO=SUBL
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000

kernel.c
Code:
#include "terminal.h"

static int test; // Without this everything behaves as expected

int kmain() {
    test = 0;

    /* This function runs just fine unless a static variable is declared in terminal.c or here in kernel.c */
    some_function_from_terminal_h();
    for(;;);
    return 0;
}



boot.s
Code:
.intel_syntax
.extern kmain

.set MAGIC_NUMBER, 0x1BADB002
.set FLAGS, 0X0
.set CHECKSUM, -(MAGIC_NUMBER + FLAGS)

.set KERNEL_STACK_SIZE, 16384 # 16 KiB

.section .multiboot
.align 4
.long MAGIC_NUMBER
.long FLAGS
.long CHECKSUM

# Reserve stack space for kernel
.section .bss
.align 16
stack_bottom:
.skip KERNEL_STACK_SIZE
stack_top:

.section .text
.global loader
loader:
        mov %esp, stack_top

        call kmain
loop:
        jmp loop


link.ld
Code:
ENTRY(loader)

SECTIONS {
        . = 1M;

        .text BLOCK(4K) : ALIGN (4K)
        {
                *(.multiboot)
                *(.text)
        }

        .rodata BLOCK(4K) : ALIGN (4K)
        {
                *(.rodata)
        }

        .data BLOCK(4K) : ALIGN (4K)
        {
                *(.data)
        }

        .bss BLOCK(4K) : ALIGN (4K)
        {
                *(COMMON)
                *(.bss)
        }
}


Last edited by MuchLearning on Sun Feb 12, 2017 2:00 pm, edited 5 times in total.

Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 4:49 am 
Offline
Member
Member
User avatar

Joined: Fri Mar 07, 2008 5:36 pm
Posts: 2111
Location: Bucharest, Romania
You are calling kmain but there is no reference of it. Instead, your C file declares a function call main. Limiting the visibility of your variable, which already has static storage since it is at file scope, isn't the issue. Your linker emits diagnostic messages precisely to avoid such silly problems.

_________________
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 12:33 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 12, 2017 1:50 am
Posts: 26
Love4Boobies wrote:
You are calling kmain but there is no reference of it. Instead, your C file declares a function call main.

Excellent catch, but unfortunately that was just a typo I made writing the forum post last night. I came back and looked at the issue again this morning and realized I had missed another important step in reproducing the error, which was to include and call a function from another file along with declaring a static variable.

I am very appreciative of the time you took to read through everything the first time. I've gone through and updated the original question with more information and ensured that all the code I've supplied reproduces the error exactly as it is provided above.


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 12:51 pm 
Offline
Member
Member

Joined: Sat Mar 28, 2015 11:23 am
Posts: 103
MuchLearning wrote:
Love4Boobies wrote:
You are calling kmain but there is no reference of it. Instead, your C file declares a function call main.

Excellent catch, but unfortunately that was just a typo I made writing the forum post last night. I came back and looked at the issue again this morning and realized I had missed another important step in reproducing the error, which was to include and call a function from another file along with declaring a static variable.

I am very appreciative of the time you took to read through everything the first time. I've gone through and updated the original question with more information and ensured that all the code I've supplied reproduces the error exactly as it is provided above.


Use a cross-compiler, please. It might be the source of your issues.

_________________
If some of you people keep insisting on having backwards compatibitity with the stone age, we'll have stone tools forever.
My Hobby OS: https://github.com/heatd/Onyx


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 1:58 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 12, 2017 1:50 am
Posts: 26
Error persists even when using cross compiler.


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 2:32 pm 
Offline
Member
Member
User avatar

Joined: Thu Mar 27, 2014 3:57 am
Posts: 568
Location: Moscow, Russia
Try disassembling the kernel image with 'i686-elf-objdump -d'.

_________________
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 2:38 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5145
Code:
ESP=fffffff0

Hm.

Code:
.intel_syntax

Hmm.

Code:
mov %esp, stack_top

Hmmmmmm.


There are several varieties of "Intel syntax". Which one are you using? Which one does GAS expect?


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 2:51 pm 
Online
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4596
Location: Chichester, UK
Produce a linker map and inspect it for any possible overlaps/conflicts.


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 3:41 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 12, 2017 1:50 am
Posts: 26
With static int test
Code:
Disassembly of section .text:

00100000 <loader-0xc>:
  100000:       02 b0 ad 1b 00 00       add    dh,BYTE PTR [eax+0x1bad]
  100006:       00 00                   add    BYTE PTR [eax],al
  100008:       fe 4f 52                dec    BYTE PTR [edi+0x52]
  10000b:       e4                      .byte 0xe4

0010000c <loader>:
  10000c:       8b 25 00 50 10 00       mov    esp,DWORD PTR ds:0x105000
  100012:       e8 09 00 00 00          call   100020 <kmain>

00100017 <loop>:
  100017:       eb fe                   jmp    100017 <loop>
  100019:       66 90                   xchg   ax,ax
  10001b:       66 90                   xchg   ax,ax
  10001d:       66 90                   xchg   ax,ax
  10001f:       90                      nop

00100020 <kmain>:
  100020:       83 ec 0c                sub    esp,0xc
  100023:       c7 05 00 50 10 00 00    mov    DWORD PTR ds:0x105000,0x0
  10002a:       00 00 00
  10002d:       e8 0e 00 00 00          call   100040 <some_function_from_terminal_h>
  100032:       eb fe                   jmp    100032 <kmain+0x12>
  100034:       66 90                   xchg   ax,ax
  100036:       66 90                   xchg   ax,ax
  100038:       66 90                   xchg   ax,ax
  10003a:       66 90                   xchg   ax,ax
  10003c:       66 90                   xchg   ax,ax
  10003e:       66 90                   xchg   ax,ax

00100040 <some_function_from_terminal_h>:
  100040:       f3 c3                   repz ret


Without static int test
Code:
Disassembly of section .text:

00100000 <loader-0xc>:
  100000:       02 b0 ad 1b 00 00       add    dh,BYTE PTR [eax+0x1bad]
  100006:       00 00                   add    BYTE PTR [eax],al
  100008:       fe 4f 52                dec    BYTE PTR [edi+0x52]
  10000b:       e4                      .byte 0xe4

0010000c <loader>:
  10000c:       8b 25 00 50 10 00       mov    esp,DWORD PTR ds:0x105000
  100012:       e8 09 00 00 00          call   100020 <kmain>

00100017 <loop>:
  100017:       eb fe                   jmp    100017 <loop>
  100019:       66 90                   xchg   ax,ax
  10001b:       66 90                   xchg   ax,ax
  10001d:       66 90                   xchg   ax,ax
  10001f:       90                      nop

00100020 <kmain>:
  100020:       83 ec 0c                sub    esp,0xc
  100023:       e8 08 00 00 00          call   100030 <some_function_from_terminal_h>
  100028:       eb fe                   jmp    100028 <kmain+0x8>
  10002a:       66 90                   xchg   ax,ax
  10002c:       66 90                   xchg   ax,ax
  10002e:       66 90                   xchg   ax,ax

00100030 <some_function_from_terminal_h>:
  100030:       f3 c3                   repz ret



Not sure what is up with the weird xchg ax, ax instructions. Other than that the only difference between the two is the addition of these two lines in kmain.
Code:
  100023:       c7 05 00 50 10 00 00    mov    DWORD PTR ds:0x105000,0x0
  10002a:       00 00 00


I assume the first line is trying to initialize the static int to 0, meaning it is stored at [DS + 0x105000] which from the first instruction in <loader> looks to be on the stack.
Not sure what is going on with the second line. Either way, still not sure how I end up trying to execute an instruction at such a crazy address.


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 3:51 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 12, 2017 1:50 am
Posts: 26
Octocontrabass wrote:
Code:
ESP=fffffff0

Hm.

Code:
.intel_syntax

Hmm.

Code:
mov %esp, stack_top

Hmmmmmm.


There are several varieties of "Intel syntax". Which one are you using? Which one does GAS expect?


Based on this SO question I assumed .intel_syntax without being followed by no_prefix should look like the code provided.
Following the format instr dest, src and registers being denoted by %. Did I make a faulty assumption somewhere? It is somewhat difficult to find documentation for all of these things. Especially when you're not exactly sure what you are looking for.

From asm docs:
Quote:
Good news are that starting from binutils 2.10 release, GAS supports Intel syntax too. It can be triggered with .intel_syntax directive. Unfortunately this mode is not documented (yet?) in the official binutils manual


Last edited by MuchLearning on Sun Feb 12, 2017 3:57 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 3:56 pm 
Online
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4596
Location: Chichester, UK
You appear to be loading your stack pointer from the contents of a memory location. The same location that stores your static variable.


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 4:15 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 12, 2017 1:50 am
Posts: 26
iansjack wrote:
You appear to be loading your stack pointer from the contents of a memory location. The same location that stores your static variable.


How do I control where the system is putting static variables in memory? Where should they be going? Do I need to set aside memory for them somewhere in boot.s?


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 4:50 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5145
MuchLearning wrote:
Based on this SO question I assumed .intel_syntax without being followed by no_prefix should look like the code provided.
Following the format instr dest, src and registers being denoted by %. Did I make a faulty assumption somewhere?

You're partially correct. Yes, the destination comes first, and yes, registers have the "%" prefix. The faulty assumption is in how labels are handled.

In NASM syntax, you need to explicitly specify when an operand is an immediate value or a memory reference. This means "mov eax, label" puts the address of the label in EAX, and "mov eax, [label]" puts the contents of the memory at that address into EAX.

In MASM and gas syntax, operands are automatically treated as immediate values or memory references depending on the type of the symbol. That means "mov eax, label" can load EAX with either the address of "label" or the contents of the memory at that address depending on how "label" was defined.

So!

When you say "mov $esp, stack_top", are you loading ESP with the address of the top of the stack, or the contents of the top of the stack?


MuchLearning wrote:
It is somewhat difficult to find documentation for all of these things. Especially when you're not exactly sure what you are looking for.

You can get a pretty good idea of what to do by looking at the differences between MASM and NASM syntax.


Top
 Profile  
 
 Post subject: Re: Error: Trying to execute code outside RAM
PostPosted: Sun Feb 12, 2017 4:59 pm 
Online
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4596
Location: Chichester, UK
MuchLearning wrote:
iansjack wrote:
You appear to be loading your stack pointer from the contents of a memory location. The same location that stores your static variable.


How do I control where the system is putting static variables in memory? Where should they be going? Do I need to set aside memory for them somewhere in boot.s?

That's not the problem. It's a question of loading the correct value into esp.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], iansjack, nullplan and 245 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