lkmc_vector_equal into lkmc.c

Document lkmc.c
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-02-20 00:00:04 +00:00
parent e44362b394
commit d5e16fd8ae
8 changed files with 118 additions and 80 deletions

View File

@@ -12990,6 +12990,23 @@ ls /mnt/9p/rootfs_overlay
This way you can just hack away the scripts and try them out immediately without any further operations. This way you can just hack away the scripts and try them out immediately without any further operations.
==== lkmc.c
The files:
* link:lkmc.c[]
* link:lkmc.h[]
contain common C function helpers that can be used both in userland and baremetal. Oh, the infinite <<about-the-baremetal-setup,joys of Newlib>>.
Those files also contain arch specific helpers under ifdefs like:
....
#if defined(__aarch64__)
....
We try to keep as much as possible in those files. It bloats builds a little, but just makes everything simpler to understand.
=== Test this repo === Test this repo
==== Automated tests ==== Automated tests

View File

@@ -23,7 +23,7 @@ LKMC_VECTOR_TABLE
/* Default trap handler that does nothing. /* Default trap handler that does nothing.
* *
* Weak means that if any other file deinfes it as a non-weak global, * Weak means that if any other file defines it as a non-weak global,
* that one will take precedence. * that one will take precedence.
* *
* We need this one to not get undefined references. * We need this one to not get undefined references.

View File

@@ -19,9 +19,7 @@ Build the baremetal examples with crosstool-NG.
def build(self): def build(self):
build_dir = self.get_build_dir() build_dir = self.get_build_dir()
bootloader_obj = os.path.join(self.env['baremetal_build_lib_dir'], 'bootloader{}'.format(self.env['obj_ext'])) bootloader_obj = os.path.join(self.env['baremetal_build_lib_dir'], 'bootloader{}'.format(self.env['obj_ext']))
common_basename_noext = 'lkmc' common_obj = os.path.join(self.env['baremetal_build_lib_dir'], self.env['common_basename_noext'] + self.env['obj_ext'])
common_src = os.path.join(self.env['root_dir'], common_basename_noext + self.env['c_ext'])
common_obj = os.path.join(self.env['baremetal_build_lib_dir'], common_basename_noext + self.env['obj_ext'])
syscalls_basename_noext = 'syscalls' syscalls_basename_noext = 'syscalls'
syscalls_src = os.path.join(self.env['baremetal_source_lib_dir'], syscalls_basename_noext + self.env['c_ext']) syscalls_src = os.path.join(self.env['baremetal_source_lib_dir'], syscalls_basename_noext + self.env['c_ext'])
syscalls_obj = os.path.join(self.env['baremetal_build_lib_dir'], syscalls_basename_noext + self.env['obj_ext']) syscalls_obj = os.path.join(self.env['baremetal_build_lib_dir'], syscalls_basename_noext + self.env['obj_ext'])
@@ -34,6 +32,7 @@ Build the baremetal examples with crosstool-NG.
'-mcpu={}'.format(self.env['mcpu']), LF, '-mcpu={}'.format(self.env['mcpu']), LF,
'-nostartfiles', LF, '-nostartfiles', LF,
] ]
cflags_after = ['-lm']
gcc = self.get_toolchain_tool('gcc') gcc = self.get_toolchain_tool('gcc')
if self.env['emulator'] == 'gem5': if self.env['emulator'] == 'gem5':
if self.env['machine'] == 'VExpress_GEM5_V1': if self.env['machine'] == 'VExpress_GEM5_V1':
@@ -59,10 +58,11 @@ Build the baremetal examples with crosstool-NG.
'-c', LF, '-c', LF,
'-o', bootloader_obj, LF, '-o', bootloader_obj, LF,
src, LF, src, LF,
] ] +
cflags_after
) )
for src, obj in [ for src, obj in [
(common_src, common_obj), (self.env['common_c'], common_obj),
(syscalls_src, syscalls_obj), (syscalls_src, syscalls_obj),
]: ]:
if self.need_rebuild([src], obj): if self.need_rebuild([src], obj):
@@ -74,12 +74,14 @@ Build the baremetal examples with crosstool-NG.
'-D', 'UART0_ADDR={:#x}'.format(uart_address), LF, '-D', 'UART0_ADDR={:#x}'.format(uart_address), LF,
'-o', obj, LF, '-o', obj, LF,
src, LF, src, LF,
] ] +
cflags_after
) )
self._build_dir( self._build_dir(
'', '',
gcc=gcc, gcc=gcc,
cflags=cflags, cflags=cflags,
cflags_after=cflags_after,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_objs=common_objs, common_objs=common_objs,
@@ -88,6 +90,7 @@ Build the baremetal examples with crosstool-NG.
'interactive', 'interactive',
gcc=gcc, gcc=gcc,
cflags=cflags, cflags=cflags,
cflags_after=cflags_after,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_objs=common_objs, common_objs=common_objs,
@@ -97,6 +100,7 @@ Build the baremetal examples with crosstool-NG.
self.env['baremetal_source_arch_subpath'], self.env['baremetal_source_arch_subpath'],
gcc=gcc, gcc=gcc,
cflags=cflags, cflags=cflags,
cflags_after=cflags_after,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_objs=common_objs, common_objs=common_objs,
@@ -107,6 +111,7 @@ Build the baremetal examples with crosstool-NG.
arch_dir, arch_dir,
gcc=gcc, gcc=gcc,
cflags=cflags, cflags=cflags,
cflags_after=cflags_after,
entry_address=entry_address, entry_address=entry_address,
bootloader_obj=bootloader_obj, bootloader_obj=bootloader_obj,
common_objs=common_objs, common_objs=common_objs,
@@ -121,6 +126,7 @@ Build the baremetal examples with crosstool-NG.
subpath, subpath,
gcc, gcc,
cflags, cflags,
cflags_after,
entry_address, entry_address,
bootloader_obj, bootloader_obj,
common_objs, common_objs,
@@ -152,7 +158,8 @@ Build the baremetal examples with crosstool-NG.
'-c', LF, '-c', LF,
'-o', main_obj, LF, '-o', main_obj, LF,
src, LF, src, LF,
] ] +
cflags_after
) )
objs = common_objs + [main_obj] objs = common_objs + [main_obj]
out = os.path.join(self.env['baremetal_build_dir'], subpath, in_name + self.env['baremetal_build_ext']) out = os.path.join(self.env['baremetal_build_dir'], subpath, in_name + self.env['baremetal_build_ext'])
@@ -166,7 +173,8 @@ Build the baremetal examples with crosstool-NG.
'-o', out, LF, '-o', out, LF,
'-T', link_script, LF, '-T', link_script, LF,
] + ] +
self.sh.add_newlines(objs) self.sh.add_newlines(objs) +
cflags_after
) )
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -726,6 +726,17 @@ Valid emulators: {}
env['baremetal_build_lib_dir'] = join(env['baremetal_build_dir'], env['baremetal_lib_basename']) env['baremetal_build_lib_dir'] = join(env['baremetal_build_dir'], env['baremetal_lib_basename'])
env['baremetal_build_ext'] = '.elf' env['baremetal_build_ext'] = '.elf'
# Userland / baremetal common source.
env['common_basename_noext'] = 'lkmc'
env['common_c'] = common_c = os.path.join(
env['root_dir'],
env['common_basename_noext'] + env['c_ext']
)
env['common_h'] = common_c = os.path.join(
env['root_dir'],
env['common_basename_noext'] + env['header_ext']
)
# Docker # Docker
env['docker_build_dir'] = join(env['out_dir'], 'docker', env['arch']) env['docker_build_dir'] = join(env['out_dir'], 'docker', env['arch'])
env['docker_tar_dir'] = join(env['docker_build_dir'], 'export') env['docker_tar_dir'] = join(env['docker_build_dir'], 'export')

16
lkmc.c
View File

@@ -1,3 +1,6 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#lkmc-c */
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -13,6 +16,19 @@ void lkmc_assert_fail() {
exit(1); exit(1);
} }
bool lkmc_vector_equal(size_t n, double *v1, double *v2, double max_err) {
double sum = 0.0;
double diff;
size_t i;
for (i = 0; i < n; ++i) {
diff = v1[i] - v2[i];
sum += diff * diff;
}
if (sqrt(sum)/n > max_err)
return false;
return true;
}
#if defined(__aarch64__) #if defined(__aarch64__)
#define LKMC_SYSREG_READ_WRITE(type, name) \ #define LKMC_SYSREG_READ_WRITE(type, name) \
type LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, name), _read(void)) { \ type LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, name), _read(void)) { \

6
lkmc.h
View File

@@ -1,13 +1,17 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#lkmc-c */
#ifndef LKMC_H #ifndef LKMC_H
#define LKMC_H #define LKMC_H
/* Common C definitions. */ /* Common C definitions. */
#if !defined(__ASSEMBLER__) #if !defined(__ASSEMBLER__)
#include <stdbool.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
void lkmc_assert(bool); void lkmc_assert(bool);
void lkmc_assert_fail(); void lkmc_assert_fail();
bool lkmc_vector_equal(size_t n, double *v1, double *v2, double max_err);
#endif #endif
/* https://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg */ /* https://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg */

View File

@@ -3,13 +3,10 @@
#define _XOPEN_SOURCE 700 #define _XOPEN_SOURCE 700
#include <fcntl.h> /* open */ #include <fcntl.h> /* open */
#include <math.h> /* fabs */
#include <stdint.h> /* uint64_t */ #include <stdint.h> /* uint64_t */
#include <stdlib.h> /* size_t */
#include <stdio.h> /* snprintf */ #include <stdio.h> /* snprintf */
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> /* pread, sysconf */ #include <unistd.h> /* pread, sysconf */
#include <stdbool.h>
/* Format documented at: /* Format documented at:
* https://github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemap.txt * https://github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemap.txt
@@ -84,18 +81,4 @@ int virt_to_phys_user(uintptr_t *paddr, pid_t pid, uintptr_t vaddr)
return 0; return 0;
} }
bool common_vector_equal(size_t n, double * v1, double * v2, double max_err)
{
double sum = 0.0;
double diff;
size_t i;
for (i = 0; i < n; ++i) {
diff = v1[i] - v2[i];
sum += diff * diff;
}
if (sqrt(sum)/n > max_err)
return false;
return true;
}
#endif #endif

View File

@@ -1,16 +1,15 @@
/* 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_userland.h" #include "lkmc.h"
#include <assert.h> #include <assert.h>
#include <cblas.h> #include <cblas.h>
int main(void) int main(void) {
{
double A[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0}; double A[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0};
double B[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0}; double B[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0};
double C[9] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}; double C[9] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5};
cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans, 3, 3, 2, 1, A, 3, B, 3, 2, C, 3); cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans, 3, 3, 2, 1, A, 3, B, 3, 2, C, 3);
assert(common_vector_equal(9, C, (double[]){11.0, -9.0, 5.0, -9.0, 21.0, -1.0, 5.0, -1.0, 3.0}, 1e-6)); assert(lkmc_vector_equal(9, C, (double[]){11.0, -9.0, 5.0, -9.0, 21.0, -1.0, 5.0, -1.0, 3.0}, 1e-6));
} }