fernly: Initial commit

This is an initial commit of the code.  It just does prints "Hello, world!"
This commit is contained in:
Sean Cross 2014-06-12 12:48:10 +08:00
commit 685824f56e
12 changed files with 398 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/build
*.swp
*.swo

40
Makefile Normal file
View file

@ -0,0 +1,40 @@
include mkenv.mk
include magic.mk
CFLAGS = -mtune=arm7tdmi -mcpu=arm7tdmi -mfloat-abi=soft -Wall \
-O0 -ggdb -Iinclude
LDFLAGS = --nostdlib -T fernvale.ld
LIBS =
SRC_C = \
main.c \
vectors.c \
serial.c
SRC_S = \
start.S
OBJ = $(addprefix $(BUILD)/, $(SRC_S:.S=.o) $(SRC_C:.c=.o))
all: $(BUILD)/firmware.bin
clean:
$(RM) -rf $(BUILD)
HEADER_BUILD = $(BUILD)/genhdr
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
objcopy -S -O binary $(BUILD)/firmware.elf $@
$(BUILD)/firmware.elf: $(OBJ)
$(LD) $(LDFLAGS) --entry=reset_handler -o $@ $(OBJ) $(LIBS)
$(OBJ): $(HEADER_BUILD)/generated.h | $(OBJ_DIRS)
$(HEADER_BUILD)/generated.h: | $(HEADER_BUILD)
touch $@
OBJ_DIRS = $(sort $(dir $(OBJ)))
$(OBJ_DIRS):
$(MKDIR) -p $@
$(HEADER_BUILD):
$(MKDIR) -p $@
-include $(OBJ:.o=.P)

19
README.md Normal file
View file

@ -0,0 +1,19 @@
Fernly - Fernvale Reversing OS
========================================
Fernly is a simple operating system designed for use in the reverse engineering
of the Fernvale CPU. It will likely be disposed of when the system has been
understood well enough to implement a full operating system.
Usage
-----
To compile, simply run "make".
To install, use radare2:
$ sudo radare2 fv://
[0x00000000]> s 0x3460
[0x00003460]> wf .//build/firmware.bin

85
fernvale.ld Normal file
View file

@ -0,0 +1,85 @@
/************************************************************
* configs/c5471evm/scripts/ld.script
*
* Copyright (C) 2007, 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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.
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 OWNER 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.
*
************************************************************/
OUTPUT_ARCH(arm)
ENTRY(_stext)
SECTIONS
{
/* The OS entry point is here */
. = 0x10003460;
.text : {
_stext = ABSOLUTE(.);
KEEP(*(vectors))
*(.text)
*(.fixup)
*(.gnu.warning)
*(.rodata)
*(.glue_7)
*(.glue_7t)
*(.got) /* Global offset table */
_etext = ABSOLUTE(.);
}
_eronly = ABSOLUTE(.); /* See below */
. = ALIGN(4096);
.data : {
_sdata = ABSOLUTE(.);
*(.data)
CONSTRUCTORS
_edata = ABSOLUTE(.);
}
.bss : { /* BSS */
_sbss = ABSOLUTE(.);
*(.bss)
*(COMMON)
_ebss = ABSOLUTE(.);
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

27
include/gnu/stubs-soft.h Normal file
View file

@ -0,0 +1,27 @@
/* This file is automatically generated.
It defines a symbol `__stub_FUNCTION' for each function
in the C library which is a stub, meaning it will fail
every time called, usually setting errno to ENOSYS. */
#ifdef _LIBC
# error Applications may not define the macro _LIBC
#endif
#define __stub_chflags
#define __stub_create_module
#define __stub_fattach
#define __stub_fchflags
#define __stub_fdetach
#define __stub_get_kernel_syms
#define __stub_getmsg
#define __stub_getpmsg
#define __stub_gtty
#define __stub_lchmod
#define __stub_putmsg
#define __stub_putpmsg
#define __stub_query_module
#define __stub_revoke
#define __stub_setlogin
#define __stub_sigreturn
#define __stub_sstk
#define __stub_stty

9
include/serial.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef __UART_H__
#define __UART_H__
#include <stdint.h>
int uart_putc(uint8_t c);
int uart_puts(char *s);
#endif /* __UART_H__ */

44
magic.mk Normal file
View file

@ -0,0 +1,44 @@
# This file expects that OBJ contains a list of all of the object files.
# The directory portion of each object file is used to locate the source
# and should not contain any ..'s but rather be relative to the top of the
# tree.
#
# So for example, py/map.c would have an object file name py/map.o
# The object files will go into the build directory and mantain the same
# directory structure as the source tree. So the final dependency will look
# like this:
#
# build/py/map.o: py/map.c
#
# We set vpath to point to the top of the tree so that the source files
# can be located. By following this scheme, it allows a single build rule
# to be used to compile all .c files.
vpath %.S . $(TOP)
$(BUILD)/%.o: %.S
$(ECHO) "CC $<"
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
vpath %.s . $(TOP)
$(BUILD)/%.o: %.s
$(ECHO) "AS $<"
$(Q)$(AS) -o $@ $<
define compile_c
$(ECHO) "CC $<"
$(Q)$(CC) $(CFLAGS) -c -MD -o $@ $<
@# The following fixes the dependency file.
@# See http://make.paulandlesley.org/autodep.html for details.
@$(CP) $(@:.o=.d) $(@:.o=.P); \
$(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \
$(RM) -f $(@:.o=.d)
endef
vpath %.c . $(TOP)
$(BUILD)/%.o: %.c
$(call compile_c)
$(BUILD)/%.pp: %.c
$(ECHO) "PreProcess $<"
$(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<

10
main.c Normal file
View file

@ -0,0 +1,10 @@
#include "serial.h"
int main(int argc, char **argv) {
while(1) {
int i;
uart_puts("Hello, world!\n");
for (i = 0; i < 0xf000; i++);
}
return 0;
}

58
mkenv.mk Normal file
View file

@ -0,0 +1,58 @@
ifneq ($(lastword a b),b)
$(error These Makefiles require make 3.81 or newer)
endif
# Set TOP to be the path to get from the current directory (where make was
# invoked) to the top of the tree. $(lastword $(MAKEFILE_LIST)) returns
# the name of this makefile relative to where make was invoked.
#
# We assume that this file is in the py directory so we use $(dir ) twice
# to get to the top of the tree.
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
TOP := $(patsubst %/py/mkenv.mk,%,$(THIS_MAKEFILE))
# Turn on increased build verbosity by defining BUILD_VERBOSE in your main
# Makefile or in your environment. You can also use V=1 on the make command
# line.
ifeq ("$(origin V)", "command line")
BUILD_VERBOSE=$(V)
endif
ifndef BUILD_VERBOSE
BUILD_VERBOSE = 0
endif
ifeq ($(BUILD_VERBOSE),0)
Q = @
else
Q =
endif
# Since this is a new feature, advertise it
ifeq ($(BUILD_VERBOSE),0)
$(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.)
endif
# default settings; can be overriden in main Makefile
BUILD ?= build
RM = rm
ECHO = @echo
CP = cp
MKDIR = mkdir
SED = sed
PYTHON = python
AS = $(CROSS_COMPILE)as
CC = $(CROSS_COMPILE)clang
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
STRIP = $(CROSS_COMPILE)strip
all:
.PHONY: all
.DELETE_ON_ERROR:
MKENV_INCLUDED = 1

20
serial.c Normal file
View file

@ -0,0 +1,20 @@
#include <stdint.h>
#include "serial.h"
int uart_putc(uint8_t c) {
uint32_t *uart_ldr = (uint32_t *)0xa0080014;
uint32_t *uart_sbr = (uint32_t *)0xa0080000;
/* Wait for UART to be empty */
while (! (*uart_ldr & 0x20));
*uart_sbr = c;
return 0;
}
int uart_puts(char *s) {
while(*s) {
if (*s == '\n')
uart_putc('\r');
uart_putc(*s++);
}
return 0;
}

49
start.S Normal file
View file

@ -0,0 +1,49 @@
.section vectors
b do_reset
b do_undef
b do_swi
b do_prefetch_abort
b do_data_abort
b do_reserved
b do_irq
b do_fiq
do_reset:
b reset_handler
do_undef:
b undef_handler
do_swi:
b swi_handler
do_prefetch_abort:
b prefetch_abort_handler
do_data_abort:
b data_abort_handler
do_reserved:
b reserved_handler
do_irq:
b irq_handler
do_fiq:
b fiq_handler
.text
.global other
other:
add r1, r2, r1
bx lr
.global __start
__start:
add r3, r2, r3
bx lr
.global _start
_start:
add r4, r3, r4
bx lr
.global other2
other2:
add r5, r4, r5
bx lr

34
vectors.c Normal file
View file

@ -0,0 +1,34 @@
void reset_handler(void) {
extern int main(int argc, char **argv);
main(1, 0);
return;
}
void undef_handler(void) {
return;
}
void swi_handler(void) {
return;
}
void prefetch_abort_handler(void) {
return;
}
void data_abort_handler(void) {
return;
}
void reserved_handler(void) {
return;
}
void irq_handler(void) {
return;
}
void fiq_handler(void) {
return;
}