mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
lkmc_vector_equal into lkmc.c
Document lkmc.c
This commit is contained in:
17
README.adoc
17
README.adoc
@@ -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.
|
||||
|
||||
==== 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
|
||||
|
||||
==== Automated tests
|
||||
|
||||
@@ -23,7 +23,7 @@ LKMC_VECTOR_TABLE
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* We need this one to not get undefined references.
|
||||
|
||||
@@ -19,9 +19,7 @@ Build the baremetal examples with crosstool-NG.
|
||||
def build(self):
|
||||
build_dir = self.get_build_dir()
|
||||
bootloader_obj = os.path.join(self.env['baremetal_build_lib_dir'], 'bootloader{}'.format(self.env['obj_ext']))
|
||||
common_basename_noext = 'lkmc'
|
||||
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'])
|
||||
common_obj = os.path.join(self.env['baremetal_build_lib_dir'], self.env['common_basename_noext'] + self.env['obj_ext'])
|
||||
syscalls_basename_noext = 'syscalls'
|
||||
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'])
|
||||
@@ -34,6 +32,7 @@ Build the baremetal examples with crosstool-NG.
|
||||
'-mcpu={}'.format(self.env['mcpu']), LF,
|
||||
'-nostartfiles', LF,
|
||||
]
|
||||
cflags_after = ['-lm']
|
||||
gcc = self.get_toolchain_tool('gcc')
|
||||
if self.env['emulator'] == 'gem5':
|
||||
if self.env['machine'] == 'VExpress_GEM5_V1':
|
||||
@@ -59,10 +58,11 @@ Build the baremetal examples with crosstool-NG.
|
||||
'-c', LF,
|
||||
'-o', bootloader_obj, LF,
|
||||
src, LF,
|
||||
]
|
||||
] +
|
||||
cflags_after
|
||||
)
|
||||
for src, obj in [
|
||||
(common_src, common_obj),
|
||||
(self.env['common_c'], common_obj),
|
||||
(syscalls_src, syscalls_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,
|
||||
'-o', obj, LF,
|
||||
src, LF,
|
||||
]
|
||||
] +
|
||||
cflags_after
|
||||
)
|
||||
self._build_dir(
|
||||
'',
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
cflags_after=cflags_after,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_objs=common_objs,
|
||||
@@ -88,6 +90,7 @@ Build the baremetal examples with crosstool-NG.
|
||||
'interactive',
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
cflags_after=cflags_after,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_objs=common_objs,
|
||||
@@ -97,6 +100,7 @@ Build the baremetal examples with crosstool-NG.
|
||||
self.env['baremetal_source_arch_subpath'],
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
cflags_after=cflags_after,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_objs=common_objs,
|
||||
@@ -107,6 +111,7 @@ Build the baremetal examples with crosstool-NG.
|
||||
arch_dir,
|
||||
gcc=gcc,
|
||||
cflags=cflags,
|
||||
cflags_after=cflags_after,
|
||||
entry_address=entry_address,
|
||||
bootloader_obj=bootloader_obj,
|
||||
common_objs=common_objs,
|
||||
@@ -121,6 +126,7 @@ Build the baremetal examples with crosstool-NG.
|
||||
subpath,
|
||||
gcc,
|
||||
cflags,
|
||||
cflags_after,
|
||||
entry_address,
|
||||
bootloader_obj,
|
||||
common_objs,
|
||||
@@ -152,7 +158,8 @@ Build the baremetal examples with crosstool-NG.
|
||||
'-c', LF,
|
||||
'-o', main_obj, LF,
|
||||
src, LF,
|
||||
]
|
||||
] +
|
||||
cflags_after
|
||||
)
|
||||
objs = common_objs + [main_obj]
|
||||
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,
|
||||
'-T', link_script, LF,
|
||||
] +
|
||||
self.sh.add_newlines(objs)
|
||||
self.sh.add_newlines(objs) +
|
||||
cflags_after
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
11
common.py
11
common.py
@@ -726,6 +726,17 @@ Valid emulators: {}
|
||||
env['baremetal_build_lib_dir'] = join(env['baremetal_build_dir'], env['baremetal_lib_basename'])
|
||||
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
|
||||
env['docker_build_dir'] = join(env['out_dir'], 'docker', env['arch'])
|
||||
env['docker_tar_dir'] = join(env['docker_build_dir'], 'export')
|
||||
|
||||
16
lkmc.c
16
lkmc.c
@@ -1,3 +1,6 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#lkmc-c */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -13,6 +16,19 @@ void lkmc_assert_fail() {
|
||||
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__)
|
||||
#define LKMC_SYSREG_READ_WRITE(type, name) \
|
||||
type LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, name), _read(void)) { \
|
||||
|
||||
6
lkmc.h
6
lkmc.h
@@ -1,13 +1,17 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#lkmc-c */
|
||||
|
||||
#ifndef LKMC_H
|
||||
#define LKMC_H
|
||||
|
||||
/* Common C definitions. */
|
||||
#if !defined(__ASSEMBLER__)
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void lkmc_assert(bool);
|
||||
void lkmc_assert_fail();
|
||||
bool lkmc_vector_equal(size_t n, double *v1, double *v2, double max_err);
|
||||
#endif
|
||||
|
||||
/* https://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg */
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <fcntl.h> /* open */
|
||||
#include <math.h> /* fabs */
|
||||
#include <stdint.h> /* uint64_t */
|
||||
#include <stdlib.h> /* size_t */
|
||||
#include <stdio.h> /* snprintf */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h> /* pread, sysconf */
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Format documented at:
|
||||
* 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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
/* https://github.com/cirosantilli/linux-kernel-module-cheat#blas
|
||||
* 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 <cblas.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
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 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);
|
||||
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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user