1

I'm writing a toy OS for my raspberry pi, and I'm using xv6 as a reference.

My code has a compile error, when I tried to load an "entrypgdir" symbol that's defined in another file (which is in C).

_start.S:

#include "mem.h"

.globl entry
entry:
    mov r0, #(V2P_NOCAST(entrypgdir))

V2P_NOCAST is a simple macro defined in a .h file as

mem.h:

#define V2P_NOCAST(va) ((va) - KERNBASE)

And the error:

$ arm-none-eabi-gcc -c -o build/_start.o source/_start.S
source/_start.S: Assembler messages:
source/_start.S:17: Error: undefined symbol entrypgdir used as an immediate value

I'm curious since that's how xv6 does it,

movl    $(V2P_WO(entrypgdir)), %eax

And it compiles fine,

$ gcc -m32 -c -o entry.o entry.S

Is it something with my toolchain? Or it's not possible in ARM?

jsz
  • 1,387
  • 9
  • 17
  • The code you are compiling is using `%eax`? This is **x86** assembler? Are you sure that *source/_start.S* is ARM code? Often `gas` will go and try to compile **x86** assembler as it if is ARM code, and doesn't give error diagnostics that pin-point the issue. ARM registers are *r0-r15* and have some special names like *lr,sp,ip,fp,pc*. Registers like `eax ebx esi, edx al ah` are a good clue that the code is `x86`. I got the latest *git repo* and this code is **x86**. You will have many issues using this. I would suggest eCos, uCos, rtems, etc. – artless noise Mar 28 '13 at 14:19
  • You must be looking at the wrong place ;) My code is earlier, "_start.S". – jsz Mar 28 '13 at 14:26
  • Sorry, I didn't get you are porting this to ARM and not compiling as is. Is that correct? Then, I think [auselen](http://stackoverflow.com/users/1163019/auselen) is correct. See also [relocation in arm](http://stackoverflow.com/questions/15671717/relocation-in-assembly). – artless noise Mar 28 '13 at 14:29
  • Yeah, But I'm not porting it. Just reading the code and accompany book as a guide. – jsz Mar 28 '13 at 14:34
  • Thanks anyway! I need more systematic study of arm. – jsz Mar 28 '13 at 14:35

1 Answers1

2

Try this instead

entry:
    ldr r0, =(V2P_NOCAST(entrypgdir))

Intermediate value in mov instruction needs to be embedded in instruction so that needs to be known at compile time and also for address uses, you can't load any 32 bit value via mov which forces you to fall back to ldr.

auselen
  • 27,577
  • 7
  • 73
  • 114