I've got some Errors while running the Makefile. I am currently using MacOS Mojave, and got some weird errors and I am not able to understand them. The Makefile hadn't work at all, there was an error in ASPARAMS = -m32 (before that it was ASPARAMS= --32 {didn't work}. Now the Makefile has no errors but a other file does. Here is the code of the Makefile:
GPPPARAMS = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
ASPARAMS = -m32
LDPARAMS = -melf_i386
objects = loader.o kernel.o
%.o: %.cpp
g++ $(GPPPARAMS) -o $# -c $<
%.o: %.s
as $(ASPARAMS) -o $# $<
mykernel.bin: linker.ld $(objects)
ld $(LDPARAMS) -T $< -o $# $(objects)
install: mykernel.bin
sudo cp $< /boot/mykernel.bin
mykernel.iso: mykernel.bin
mkdir iso
mkdir iso/boot
mkdir iso/boot/grub
cp $< iso/boot/
echo 'set timeout-0' >> iso/boot/grub/grub.cfg
echo 'set default-0' >> iso/boot/grub/grub.cfg
echo 'menuentry "My Operating System"{' >> iso/boot/grub/grub.cfg
echo ' multiboot /boot/mykernel.bin' >> iso/boot/grub/grub.cfg
echo ' boot' >> iso/boot/grub/grub.cfg
echo '}' >> iso/boot/grub/grub.cfg
grub-mkrescue --output=$# iso
rm -rf iso
run: mykernel.iso
(killall VirtualBox && sleep 1) || true
VirtualBox --startvm "My Operating System" &
Here are the errors:
loader.s:5:20: error: unexpected token in '.section' directive
.section .multiboot
^
loader.s:12:15: error: unexpected token in '.section' directive
.section .text
^
loader.s:29:15: error: unexpected token in '.section' directive
.section .bss
^
make: *** [loader.o] Error 1
And here is the file were the errors appear:
.set MAGIC, 0x1badb002
.set FLAGS, (1<<0 | 1<<1)
.set CHECKSUM, -(MAGIC + FLAGS)
.section .multiboot
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .text
.extern kernelMain
.extern callConstructors
.global loader
loader:
mov $kernel_stack, %esp
call callConstructors
push %eax
push %ebx
call kernelMain
_stop:
cli
hlt
jmp _stop
.section .bss
.space 2*1024*1024;
kernel_stack:
Related
OS - RedHat 8.5, kernel 4.18.0-348.20.1.el8_5.x86_64, gcc-8.5.0
I have installed kernel-devel and kernel-headers, and tried to build a very simple kernel module (just a pair of printk()).
Makefile:
obj-m += test_mod.o
MSRC ?= $(PWD)
KDIR ?= /lib/modules/`uname -r`/build/
all:
make -C $(KDIR) M=$(MSRC) modules
clean:
make -C $(KDIR) M=$(MSRC) clean
However I'm getting error:
% make V=1
make -C /lib/modules/`uname -r`/build M= modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
arch/x86/Makefile:249: *** You are building kernel with non-retpoline compiler, please update your compiler.. Stop.
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:4: all] Error 2
%
Do I have to upgrade to a new compiler, if so which compiler version is needed? man gcc on my machine (RHEL8.5) says that -mindirect-branch= option is supported, and I believe this is the one enabling retpoline.
Should it be possible to disable retpoline support in the kernel? (however I would not like to rebuild the kernel if possible).
Thanks!
EDIT
I disabled retpoline as suggested by 0andriy via grub configuration file, (cat /proc/cmdline shows spectre_v2=off):
% grub2-editenv - set kernelopts=root=/dev/mapper/rhel_ps3cat5505k1-root ro crashkernel=auto resume=/dev/mapper/rhel_ps3cat5505k1-swap rd.lvm.lv=rhel_ps3cat5505k1/root rd.lvm.lv=rhel_ps3cat5505k1/swap rhgb quiet spectre_v2=off
% reboot
However the build still fails:
% make V=1
make -C /lib/modules/`uname -r`/build/ M=/home/mrv/tmp modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /home/mrv/tmp/.tmp_versions ; rm -f /home/mrv/tmp/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/home/mrv/tmp
(cat /dev/null; echo kernel//home/mrv/tmp/test_mod.ko;) > /home/mrv/tmp/modules.order
gcc -Wp,-MD,/home/mrv/tmp/.test_mod.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/8/include -I./arch/x86/include -I./arch/x86/include/generated -I./include/drm-backport -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -DCC_HAVE_ASM_GOTO -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -DCONFIG_TPAUSE=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -Wframe-larger-than=2048 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -g -gdwarf-4 -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -Wno-stringop-truncation -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -fmacro-prefix-map=./= -Wno-packed-not-aligned -DMODULE -DKBUILD_BASENAME='"test_mod"' -DKBUILD_MODNAME='"test_mod"' -c -o /home/mrv/tmp/.tmp_test_mod.o /home/mrv/tmp/test_mod.c
In file included from ./include/linux/module.h:18,
from /home/mrv/tmp/test_mod.c:1:
./include/linux/moduleparam.h:22:1: error: expected ‘,’ or ‘;’ before ‘static’
static const char __UNIQUE_ID(name)[] \
^~~~~~
./include/linux/module.h:158:32: note: in expansion of macro ‘__MODULE_INFO’
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
^~~~~~~~~~~~~
./include/linux/module.h:196:34: note: in expansion of macro ‘MODULE_INFO’
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
^~~~~~~~~~~
/home/mrv/tmp/test_mod.c:19:1: note: in expansion of macro ‘MODULE_LICENSE’
MODULE_LICENSE("GPL")
^~~~~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:322: /home/mrv/tmp/test_mod.o] Error 1
make[1]: *** [Makefile:1571: _module_/home/mrv/tmp] Error 2
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:6: all] Error 2
%
So, running 'make oldconfig && make prepare' in kernel sources directory /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64 results in failure to locate tools/build/Build.include.
Not sure if RedHat allows to build kernel modules in RHEL8 at all.
EDIT2
Simple kernel module:
#include <linux/module.h>
#include <linux/kernel.h>
static __init int test_init(void)
{
printk("Init module\n");
return 0;
}
static __exit void test_exit(void)
{
printk("Cleanup module\n");
}
module_init(test_init)
module_exit(test_exit)
MODULE_DESCRIPTION("Test module");
MODULE_LICENSE("GPL");
I'm trying to compile 2 F90 files and to execute each one separately using a Makefile. The language used is fortran. I am not used to this so I need your help.
The first file is called HECESE_avec_modif.f90 and the second one is called hecese_seq.f90.
The makefile is below :
# Define dependance for suffix .FFREE
# -----------------------------------
.SUFFIXES: .exe .out .o .f .f90
#
# Compilation options for ifort
# ---------------------------------
# ---------------------------------
#FLAGS_fred = -free -O2 -traceback -mcmodel=large\
# -check overflow -check bounds
#FLAGS_fred = -FR -free -ftz -O3 -fPIC
#F90_COMPILER = /opt/intel/bin/ifort
#---------------------------------------------------------
#
# Compilation options for G95
#
#FLAGS_fred = -C -O3 -ffree-form -ffree-line-length-huge -fzero
#FLAGS_fred = -O5 -ffree-form -ffree-line-length-huge -fzero
#F90_COMPILER = g95
#
# Compilation options for GFortran
FLAGS_fred = -ffree-form -ffree-line-length-none -O3 #-march=native
F90_COMPILER = gfortran -m64
F90_COMPILER7 = gfortran-7 -m64
#FLAGS_fred = -O3
#F90_COMPILER = gfortran
#FLAGS_CPPFOR = -L/usr/local/gfortran/lib/x86_64/
#
#
#FLAGS_fred = -free -O4
#
#
# ***************************************************
# ***************************************************
# ** **
# ** definition of file groups for F. Waymel **
# ** **
# ***************************************************
# ***************************************************
#
# 0.) group of all modules containing common variables
# for multiblocs initialisation
# ----------------------------------------------------
#
MAIN = HECESE_avec_modif.f90
MAIN2 = hecese_seq.f90
#
# Compilation of object files :
# -----------------------------
#
MAIN_OBJ =$(MAIN:.f90=.o)
MAIN_OBJ2 =$(MAIN2:.f90=.o)
# Creation of executable:
# ---------------------------------
#
#DEST1 = ~/bin
EXEC = hecesevfinale.out
EXEC2 = heceseseq.out
all : $(EXEC) $(EXEC2)
$(EXEC):$(MAIN_OBJ)
$(F90_COMPILER) -g $(FLAGS_fred) -o $(EXEC) $(MAIN_OBJ)
$(EXEC2):$(MAIN_OBJ2)
$(F90_COMPILER) -g $(FLAGS_fred) -o $(EXEC2) $(MAIN_OBJ2)
#
%.o : %.mod
.f90.o:
$(F90_COMPILER) -g $(FLAGS_fred) -c $<
# $(F90_COMPILER) -g $(FLAGS_fred) -c $<
%.o : %.mod
.f90.o:
$(F90_COMPILER) -g $(FLAGS_fred) -c $<
# $(F90_COMPILER) -g $(FLAGS_fred) -c $<
clean:
rm -f *.o *.mod *.out
#depend .depend:
# makedepf90 metas.f90 $(SOURCES90_fred1) $(SOURCES90_fred2) $(SOURCES90_mwl) $(SOURCES90_mwl2) > .depend
#include .depend
I think that I made a mistake related to the second file.
The message I get when I execute this makefile is :
gfortran -m64 -g -ffree-form -ffree-line-length-none -O3 -o hecesevfinale.out HECESE_avec_modif.o
make: *** No rule to make target 'hecese_seq.o', needed by 'heceseseq.out'. Stop.
I have another problem when I try to execute make clean.
I get :
makefile:82: warning: overriding recipe for target '.f90.o'
makefile:76: warning: ignoring old recipe for target '.f90.o'
Can you help me, please ?
I'm writing my own OS. But in the tutorial (https://github.com/AlgorithMan-de/wyoos/commit/7eb9f8a1d5089cf7587e553e601c42db34dc94a2) he is writing it for i386 arch with x86_32. But now I want to change it to x86_64.
Now I have to replace a few things in the Makefile and in the Linker (like the OUTPUT_ARCH()) but I don't now what I should write there instead.
linker.ld
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)
SECTIONS
{
. = 0x0100000;
.text :
{
*(.multiboot)
*(.text*)
*(.rodata)
}
.data :
{
start_ctors = .;
KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .;
*(.data)
}
.bss :
{
*(.bss)
}
/DISCARD/ : { *(.fini_array*) *(.comment) }
}
Makefile
GCCPARAMS = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
ASPARAMS = --32
LDPARAMS = -melf_i386
objects = loader.o kernel.o
%.o: %.cpp
gcc $(GCCPARAMS) -c -o $# $<
%.o: %.s
as $(ASPARAMS) -o $# $<
mykernel.bin: linker.ld $(objects)
ld $(LDPARAMS) -T $< -o $# $(objects)
install: mykernel.bin
sudo cp $< /boot/mykernel.bin
EDIT
I have now edited the Makefile and the linker.ld
Makefile
GCCPARAMS = -m64 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
ASPARAMS = --64
LDPARAMS = -melf_x86_64
objects = loader.o kernel.o
%.o: %.cpp
gcc $(GCCPARAMS) -c -o $# $<
%.o: %.s
as $(ASPARAMS) -o $# $<
mykernel.bin: linker.ld $(objects)
ld $(LDPARAMS) -T $< -o $# $(objects)
install: mykernel.bin
sudo cp $< /boot/mykernel.bin
linker.ld
ENTRY(loader)
OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386:x86-64)
SECTIONS
{
. = 0x0100000;
.text :
{
*(.multiboot)
*(.text*)
*(.rodata)
}
.data :
{
start_ctors = .;
KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .;
*(.data)
}
.bss :
{
*(.bss)
}
/DISCARD/ : { *(.fini_array*) *(.comment) }
}
But when I try to compile it (ld -melf_x86_64 -T linker.ld -o mykernel.bin loader.o kernel.o), I get an error:
ld: loader.o: in function 'loader':
(.text+0x6): undefined reference to 'eax'
ld: (.text+0xb): undefined reference to 'ebx'
ld: (.text+0x20): undefined reference to 'kernelMain'
I think I have to install a binutil but I don't know which one.
Can someone help me finding the right one?
I've been writing C for 2-3 years and recently picked up assembly but as I use Windows I've never needed to use make files before as I've just used Visual Studio. I'm trying to use Cygwin and an i686 cross compiler to compile c and assembly files, and then link them together into a binary file representing my operating system. I am new to make files so I don't know how to do this properly. This is what I've got so far for the Makefile:
CC = i686-elf-gcc
CC_FLAGS = -c -std=gnu99 -ffreestanding -O2 -Wall -Wextra -I./include
AS = i686-elf-as
LD = i686-elf-gcc -T linker.ld -o myos.bin
LD_FLAGS = -ffreestanding -O2 -nostdlib -lgcc
O_FILES = $(wildcard src/*.o)
all: $(O_FILES)
$(LD) $(LD_FLAGS) $(O_FILES)
src/%.o: src/%.c
$(CC) $(CC_FLAGS) -o $# $<
src/%.o: src/%.asm
$(AS) -o $# $<
I'm getting an error stating that the linker can't find the entry symbol _start so obviously nothing is compiling. How would I fix this?
My src/linker.ld file that defines _start as the entry point is:
ENTRY(_start)
SECTIONS
{
. = 1M;
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
}
The src/boot.asmfile I'm using that defines my _start label is:
# Declare constants for the multiboot header.
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.section .text
.global _start
.type _start, #function
_start:
mov $stack_top, %esp
call kernel_main
cli
1: hlt
jmp 1b
.size _start, . - _start
You will need to modify your Makefile to something like this:
CC = i686-elf-gcc
AS = i686-elf-as
LD = i686-elf-gcc
AS_FLAGS =
LD_FLAGS = -ffreestanding -nostdlib -lgcc -Tlinker.ld
CC_FLAGS = -c -std=gnu99 -ffreestanding -O2 -Wall -Wextra -I./include
C_FILES := $(wildcard src/*.c)
ASM_FILES := $(wildcard src/*.asm)
O_FILES := $(C_FILES:.c=.o) $(ASM_FILES:.asm=.o)
KERNEL_BIN := myos.bin
all: $(KERNEL_BIN)
clean:
rm -f $(KERNEL_BIN) $(O_FILES)
$(KERNEL_BIN): $(O_FILES)
$(LD) $(LD_FLAGS) -o $# $^
%.o: %.c
$(CC) $(CC_FLAGS) -o $# $<
%.o: %.asm
$(AS) $(AS_FLAGS) -o $# $<
This Makefile is different in that we construct a list of ASM files and C files. I also cleaned up the LD_FLAGS a bit and added an extra rule to create myos.bin and to clean the object and bin files.
In your current code you'd have the Makefile variables with this in them after expansion:
C_FILES = src/string.c src/tty.c src/kernel.c
ASM_FILES = src/boot.asm
O_FILES = src/string.o src/tty.o src/kernel.o src/boot.o
O_FILES was derived from concatenating both file lists together and replacing the .c and .asm extensions with .o. This is the list of all the objects that need to be generated from their source files.
With GNU Assembler it is customary to use files with .s extensions (or .S if you want to use the C preprocessor) rather than .asm
The reason the _start label wasn't found is because the assembly files were not being processed. This means that boot.asm was not becoming boot.o and thus wasn't being linked at all.
I am compiling and uploading sketch through command line. I have built a .CPP file as under:
#include< WProgram.h>
int led = 13;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
digitalWrite(led, HIGH);
delay(10000);
digitalWrite(led, LOW);
delay(1000);
}
Now i compiled using command: make TARGET=file_1402814559284 and it compiled fine. When i uploaded using command: make upload TARGET=file_1402814559284
avrdude -F -p atmega328p -P \\.\COM121 -c stk500 -b 115200 -C"avrdude.conf" -U
flash:w:file_1402814559284.hex
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x10
avrdude: initialization failed, rc=-1
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
Please suggest me how to resolve the problem. Code is easily uploaded using arduino IDE but through command line its a problem. I am using Arduino UNO atmega328p and no wiring is done. I am just checking the uploading part.
Make file i am using:
# Arduino makefile
# $Id$
SHELL=C:/Windows/System32/cmd.exe
PORT = \\.\COM121
#/dev/tty.USB*
ARDUINO = arduino
SRC = $(ARDUINO)/buffer.c $(ARDUINO)/pins_arduino.c \
$(ARDUINO)/Serial.c $(ARDUINO)/uart.c $(ARDUINO)/wiring.c
CXXSRC = $(TARGET).cpp $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp
MCU = atmega328p
F_CPU = 16000000
FORMAT = ihex
UPLOAD_RATE = 115200
# Name of this Makefile (used for "make depend").
MAKEFILE = Makefile
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
OPT = s
# Place -D or -U options here
CDEFS = -DF_CPU=$(F_CPU)
CXXDEFS = -DF_CPU=$(F_CPU)
# Place -I options here
CINCS = -I$(ARDUINO)
CXXINCS = -I$(ARDUINO)
# Compiler flag to set the C Standard level.
# c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
LDFLAGS =
# Programming support using avrdude. Settings and variables.
AVRDUDE_PROGRAMMER = stk500
AVRDUDE_PORT = $(PORT)
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
AVRDUDE_FLAGS =-F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
-b $(UPLOAD_RATE) -C"avrdude.conf"
# Program settings
# Program settings
CC = avr-gcc
CXX = avr-g++
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
MV = mv -f
# Define all object files.
OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: build
build: elf hex eep
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
# Program the device.
upload: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
$(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof
extcoff: $(TARGET).elf
$(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof
.SUFFIXES: .elf .hex .eep .lss .sym
.elf.hex:
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $#
.elf.eep:
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $#
# Create extended listing file from ELF output file.
.elf.lss:
$(OBJDUMP) -h -S $< > $#
# Create a symbol table from ELF output file.
.elf.sym:
$(NM) -n $< > $#
# Link: create ELF output file from object files.
$(TARGET).elf: $(OBJ)
$(CC) $(ALL_CFLAGS) $(OBJ) --output $# $(LDFLAGS)
# Compile: create object files from C++ source files.
.cpp.o:
$(CXX) -c $(ALL_CXXFLAGS) $< -o $#
# Compile: create object files from C source files.
.c.o:
$(CC) -c $(ALL_CFLAGS) $< -o $#
# Compile: create assembler files from C source files.
.c.s:
$(CC) -S $(ALL_CFLAGS) $< -o $#
# Assemble: create object files from assembler source files.
.S.o:
$(CC) -c $(ALL_ASFLAGS) $< -o $#
# Target: clean project.
clean:
$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \
$(TARGET).map $(TARGET).sym $(TARGET).lss \
$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
depend:
if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
then \
sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
$(MAKEFILE).$$$$ && \
$(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
fi
echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
>> $(MAKEFILE); \
$(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend