Factor common userland and baremetal C functions

This allows add.c to run unmodified on both!

For that to work, use int main on baremetal, and pass the return value to
the final exit.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2018-11-15 00:00:00 +00:00
parent ecc2a21b57
commit 26b890f42f
26 changed files with 87 additions and 52 deletions

View File

@@ -1,6 +1,6 @@
#include <common.h> #include <common.h>
void main(void) { int main(void) {
int i, j, k; int i, j, k;
i = 1; i = 1;
/* test-gdb-op1 */ /* test-gdb-op1 */
@@ -9,5 +9,5 @@ void main(void) {
k = i + j; k = i + j;
/* test-gdb-result */ /* test-gdb-result */
if (k != 3) if (k != 3)
assert_fail(); common_assert_fail();
} }

View File

@@ -7,6 +7,6 @@ main:
/* test-gdb-result */ /* test-gdb-result */
cmp x1, #3 cmp x1, #3
beq 1f beq 1f
bl assert_fail bl common_assert_fail
1: 1:
ret ret

View File

@@ -12,7 +12,7 @@ main:
fmov d3, #4.0 fmov d3, #4.0
fcmp d2, d3 fcmp d2, d3
beq 1f beq 1f
bl assert_fail bl common_assert_fail
1: 1:
/* Now in 32-bit. */ /* Now in 32-bit. */
@@ -26,7 +26,7 @@ main:
fmov s3, #4.0 fmov s3, #4.0
fcmp s2, s3 fcmp s2, s3
beq 1f beq 1f
bl assert_fail bl common_assert_fail
1: 1:
/* Higher registers. */ /* Higher registers. */
@@ -40,6 +40,6 @@ main:
/* test-gdb-d31 */ /* test-gdb-d31 */
fcmp d30, d31 fcmp d30, d31
beq 1f beq 1f
bl assert_fail bl common_assert_fail
1: 1:
ret ret

View File

@@ -7,6 +7,6 @@ main:
/* test-gdb-result */ /* test-gdb-result */
cmp r1, #3 cmp r1, #3
beq 1f beq 1f
bl assert_fail bl common_assert_fail
1: 1:
bx lr bx lr

View File

@@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void main(void) { int main(void) {
exit(0); exit(0);
} }

View File

@@ -1,6 +1,6 @@
#include <common.h> #include <common.h>
void main(void) { int main(void) {
assert_fail(); common_assert_fail();
} }

View File

@@ -1,6 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void main(void) { int main(void) {
exit(1); exit(1);
} }

View File

@@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
void main(void) { int main(void) {
puts("hello"); puts("hello");
return 0;
} }

View File

@@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void main(void) { int main(void) {
char c; char c;
char *ptr = NULL; char *ptr = NULL;
size_t alloc_size = 1; size_t alloc_size = 1;
@@ -19,4 +19,3 @@ void main(void) {
} }
} }
} }

View File

@@ -0,0 +1 @@
int main(void) { return 1; }

View File

@@ -8,5 +8,4 @@ mystart:
ldr x0, =stack_top ldr x0, =stack_top
mov sp, x0 mov sp, x0
bl main bl main
mov x0, #0
bl exit bl exit

View File

@@ -2,5 +2,4 @@
mystart: mystart:
ldr sp, =stack_top ldr sp, =stack_top
bl main bl main
mov r0, #0
bl exit bl exit

View File

@@ -1,4 +0,0 @@
#ifndef COMMON_H
#define COMMON_H
void assert_fail();
#endif

View File

@@ -86,8 +86,3 @@ void _exit(int status) {
#endif #endif
#endif #endif
} }
void assert_fail() {
puts("lkmc_test_fail");
exit(1);
}

View File

@@ -1 +1 @@
void main(void) {} int main(void) { return 0; }

View File

@@ -9,9 +9,16 @@ class BaremetalComponent(common.Component):
common.assert_crosstool_ng_supports_arch(args.arch) common.assert_crosstool_ng_supports_arch(args.arch)
build_dir = self.get_build_dir(args) build_dir = self.get_build_dir(args)
bootloader_obj = os.path.join(common.baremetal_build_lib_dir, 'bootloader{}'.format(common.obj_ext)) bootloader_obj = os.path.join(common.baremetal_build_lib_dir, 'bootloader{}'.format(common.obj_ext))
common_obj = os.path.join(common.baremetal_build_lib_dir, 'common{}'.format(common.obj_ext)) common_basename_noext = 'common'
common_src = os.path.join(common.root_dir, common_basename_noext + common.c_ext)
common_obj = os.path.join(common.baremetal_build_lib_dir, common_basename_noext + common.obj_ext)
syscalls_basename_noext = 'syscalls'
syscalls_src = os.path.join(common.baremetal_src_lib_dir, syscalls_basename_noext + common.c_ext)
syscalls_obj = os.path.join(common.baremetal_build_lib_dir, syscalls_basename_noext + common.obj_ext)
common_objs = [common_obj, syscalls_obj]
cflags = [ cflags = [
'-I', common.baremetal_src_lib_dir, common.Newline, '-I', common.baremetal_src_lib_dir, common.Newline,
'-I', common.root_dir, common.Newline,
'-O0', common.Newline, '-O0', common.Newline,
'-ggdb3', common.Newline, '-ggdb3', common.Newline,
'-mcpu={}'.format(common.mcpu), common.Newline, '-mcpu={}'.format(common.mcpu), common.Newline,
@@ -46,23 +53,27 @@ class BaremetalComponent(common.Component):
os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), common.Newline, os.path.join(common.baremetal_src_lib_dir, '{}{}'.format(args.arch, common.asm_ext)), common.Newline,
] ]
) )
common.run_cmd( for src, obj in [
[gcc, common.Newline] + (common_src, common_obj),
cflags + (syscalls_src, syscalls_obj),
[ ]:
'-c', common.Newline, common.run_cmd(
'-D', 'UART0_ADDR={:#x}'.format(uart_address), common.Newline, [gcc, common.Newline] +
'-o', common_obj, common.Newline, cflags +
os.path.join(common.baremetal_src_lib_dir, 'common' + common.c_ext), common.Newline, [
] '-c', common.Newline,
) '-D', 'UART0_ADDR={:#x}'.format(uart_address), common.Newline,
'-o', obj, common.Newline,
src, common.Newline,
]
)
self._build_dir( self._build_dir(
'', '',
gcc=gcc, gcc=gcc,
cflags=cflags, cflags=cflags,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_obj=common_obj, common_objs=common_objs,
) )
self._build_dir( self._build_dir(
'interactive', 'interactive',
@@ -70,7 +81,7 @@ class BaremetalComponent(common.Component):
cflags=cflags, cflags=cflags,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_obj=common_obj, common_objs=common_objs,
) )
arch_dir = os.path.join('arch', args.arch) arch_dir = os.path.join('arch', args.arch)
if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)): if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)):
@@ -80,7 +91,7 @@ class BaremetalComponent(common.Component):
cflags=cflags, cflags=cflags,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_obj=common_obj, common_objs=common_objs,
) )
arch_dir = os.path.join('arch', args.arch, 'no_bootloader') arch_dir = os.path.join('arch', args.arch, 'no_bootloader')
if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)): if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)):
@@ -90,7 +101,7 @@ class BaremetalComponent(common.Component):
cflags=cflags, cflags=cflags,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_obj=common_obj, common_objs=common_objs,
bootloader=False, bootloader=False,
) )
@@ -107,7 +118,16 @@ Build the baremetal examples with crosstool-NG.
def get_default_args(self): def get_default_args(self):
return {'baremetal': 'all'} return {'baremetal': 'all'}
def _build_dir(self, subpath, gcc, cflags, entry_address, bootloader_obj, common_obj, bootloader=True): def _build_dir(
self,
subpath,
gcc,
cflags,
entry_address,
bootloader_obj,
common_objs,
bootloader=True
):
""" """
Build all .c and .S files in a given subpath of the baremetal source Build all .c and .S files in a given subpath of the baremetal source
directory non recursively. directory non recursively.
@@ -144,8 +164,8 @@ Build the baremetal examples with crosstool-NG.
'-T', os.path.join(common.baremetal_src_dir, 'link.ld'), common.Newline, '-T', os.path.join(common.baremetal_src_dir, 'link.ld'), common.Newline,
] + ] +
bootloader_cmd + bootloader_cmd +
common.add_newlines(common_objs) +
[ [
common_obj, common.Newline,
main_obj, common.Newline, main_obj, common.Newline,
] ]
) )

View File

@@ -58,6 +58,8 @@ has the OpenBLAS libraries and headers installed.
[ [
'make', common.Newline, 'make', common.Newline,
'-j', str(args.nproc), common.Newline, '-j', str(args.nproc), common.Newline,
'CCFLAGS_SCRIPT={} {}'.format('-I', common.userland_src_dir), common.Newline,
'COMMON_DIR={}'.format(common.root_dir), common.Newline,
'CC={}'.format(cc), common.Newline, 'CC={}'.format(cc), common.Newline,
'CXX={}'.format(cxx), common.Newline, 'CXX={}'.format(cxx), common.Newline,
'PKG_CONFIG={}'.format(common.buildroot_pkg_config), common.Newline, 'PKG_CONFIG={}'.format(common.buildroot_pkg_config), common.Newline,

7
common.c Normal file
View File

@@ -0,0 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
void common_assert_fail() {
puts("lkmc_test_fail");
exit(1);
}

8
common.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef COMMON_H
#define COMMON_H
/* Common baremetal and userland functionality. */
void common_assert_fail();
#endif

View File

@@ -1,13 +1,17 @@
.PHONY: all clean mkdir .PHONY: all clean mkdir
CCFLAGS = -ggdb3 -I$(COMMON_DIR) -O0 -Wall -Werror -Wextra -Wno-unused-function $(CCFLAGS_EXTRA) $(CCFLAGS_SCRIPT)
CFLAGS = -fopenmp -std=c99 $(CCFLAGS) $(CFLAGS_EXTRA) CFLAGS = -fopenmp -std=c99 $(CCFLAGS) $(CFLAGS_EXTRA)
CXXFLAGS = -std=c++17 $(CCFLAGS) $(CXXFLAGS_EXTRA) CXXFLAGS = -std=c++17 $(CCFLAGS) $(CXXFLAGS_EXTRA)
# -Wno-unused-function for function definitions on headers, # -Wno-unused-function for function definitions on headers,
# because we are lazy to make a shared object. TODO. # because we are lazy to make a shared object. TODO.
CCFLAGS = -ggdb3 -O0 -Wall -Werror -Wextra -Wno-unused-function $(CCFLAGS_EXTRA) COMMON_DIR = ..
COMMON_BASENAME = common
COMMON_OBJ = $(OUT_DIR)/$(COMMON_BASENAME)$(OBJ_EXT)
IN_EXT_C = .c IN_EXT_C = .c
IN_EXT_CXX = .cpp IN_EXT_CXX = .cpp
LIBS = -lm LIBS = -lm
OBJ_EXT = .o
OUT_EXT = .out OUT_EXT = .out
OUT_DIR = . OUT_DIR = .
@@ -38,14 +42,17 @@ OUTS := $(addprefix $(OUT_DIR)/,$(OUTS))
all: mkdir $(OUTS) all: mkdir $(OUTS)
$(OUT_DIR)/%$(OUT_EXT): %$(IN_EXT_C) $(COMMON_OBJ): $(COMMON_DIR)/$(COMMON_BASENAME)$(IN_EXT_C)
$(CC) $(CFLAGS) -o '$@' '$<' $(LIBS) $(CC) $(CFLAGS) -c -o '$@' '$<' $(LIBS)
$(OUT_DIR)/%$(OUT_EXT): %$(IN_EXT_CXX) $(OUT_DIR)/%$(OUT_EXT): %$(IN_EXT_C) $(COMMON_OBJ)
$(CC) $(CFLAGS) $(COMMON_OBJ) -o '$@' '$<' $(LIBS)
$(OUT_DIR)/%$(OUT_EXT): %$(IN_EXT_CXX) $(COMMON_OBJ)
$(CXX) $(CXXFLAGS) -o '$@' '$<' $(LIBS) $(CXX) $(CXXFLAGS) -o '$@' '$<' $(LIBS)
clean: clean:
rm -f *'$(OUT_EXT)' rm -f *'$(OBJ_EXT)' *'$(OUT_EXT)'
mkdir: mkdir:
mkdir -p '$(OUT_DIR)' mkdir -p '$(OUT_DIR)'

1
userland/add.c Symbolic link
View File

@@ -0,0 +1 @@
../baremetal/add.c

View File

@@ -10,7 +10,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> /* sysconf */ #include <unistd.h> /* sysconf */
#include "common.h" /* virt_to_phys_user */ #include "common_userland.h" /* virt_to_phys_user */
enum { BUFFER_SIZE = 4 }; enum { BUFFER_SIZE = 4 };

View File

@@ -1,7 +1,7 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#blas /* https://github.com/cirosantilli/linux-kernel-module-cheat#blas
* Adapted from: https://github.com/xianyi/OpenBLAS/wiki/User-Manual/59b62f98e7400270fb03ad1d85fba5b64ebbff2b#call-cblas-interface */ * Adapted from: https://github.com/xianyi/OpenBLAS/wiki/User-Manual/59b62f98e7400270fb03ad1d85fba5b64ebbff2b#call-cblas-interface */
#include "common.h" #include "common_userland.h"
#include <assert.h> #include <assert.h>
#include <cblas.h> #include <cblas.h>

View File

@@ -9,7 +9,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "common.h" /* pagemap_get_entry */ #include "common_userland.h" /* pagemap_get_entry */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {

View File

@@ -4,7 +4,7 @@
#include <stdio.h> /* printf */ #include <stdio.h> /* printf */
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE, strtoull */ #include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE, strtoull */
#include "common.h" /* virt_to_phys_user */ #include "common_userland.h" /* virt_to_phys_user */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {