diff --git a/src/02-driver/.clangd b/src/02-driver/.clangd new file mode 100644 index 0000000..7c98f3d --- /dev/null +++ b/src/02-driver/.clangd @@ -0,0 +1,13 @@ +CompileFlags: + Add: + # Architecture and cross-compilation + - "--target=aarch64-linux-gnu" + + # Setup sysroot for buildroot + - "--sysroot=/buildroot/output/host/aarch64-buildroot-linux-gnu/sysroot" + + # Add specific header of linux from buildroot + - "-I/buildroot/output/build/linux-headers-5.15.148/include" + - "-I/buildroot/output/build/linux-headers-5.15.148/arch/arm64/include" + - "-I/buildroot/output/build/linux-headers-5.15.148/arch/arm64/include/generated" + - "-I/buildroot/output/build/linux-headers-5.15.148/**" diff --git a/src/02-driver/Makefile b/src/02-driver/Makefile new file mode 100644 index 0000000..7feae3f --- /dev/null +++ b/src/02-driver/Makefile @@ -0,0 +1,44 @@ +EXE=app +SRCS=$(wildcard *.c) + +ifeq ($(target),) +target=nano +endif + +CFLAGS=-Wall -Wextra -g -c -O0 -MD -std=gnu11 + +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CFLAGS+=-mcpu=cortex-a53 -funwind-tables +##CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/nano +EXEC=$(EXE) + +CC=$(TOOLCHAIN)gcc +LD=$(TOOLCHAIN)gcc +AR=$(TOOLCHAIN)ar +STRIP=$(TOOLCHAIN)strip + +OBJDIR=.obj/$(target) +OBJS= $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +$(OBJDIR)/%o: %c + $(CC) $(CFLAGS) $< -o $@ + +all: $(OBJDIR)/ $(EXEC) + +$(EXEC): $(OBJS) $(LINKER_SCRIPT) + $(LD) $(OBJS) $(LDFLAGS) -o $@ + +$(OBJDIR)/: + mkdir -p $(OBJDIR) + +clean: + rm -Rf $(OBJDIR) $(EXEC) $(EXEC)_s *~ + +clean_all: clean + rm -Rf .obj $(EXE) $(EXE)_s $(EXE)_a $(EXE)_a_s $(EXE)_h $(EXE)_h_s + +-include $(OBJS:.o=.d) + +.PHONY: all clean clean_all diff --git a/src/02-driver/dts/.clangd b/src/02-driver/dts/.clangd new file mode 100644 index 0000000..d940495 --- /dev/null +++ b/src/02-driver/dts/.clangd @@ -0,0 +1,33 @@ +CompileFlags: + Add: + # Architecture and cross-compilation + - "--target=aarch64-linux-gnu" + + # Exclude standard library + - "-nostdinc" + + # Mandatory kernel definitions + - "-D__KERNEL__" + - "-DMODULE" + - "-DCONFIG_CC_HAS_K_CONSTRAINT=1" + + # Force-included files + - "-include" + - "/buildroot/output/build/linux-5.15.148/include/linux/compiler-version.h" + - "-include" + - "/buildroot/output/build/linux-5.15.148/include/linux/kconfig.h" + - "-include" + - "/buildroot/output/build/linux-5.15.148/include/linux/compiler_types.h" + + # Kernel include paths + - "-I/buildroot/output/build/linux-5.15.148/arch/arm64/include" + - "-I/buildroot/output/build/linux-5.15.148/arch/arm64/include/generated" + - "-I/buildroot/output/build/linux-5.15.148/include" + - "-I/buildroot/output/build/linux-5.15.148/arch/arm64/include/uapi" + - "-I/buildroot/output/build/linux-5.15.148/arch/arm64/include/generated/uapi" + - "-I/buildroot/output/build/linux-5.15.148/include/uapi" + - "-I/buildroot/output/build/linux-5.15.148/include/generated/uapi" + + # GCC compiler system include path + - "-isystem" + - "/buildroot/output/host/lib/gcc/aarch64-buildroot-linux-gnu/11.3.0/include" diff --git a/src/02-driver/dts/Makefile b/src/02-driver/dts/Makefile new file mode 100644 index 0000000..5ea736b --- /dev/null +++ b/src/02-driver/dts/Makefile @@ -0,0 +1,37 @@ +# Part executed when called from kernel build system: +ifneq ($(KERNELRELEASE),) +obj-m += mymodule.o ## name of the generated module + +ccflags-y += -Wno-declaration-after-statement -std=gnu11 +mymodule-objs := skeleton.o ## list of objects needed for that module + +# Part executed when called from standard make in module source directory: +else +include ../../kernel_settings +PWD := $(shell pwd) + +INCL+=-I. -I$(KDIR)/include -I$(KDIR)/arch/arm64/boot/dts +DTB = mydt.dtb +DTS = $(DTB:.dtb=.dts) + +all: dtb boot + $(MAKE) -C $(KDIR) M=$(PWD) ARCH=$(CPU) CROSS_COMPILE=$(TOOLS) modules + +dtb: $(DTB) +$(DTB) : $(DTS) + ln -s $(KDIR)/arch/arm/boot/dts arm + -cpp $(INCL) -E -P -x assembler-with-cpp $(DTS) | dtc -I dts -O dtb -o $(DTB) - + rm arm + +boot: + mkimage -T script -A arm -C none -d boot.cmd boot.ovl + +clean: + $(MAKE) -C $(KDIR) M=$(PWD) clean + rm -f *.dtb *.ovl + +install: + $(MAKE) -C $(KDIR) M=$(PWD) INSTALL_MOD_PATH=$(MODPATH) modules_install + +endif + diff --git a/src/02-driver/dts/boot.cmd b/src/02-driver/dts/boot.cmd new file mode 100644 index 0000000..1780fdb --- /dev/null +++ b/src/02-driver/dts/boot.cmd @@ -0,0 +1,10 @@ +setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait + +fatload mmc 0 $kernel_addr_r Image +#fatload mmc 0 $fdt_addr_r nanopi-neo-plus2.dtb +fatload mmc 0 $fdt_addr_r mydt.dtb + +fdt addr $fdt_addr_r +fdt resize + +booti $kernel_addr_r - $fdt_addr_r diff --git a/src/02-driver/dts/mydt.dts b/src/02-driver/dts/mydt.dts new file mode 100644 index 0000000..66f5564 --- /dev/null +++ b/src/02-driver/dts/mydt.dts @@ -0,0 +1,12 @@ +/dts-v1/; + +#include "allwinner/sun50i-h5-nanopi-neo-plus2.dts" + +/ { + /delete-node/ leds; + + mydevice { + compatible = "mydevice"; + attribute = "text"; + }; +}; diff --git a/src/02-driver/dts/skeleton.c b/src/02-driver/dts/skeleton.c new file mode 100644 index 0000000..d97bdde --- /dev/null +++ b/src/02-driver/dts/skeleton.c @@ -0,0 +1,135 @@ +/* skeleton.c */ +#include /* needed for macros */ +#include /* needed for debugging */ +#include /* needed by all modules */ + +#include /* needed for char device driver */ +#include /* needed for device drivers */ +#include /* needed to copy data to/from user */ + +#include /* needed for sysfs handling */ +#include +#include +#include /* needed for sysfs handling */ + +static int skeleton_open(struct inode* i, struct file* f) +{ + pr_info("skeleton : open operation... major:%d, minor:%d\n", + imajor(i), + iminor(i)); + return 0; +} + +static int skeleton_release(struct inode* i, struct file* f) +{ + pr_info("skeleton: release operation...\n"); + return 0; +} + +static ssize_t skeleton_read(struct file* f, + char __user* buf, + size_t count, + loff_t* off) +{ + pr_info("skeleton: read operation... read=%ld\n", count); + return 0; +} + +static ssize_t skeleton_write(struct file* f, + const char __user* buf, + size_t count, + loff_t* off) +{ + pr_info("skeleton: write operation... written=%ld\n", count); + return count; +} + +static struct file_operations fops = { + .owner = THIS_MODULE, + .open = skeleton_open, + .read = skeleton_read, + .write = skeleton_write, + .release = skeleton_release, +}; + +struct miscdevice misc_device = { + .minor = MISC_DYNAMIC_MINOR, + .fops = &fops, + .name = "mydevice", + .mode = 0777, +}; + +int skeleton_probe(struct platform_device* pdev) +{ + pr_info("skeleton - driver probe %llx (%s)- M.m=%d.%d\n", + (unsigned long long)pdev, + pdev->name, + MAJOR(pdev->dev.devt), + MINOR(pdev->dev.devt)); + + // register misc device ... + int ret = misc_register(&misc_device); + + // read device tree attribute + struct device_node* dt_node = pdev->dev.of_node; + const char* prop = 0; + if (dt_node) + ret = of_property_read_string(dt_node, "attribute", &prop); + else + pr_info("mymodule not found!\n"); + if ((prop != 0) && (ret == 0)) + pr_info("attribute=%s (ret=%d)\n", prop, ret); + + return 0; +} +int skeleton_remove(struct platform_device* pdev) +{ + pr_info("skeleton - sysfs driver remove %llx\n", (unsigned long long)pdev); + misc_deregister(&misc_device); + return 0; +} +void skeleton_shutdown(struct platform_device* pdev) +{ + pr_info("skeleton - sysfs driver shutdown %s\n", pdev->name); +} + +struct of_device_id of_skeleton[] = { + { + .compatible = "mydevice", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_skeleton); + +static struct platform_driver sysfs_driver = { + .probe = skeleton_probe, + .remove = skeleton_remove, + .shutdown = skeleton_shutdown, + .driver = + { + .name = "mydriver", + .of_match_table = of_match_ptr(of_skeleton), + }, +}; + +static int __init skeleton_init(void) +{ + pr_info("Linux module skeleton loading...\n"); + int status = platform_driver_register(&sysfs_driver); + pr_info("Linux module skeleton loaded\n"); + return status; +} + +static void __exit skeleton_exit(void) +{ + pr_info("Linux module skeleton exiting...\n"); + platform_driver_unregister(&sysfs_driver); + pr_info("Linux module skeleton unloaded\n"); +} + +module_init(skeleton_init); +module_exit(skeleton_exit); + +MODULE_AUTHOR("Daniel Gachet "); +MODULE_DESCRIPTION("Module skeleton"); +MODULE_LICENSE("GPL"); diff --git a/src/02-driver/main.c b/src/02-driver/main.c new file mode 100644 index 0000000..56f4346 --- /dev/null +++ b/src/02-driver/main.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +int main() { + + int fd = open() + + + + return 0; +}