fernly: Initial commit
This is an initial commit of the code. It just does prints "Hello, world!"
This commit is contained in:
commit
685824f56e
12 changed files with 398 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/build
|
||||
*.swp
|
||||
*.swo
|
40
Makefile
Normal file
40
Makefile
Normal 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
19
README.md
Normal 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
85
fernvale.ld
Normal 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
27
include/gnu/stubs-soft.h
Normal 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
9
include/serial.h
Normal 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
44
magic.mk
Normal 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
10
main.c
Normal 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
58
mkenv.mk
Normal 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
20
serial.c
Normal 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
49
start.S
Normal 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
34
vectors.c
Normal 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue