ARM Integrator-CP Bare Bones: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
Nathan (talk | contribs)
m Bot: Replace deprecated source tag with syntaxhighlight
 
(15 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{BeginnersWarning}}
{{In Progress}}
{{Rating|1}}
{{Template:Kernel designs}}
{{Template:Kernel designs}}
''In this tutorial we are going to compile a simple kernel for the ARM Integrator-CP board and boot it.''
''In this tutorial we are going to compile a simple kernel for the ARM Integrator-CP board and boot it.''
Line 12: Line 13:
For this tutorial you'll need:
For this tutorial you'll need:
* A [[GCC Cross-Compiler|cross compiler]] environment for ARM, minimally arm-elf-as, arm-elf-gcc and arm-elf-ld
* A [[GCC Cross-Compiler|cross compiler]] environment for ARM, minimally arm-elf-as, arm-elf-gcc and arm-elf-ld
* Qemu - to test the kernel (Unless of course you have a spare Integrator-CP board hanging around)
* QEMU - to test the kernel (Unless of course you have a spare Integrator-CP board hanging around)
You should also have read [[Getting Started]] and [[Beginner Mistakes]]. You should also have a reasonable knowledge of ARM assembly by this point, though in this example there isn't much assembly to understand anyway.
You should also have read [[Getting Started]] and [[Beginner Mistakes]]. You should also have a reasonable knowledge of ARM assembly by this point, though in this example there isn't much assembly to understand anyway.


Line 39: Line 40:
</pre>
</pre>


Assemble with: <source lang="bash"> arm-elf-as -o start.o start.s </source>
Assemble with: <syntaxhighlight lang="bash"> arm-elf-as -o start.o start.s </syntaxhighlight>


==main.c==
==main.c==
Line 45: Line 46:
Now we get to the interesting part. We're going to display some characters via the serial port, those characters being "hello, world!" of course.
Now we get to the interesting part. We're going to display some characters via the serial port, those characters being "hello, world!" of course.


<source lang="c">
<syntaxhighlight lang="c">
#define SERIAL_BASE 0x16000000
#define SERIAL_BASE 0x16000000
#define SERIAL_FLAG_REGISTER 0x18
#define SERIAL_FLAG_REGISTER 0x18
Line 57: Line 58:
/* Put our character, c, into the serial buffer */
/* Put our character, c, into the serial buffer */
*(volatile unsigned long*)SERIAL_BASE = c;
*(volatile unsigned long*)SERIAL_BASE = c;

/* Print a carriage return if this is a newline, as the cursor's x position will not reset to 0*/
if (c == '\n')
{
putc('\r');
}
}
}


Line 69: Line 76:
return 0;
return 0;
}
}
</syntaxhighlight>
</source>


Compile this with: <source lang="bash">arm-elf-gcc -Wall -Wextra -Werror -nostdlib -nostartfiles -ffreestanding -std=gnu99 -c main.c</source>
Compile this with: <syntaxhighlight lang="bash">arm-elf-gcc -Wall -Wextra -Werror -nostdlib -nostartfiles -ffreestanding -std=gnu99 -c main.c</syntaxhighlight>


==link.ld==
==link.ld==
Line 87: Line 94:
</pre>
</pre>


Now we link everything using: <source lang="bash">arm-elf-ld -T link.ld -o kernel start.o main.o</source>
Now we link everything using: <syntaxhighlight lang="bash">arm-elf-ld -T link.ld -o kernel start.o main.o</syntaxhighlight>


==Booting==
==Booting==


Boot everything using: <source lang="bash">qemu-system-arm -m 128 -kernel kernel -serial stdio</source>
Boot everything using: <syntaxhighlight lang="bash">qemu-system-arm -m 128 -kernel kernel -serial stdio</syntaxhighlight>

Here is the output:
[[File:Qemuarmhello.png]]


==Links==
==Links==
Line 97: Line 107:
*[http://infocenter.arm.com/help/topic/com.arm.doc.dui0159b/DUI0159B_integratorcp_1_0_ug.pdf Integrator/CP Reference Manual]
*[http://infocenter.arm.com/help/topic/com.arm.doc.dui0159b/DUI0159B_integratorcp_1_0_ug.pdf Integrator/CP Reference Manual]
*[http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf UART PL011 (Serial Port) Technical Reference Manual]
*[http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf UART PL011 (Serial Port) Technical Reference Manual]
*[http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/ Hello world for bare metal ARM using QEMU]
*[[ARM Overview]]
[[Category:ARM]]

[[Category:In Progress]][[Category:ARM]]
[[Category:Bare bones tutorials]]

Latest revision as of 05:18, 9 June 2024

WAIT! Have you read Getting Started, Beginner Mistakes, and some of the related OS theory?
Difficulty level

Beginner
Kernel Designs
Models
Other Concepts

In this tutorial we are going to compile a simple kernel for the ARM Integrator-CP board and boot it.




Required Tools

For this tutorial you'll need:

  • A cross compiler environment for ARM, minimally arm-elf-as, arm-elf-gcc and arm-elf-ld
  • QEMU - to test the kernel (Unless of course you have a spare Integrator-CP board hanging around)

You should also have read Getting Started and Beginner Mistakes. You should also have a reasonable knowledge of ARM assembly by this point, though in this example there isn't much assembly to understand anyway.

start.s

This is the assembly file, most of it isn't that hard to understand.

interrupt_vector_table:
    b . @ Reset
    b . 
    b . @ SWI instruction
    b . 
    b .
    b .
    b .
    b .

.comm stack, 0x10000 @ Reserve 64k stack in the BSS
_start:
    .globl _start
    ldr sp, =stack+0x10000 @ Set up the stack
    bl main @ Jump to the main function
1: 
    b 1b @ Halt

Assemble with:

 arm-elf-as -o start.o start.s

main.c

Now we get to the interesting part. We're going to display some characters via the serial port, those characters being "hello, world!" of course.

#define SERIAL_BASE 0x16000000
#define SERIAL_FLAG_REGISTER 0x18
#define SERIAL_BUFFER_FULL (1 << 5)

void putc (char c)
{
    /* Wait until the serial buffer is empty */
    while (*(volatile unsigned long*)(SERIAL_BASE + SERIAL_FLAG_REGISTER) 
                                       & (SERIAL_BUFFER_FULL));
    /* Put our character, c, into the serial buffer */
    *(volatile unsigned long*)SERIAL_BASE = c;

    /* Print a carriage return if this is a newline, as the cursor's x position will not reset to 0*/
    if (c == '\n')
    {
        putc('\r');
    }
}

void puts (const char * str)
{
    while (*str) putc (*str++);
}

int main (void)
{
    puts ("hello, world!\n");
    return 0;
}

Compile this with:

arm-elf-gcc -Wall -Wextra -Werror -nostdlib -nostartfiles -ffreestanding -std=gnu99 -c main.c

link.ld

ENTRY (_start)

SECTIONS
{
    . = 0;
    .text : { *(.text*) *(.rodata*) }
    .data : { *(.data*) }
    .bss : { *(.bss*) *(COMMON*) }
}

Now we link everything using:

arm-elf-ld -T link.ld -o kernel start.o main.o

Booting

Boot everything using:

qemu-system-arm -m 128 -kernel kernel -serial stdio

Here is the output:

Links