diff --git a/CMakeLists.txt b/CMakeLists.txt index e8a8b10..fae4d53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,18 @@ add_executable( ${TARGET_BUILD} ${rpiIncludes} ) +set_target_properties( ${TARGET_BUILD} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) + +get_target_property(RUNTIME_OUTPUT_DIRECTORY ${TARGET_BUILD} RUNTIME_OUTPUT_DIRECTORY) + add_custom_command( TARGET ${TARGET_BUILD} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ${TARGET_BUILD} -O binary ${TARGET_OUTPUT} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + WORKING_DIRECTORY ${RUNTIME_OUTPUT_DIRECTORY} COMMENT "Convert the ELF output file to a binary image" ) + diff --git a/kernel.elf b/kernel.elf deleted file mode 100755 index 8da3874..0000000 Binary files a/kernel.elf and /dev/null differ diff --git a/kernel.img b/kernel.img deleted file mode 100755 index ee27941..0000000 Binary files a/kernel.img and /dev/null differ diff --git a/src/armStart.S b/src/armStart.S new file mode 100644 index 0000000..0fce4eb --- /dev/null +++ b/src/armStart.S @@ -0,0 +1,163 @@ +// Part of the Raspberry-Pi Bare Metal Tutorials +// Copyright (c) 2013-2015, Brian Sidebotham +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + + +.section ".text.startup" + +.global _start +.global _get_stack_pointer +.global _exception_table +.global _enable_interrupts + +// From the ARM ARM (Architecture Reference Manual). Make sure you get the +// ARMv5 documentation which includes the ARMv6 documentation which is the +// correct processor type for the Broadcom BCM2835. The ARMv6-M manuals +// available on the ARM website are for Cortex-M parts only and are very +// different. +// +// See ARM section A2.2 (Processor Modes) + +.equ CPSR_MODE_USER, 0x10 +.equ CPSR_MODE_FIQ, 0x11 +.equ CPSR_MODE_IRQ, 0x12 +.equ CPSR_MODE_SVR, 0x13 +.equ CPSR_MODE_ABORT, 0x17 +.equ CPSR_MODE_UNDEFINED, 0x1B +.equ CPSR_MODE_SYSTEM, 0x1F + +// See ARM section A2.5 (Program status registers) +.equ CPSR_IRQ_INHIBIT, 0x80 +.equ CPSR_FIQ_INHIBIT, 0x40 +.equ CPSR_THUMB, 0x20 + +.equ SCTLR_ENABLE_DATA_CACHE, 0x4 +.equ SCTLR_ENABLE_BRANCH_PREDICTION, 0x800 +.equ SCTLR_ENABLE_INSTRUCTION_CACHE, 0x1000 + +_start: + ldr pc, _reset_h + ldr pc, _undefined_instruction_vector_h + ldr pc, _software_interrupt_vector_h + ldr pc, _prefetch_abort_vector_h + ldr pc, _data_abort_vector_h + ldr pc, _unused_handler_h + ldr pc, _interrupt_vector_h + ldr pc, _fast_interrupt_vector_h + +_reset_h: .word _reset_ +_undefined_instruction_vector_h: .word undefined_instruction_vector +_software_interrupt_vector_h: .word software_interrupt_vector +_prefetch_abort_vector_h: .word prefetch_abort_vector +_data_abort_vector_h: .word data_abort_vector +_unused_handler_h: .word _reset_ +_interrupt_vector_h: .word interrupt_vector +_fast_interrupt_vector_h: .word fast_interrupt_vector + +_reset_: + // We enter execution in supervisor mode. For more information on + // processor modes see ARM Section A2.2 (Processor Modes) + + mov r0, #0x8000 + mov r1, #0x0000 + ldmia r0!,{r2, r3, r4, r5, r6, r7, r8, r9} + stmia r1!,{r2, r3, r4, r5, r6, r7, r8, r9} + ldmia r0!,{r2, r3, r4, r5, r6, r7, r8, r9} + stmia r1!,{r2, r3, r4, r5, r6, r7, r8, r9} + + // Initialise Stack Pointers --------------------------------------------- + + // We're going to use interrupt mode, so setup the interrupt mode + // stack pointer which differs to the application stack pointer: + mov r0, #(CPSR_MODE_IRQ | CPSR_IRQ_INHIBIT | CPSR_FIQ_INHIBIT ) + msr cpsr_c, r0 + mov sp, #0x7000 + + // Switch back to supervisor mode (our application mode) and + // set the stack pointer. Remember that the stack works its way + // down memory, our heap will work it's way up from after the + // application. + mov r0, #(CPSR_MODE_SVR | CPSR_IRQ_INHIBIT | CPSR_FIQ_INHIBIT ) + msr cpsr_c, r0 + mov sp, #0x8000 + + // Enable L1 Cache ------------------------------------------------------- + + // R0 = System Control Register + mrc p15,0,r0,c1,c0,0 + + // Enable caches and branch prediction + orr r0,#SCTLR_ENABLE_BRANCH_PREDICTION + orr r0,#SCTLR_ENABLE_DATA_CACHE + orr r0,#SCTLR_ENABLE_INSTRUCTION_CACHE + + + // System Control Register = R0 + mcr p15,0,r0,c1,c0,0 + + + // Enable VFP ------------------------------------------------------------ + + // r1 = Access Control Register + MRC p15, #0, r1, c1, c0, #2 + // enable full access for p10,11 + ORR r1, r1, #(0xf << 20) + // ccess Control Register = r1 + MCR p15, #0, r1, c1, c0, #2 + MOV r1, #0 + // flush prefetch buffer because of FMXR below + MCR p15, #0, r1, c7, c5, #4 + // and CP 10 & 11 were only just enabled + // Enable VFP itself + MOV r0,#0x40000000 + // FPEXC = r0 + FMXR FPEXC, r0 + + // The c-startup function which we never return from. This function will + // initialise the ro data section (most things that have the const + // declaration) and initialise the bss section variables to 0 (generally + // known as automatics). It'll then call main, which should never return. + bl _cstartup + + // If main does return for some reason, just catch it and stay here. +_inf_loop: + b _inf_loop + + +_get_stack_pointer: + // Return the stack pointer value + str sp, [sp] + ldr r0, [sp] + + // Return from the function + mov pc, lr + + +_enable_interrupts: + mrs r0, cpsr + bic r0, r0, #0x80 + msr cpsr_c, r0 + + mov pc, lr