diff --git a/01_git/scissors/scissors-script.sh b/01_git/scissors/scissors-script.sh new file mode 100755 index 0000000..b9eb9b4 --- /dev/null +++ b/01_git/scissors/scissors-script.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +arr=( rock paper scissors ) + +RANGE=3 +number=$RANDOM +let "number %= $RANGE" + + +echo "Please choose: rock (r) - paper (p) - scissors (s)" +read -p "your choice: " choice + + +if [ $choice == r ]; then + choice=0 +elif [ $choice == p ]; then + choice=1 +elif [ $choice == s ]; then + choice=2 +fi + + + +echo You choose ${arr[$choice]}, I choose ${arr[$number]} + +if [ $choice -eq $number ]; then + echo draw!!! +elif [ $choice -eq 0 ]; then + if [ $number -eq 1 ]; then + echo You win: ${arr[$number]} beats ${arr[$choice]} + else + echo I win: ${arr[$choice]} beats ${arr[$number]} + fi +elif [ $choice -eq 1 ]; then #paper 1 + if [ $number -eq 0 ]; then #rock 0 + echo You win: ${arr[$choice]} beats ${arr[$number]} + else + echo I win: ${arr[$number]} beats ${arr[$choice]} + fi +elif [ $choice -eq 2 ]; then + if [ $number -eq 0 ]; then + echo I win: ${arr[$number]} beats ${arr[$choice]} + else + echo You win: ${arr[$choice]} beats ${arr[$number]} + fi +fi + + +# -lt less + diff --git a/02_bash/hwdetect/hwdetect.sh b/02_bash/hwdetect/hwdetect.sh new file mode 100755 index 0000000..48569d3 --- /dev/null +++ b/02_bash/hwdetect/hwdetect.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +arr1=( $(ls /dev) ) +arr2= + + +while [ 0 ] +do + + arr2=( $(ls /dev) ) + + for t in ${arr2[@]}; do + if [[ "${arr1[@]}" =~ "$t" ]]; then + continue + else + echo "New dev = $t" + fi + done + arr1=${arr2[@]} + sleep 1 +done + diff --git a/03_module/Makefile b/03_module/Makefile new file mode 100644 index 0000000..a7c0ade --- /dev/null +++ b/03_module/Makefile @@ -0,0 +1,18 @@ +BUILD_KERNEL=/home/dtretiakov/Desktop/Linux-Kernel-ProCamp-2021/linux-stable + + +obj-m+=simplest-kernel-module.o +all: build rm-trash file-push-to-qemu + +build: + make -C ${BUILD_KERNEL} M=$(PWD) modules + +clean: + make -C ${BUILD_KERNEL} M=$(PWD) clean + +rm-trash: + rm -f *.mod *.order *.o *. *.symvers *.mod.c .*.cmd + +file-push-to-qemu: + sshpass -p 'pass' scp -P 8022 *.ko user@localhost:~ + diff --git a/03_module/simplest-kernel-module.c b/03_module/simplest-kernel-module.c new file mode 100644 index 0000000..2e995d8 --- /dev/null +++ b/03_module/simplest-kernel-module.c @@ -0,0 +1,32 @@ +#include // Macros used to mark up functions __init __exit +#include // Core header for loading LKMs into the kernel +#include // Contains types, macros, functions for the kernel +#include + +static int int_param1; +static int int_param2; +module_param(int_param1, int, 0); +module_param(int_param2, int, 0); + +MODULE_LICENSE( "GPL" ); +MODULE_DESCRIPTION("A simple Linux driver."); +MODULE_VERSION("0.1"); + +static int __init hello_init( void ) { + printk( KERN_NOTICE "Hello, world!" ); + + printk( KERN_NOTICE "int1 + int2 = %d", int_param1 + int_param2 ); + + return -1; +} + +// static void __exit hello_exit( void ) { +// printk( KERN_DEBUG "Goodbye, world!" ); +// } + + +module_init( hello_init ); +//module_exit( hello_exit ); + + + diff --git a/04_basic_struct/Makefile b/04_basic_struct/Makefile new file mode 100644 index 0000000..90a0267 --- /dev/null +++ b/04_basic_struct/Makefile @@ -0,0 +1,22 @@ +BUILD_KERNEL=/home/dtretiakov/Desktop/Linux-Kernel-ProCamp-2021/linux-stable + + +obj-m+=kobject-module.o +all: build rm-trash file-push-to-qemu + +build: + make -C $(BUILD_KERNEL) M=$(PWD) modules + +clean: + make -C $(BUILD_KERNEL) M=$(PWD) clean + +rm-trash: + rm -f *.mod *.order *.o *. *.symvers *.mod.c .*.cmd + +file-push-to-qemu: + sshpass -p 'pass' scp -P 8022 *.ko user@localhost:~ + + + +# qemu +# !6770 diff --git a/04_basic_struct/kobject-module.c b/04_basic_struct/kobject-module.c new file mode 100644 index 0000000..69464c9 --- /dev/null +++ b/04_basic_struct/kobject-module.c @@ -0,0 +1,94 @@ +#include // Macros used to mark up functions __init __exit +#include // Core header for loading LKMs into the kernel +#include // Contains types, macros, functions for the kernel +#include +#include +#include +#include +#include + + +MODULE_LICENSE( "GPL" ); +MODULE_DESCRIPTION("A simple Linux..."); +MODULE_VERSION("0.1"); + +static LIST_HEAD(linkedlist); + +typedef struct my_arr_str_t { + char str [ 20 ]; + struct list_head list; +} my_arr_str_s; + +static my_arr_str_s my_arr [ 20 ]; +static unsigned int counter = 0; +//static ssize_t value = 0; + +static ssize_t my_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + int res = 0; + int cursor = 0; + struct my_arr_str_t *cur_node = NULL; + + list_for_each_entry(cur_node, &linkedlist, list){ + res = sprintf(&buf[cursor], "%s\n", cur_node->str); + + if (res > 0) + cursor += res; + + } + + + //sprintf(buf, "%u\n", value); + return strlen(buf); +} + +static ssize_t my_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + sscanf(buf, "%s\n", my_arr[counter++].str); + //pr_info("add: |%s|\n", my_arr[counter - 1].str); + //list_add( &my_arr[counter - 1].list, &my_arr[0].list ); + list_add_tail(&my_arr[counter - 1].list, &linkedlist); + return count; +} + + +static struct kobj_attribute list_attribute = + __ATTR(param, 0664, my_show, my_store); + +static struct kobject *my_kobj; + +static int my_init(void) +{ + int res = 0; + + INIT_LIST_HEAD(&my_arr[counter].list); + + my_kobj = kobject_create_and_add("my-kobj", kernel_kobj); + if (!my_kobj) + return -ENOMEM; + res = sysfs_create_file(my_kobj, &list_attribute.attr); + if (res) + kobject_put(my_kobj); + return res; +} + + + +static void my_exit(void) +{ + struct my_arr_str_t *cur_node = NULL; + struct my_arr_str_t *tmp_node = NULL; + + list_for_each_entry_safe(cur_node, tmp_node, &linkedlist, list) { + list_del(&cur_node->list); + } + + kobject_put(my_kobj); + pr_info("module exited\n"); +} + +module_init(my_init); +module_exit(my_exit); + diff --git a/05_timers/part1/Makefile b/05_timers/part1/Makefile new file mode 100644 index 0000000..2feec4b --- /dev/null +++ b/05_timers/part1/Makefile @@ -0,0 +1,10 @@ + + + + +all: + gcc timers.c -o timers + +clean: + rm -f timers + diff --git a/05_timers/part1/timers b/05_timers/part1/timers new file mode 100755 index 0000000..f5c1683 Binary files /dev/null and b/05_timers/part1/timers differ diff --git a/05_timers/part1/timers.c b/05_timers/part1/timers.c new file mode 100644 index 0000000..7063a94 --- /dev/null +++ b/05_timers/part1/timers.c @@ -0,0 +1,60 @@ +#include +#include + + + + +int main() +{ + struct timespec tp1, tp2; + + clock_gettime( CLOCK_REALTIME, &tp1 ); + clock_getres( CLOCK_REALTIME, &tp2 ); + printf ( "%s| CLOCK_REALTIME = %ld| resolution =%ld (Nanoseconds)\n",ctime(&tp1.tv_sec), tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_MONOTONIC, &tp1 ); + clock_getres( CLOCK_MONOTONIC, &tp2 ); + printf( "CLOCK_MONOTONIC = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_PROCESS_CPUTIME_ID, &tp1 ); + clock_getres( CLOCK_PROCESS_CPUTIME_ID, &tp2 ); + printf( "CLOCK_PROCESS_CPUTIME_ID = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_THREAD_CPUTIME_ID, &tp1 ); + clock_getres( CLOCK_THREAD_CPUTIME_ID, &tp2 ); + printf( "CLOCK_THREAD_CPUTIME_ID = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_MONOTONIC_RAW, &tp1 ); + clock_getres( CLOCK_MONOTONIC_RAW, &tp2 ); + printf( "CLOCK_MONOTONIC_RAW = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_REALTIME_COARSE, &tp1 ); + clock_getres( CLOCK_REALTIME_COARSE, &tp2 ); + printf( "CLOCK_REALTIME_COARSE = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_MONOTONIC_COARSE, &tp1 ); + clock_getres( CLOCK_MONOTONIC_COARSE, &tp2 ); + printf( "CLOCK_MONOTONIC_COARSE = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_BOOTTIME, &tp1 ); + clock_getres( CLOCK_BOOTTIME, &tp2 ); + printf( "CLOCK_BOOTTIME = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_REALTIME_ALARM, &tp1 ); + clock_getres( CLOCK_REALTIME_ALARM, &tp2 ); + printf( "CLOCK_BOOTTIME = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + clock_gettime( CLOCK_TAI, &tp1 ); + clock_getres( CLOCK_TAI, &tp2 ); + printf( "CLOCK_TAI = %ld| resolution =%ld (Nanoseconds)\n", tp1.tv_sec, tp2.tv_nsec ); + + + +} + + + + + + + diff --git a/05_timers/part2/Makefile b/05_timers/part2/Makefile new file mode 100644 index 0000000..1a5b5ec --- /dev/null +++ b/05_timers/part2/Makefile @@ -0,0 +1,22 @@ +BUILD_KERNEL=/home/dtretiakov/Desktop/Linux-Kernel-ProCamp-2021/linux-stable + + +obj-m+=time-module.o +all: build rm-trash file-push-to-qemu + +build: + make -C $(BUILD_KERNEL) M=$(PWD) modules + +clean: + make -C $(BUILD_KERNEL) M=$(PWD) clean + +rm-trash: + rm -f *.mod *.order *.o *. *.symvers *.mod.c .*.cmd + +file-push-to-qemu: + sshpass -p 'pass' scp -P 8022 *.ko script-test user@localhost:~ + + + +# qemu +# !6770 diff --git a/05_timers/part2/script-test b/05_timers/part2/script-test new file mode 100755 index 0000000..e7dbf93 --- /dev/null +++ b/05_timers/part2/script-test @@ -0,0 +1,5 @@ +#!/bin/bash + +dmesg -c +clear + diff --git a/05_timers/part2/time-module.c b/05_timers/part2/time-module.c new file mode 100644 index 0000000..cd93ed9 --- /dev/null +++ b/05_timers/part2/time-module.c @@ -0,0 +1,77 @@ +#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME + +#include // Core header for loading LKMs into the kernel +#include +#include +#include +#include +#include +#include + +unsigned long start = 0; +unsigned long total_time = 0; + +static ssize_t time_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + int min, sec, msec; + + total_time = jiffies - start; + + min = total_time / HZ / 60; + total_time -= min * HZ * 60; + sec = total_time / HZ; + total_time -= sec * HZ; + msec = total_time * 1000 / HZ; + + sprintf(buf, "%d min %d seconds %d milliseconds\n", min, sec, msec); + + start = jiffies; + return strlen(buf); +} + +static struct kobj_attribute list_attribute = + __ATTR(time-relative, 0664, time_show, NULL); + +static struct kobject *hello_kobj; + +static int hello_init(void) +{ + int res = 0; + + start = jiffies; + + hello_kobj = kobject_create_and_add("time-mod", kernel_kobj); + if (!hello_kobj) + return -ENOMEM; + res = sysfs_create_file(hello_kobj, &list_attribute.attr); + if (res) + kobject_put(hello_kobj); + return res; +} + +static void hello_exit(void) +{ + kobject_put(hello_kobj); + pr_info("module exited\n"); +} + +module_init(hello_init); +module_exit(hello_exit); + + + +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); + + +//get_jiffies_64() +//jiffies_to_clock_t() +//jiffies_64_to_clock_t() + +// static ssize_t hello_store(struct kobject *kobj, struct kobj_attribute *attr, +// const char *buf, size_t count) +// { +// sscanf(buf, "%lu\n", &value); +// return count; +// } \ No newline at end of file diff --git a/06_memory/part1/Makefile b/06_memory/part1/Makefile new file mode 100644 index 0000000..61e826b --- /dev/null +++ b/06_memory/part1/Makefile @@ -0,0 +1,11 @@ + + + + +all: + gcc *.c -o mem + +clean: + rm -f mem + + diff --git a/06_memory/part1/mem.c b/06_memory/part1/mem.c new file mode 100644 index 0000000..4c609af --- /dev/null +++ b/06_memory/part1/mem.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include + + + + + + +int main() { + + + + struct timespec tp1, tp2, tp_res; + + unsigned long int size; + char *p_alloc; + struct tm *my_tm; +//malloc + for( size = 1; ; size *= 2 ) + { + clock_gettime( CLOCK_REALTIME, &tp1 ); + p_alloc = (char *)malloc( size * sizeof(char)); + if( !p_alloc ) + { + printf("~~~~~Error in allocating %ld bites using %s\n", size, "malloc"); + break; + } + p_alloc[ 0 ] = 'a'; + p_alloc[ size - 1 ] = 'a'; + clock_gettime( CLOCK_REALTIME, &tp2 ); + free( p_alloc ); + + tp_res.tv_sec = tp2.tv_sec - tp1.tv_sec; + tp_res.tv_nsec = tp2.tv_nsec - tp1.tv_nsec; + my_tm = localtime(&tp_res.tv_sec); + + printf("allocate %ld bites in %d:%ld sec:nsec using %s\n", size, my_tm->tm_sec, tp_res.tv_nsec, "malloc"); + } +//calloc + for( size = 1; ; size *= 2 ) + { + clock_gettime( CLOCK_REALTIME, &tp1 ); + p_alloc = (char *)calloc( size, sizeof(char)); + if( !p_alloc ) + { + printf("~~~~~Error in allocating %ld bites using %s\n", size, "calloc"); + break; + } + p_alloc[ 0 ] = 'a'; + p_alloc[ size - 1 ] = 'a'; + clock_gettime( CLOCK_REALTIME, &tp2 ); + free( p_alloc ); + + tp_res.tv_sec = tp2.tv_sec - tp1.tv_sec; + tp_res.tv_nsec = tp2.tv_nsec - tp1.tv_nsec; + my_tm = localtime(&tp_res.tv_sec); + + printf("allocate %ld bites in %d:%ld sec:nsec using %s\n", size, my_tm->tm_sec, tp_res.tv_nsec, "calloc"); + } + +//alloca + for( size = 1; ; size *= 2 ) + { + clock_gettime( CLOCK_REALTIME, &tp1 ); + p_alloc = (char *)alloca( size * sizeof(char)); + if( !p_alloc ) + { + printf("~~~~~Error in allocating %ld bites using %s\n", size, "calloc"); + break; + } + p_alloc[ 0 ] = 'a'; + p_alloc[ size - 1 ] = 'a'; + clock_gettime( CLOCK_REALTIME, &tp2 ); + + tp_res.tv_sec = tp2.tv_sec - tp1.tv_sec; + tp_res.tv_nsec = tp2.tv_nsec - tp1.tv_nsec; + my_tm = localtime(&tp_res.tv_sec); + + printf("allocate %ld bites in %d:%ld sec:nsec using %s\n", size, my_tm->tm_sec, tp_res.tv_nsec, "calloc"); + } + +} + + + + + + diff --git a/06_memory/part1/program-output.txt b/06_memory/part1/program-output.txt new file mode 100644 index 0000000..cd8eb9e --- /dev/null +++ b/06_memory/part1/program-output.txt @@ -0,0 +1,96 @@ +allocate 1 bites in 0:212306 sec:nsec using malloc +allocate 2 bites in 0:1515 sec:nsec using malloc +allocate 4 bites in 0:500 sec:nsec using malloc +allocate 8 bites in 0:218 sec:nsec using malloc +allocate 16 bites in 0:290 sec:nsec using malloc +allocate 32 bites in 0:702 sec:nsec using malloc +allocate 64 bites in 0:399 sec:nsec using malloc +allocate 128 bites in 0:510 sec:nsec using malloc +allocate 256 bites in 0:300 sec:nsec using malloc +allocate 512 bites in 0:386 sec:nsec using malloc +allocate 1024 bites in 0:1427 sec:nsec using malloc +allocate 2048 bites in 0:12782 sec:nsec using malloc +allocate 4096 bites in 0:746 sec:nsec using malloc +allocate 8192 bites in 0:8224 sec:nsec using malloc +allocate 16384 bites in 0:7772 sec:nsec using malloc +allocate 32768 bites in 0:8495 sec:nsec using malloc +allocate 65536 bites in 0:8524 sec:nsec using malloc +allocate 131072 bites in 0:31542 sec:nsec using malloc +allocate 262144 bites in 0:17643 sec:nsec using malloc +allocate 524288 bites in 0:19016 sec:nsec using malloc +allocate 1048576 bites in 0:20736 sec:nsec using malloc +allocate 2097152 bites in 0:28149 sec:nsec using malloc +allocate 4194304 bites in 0:24094 sec:nsec using malloc +allocate 8388608 bites in 0:25149 sec:nsec using malloc +allocate 16777216 bites in 0:23619 sec:nsec using malloc +allocate 33554432 bites in 0:23297 sec:nsec using malloc +allocate 67108864 bites in 0:24643 sec:nsec using malloc +allocate 134217728 bites in 0:23332 sec:nsec using malloc +allocate 268435456 bites in 0:24945 sec:nsec using malloc +allocate 536870912 bites in 0:24147 sec:nsec using malloc +allocate 1073741824 bites in 0:25672 sec:nsec using malloc +allocate 2147483648 bites in 0:26631 sec:nsec using malloc +allocate 4294967296 bites in 0:27224 sec:nsec using malloc +allocate 8589934592 bites in 0:25921 sec:nsec using malloc +allocate 17179869184 bites in 0:27349 sec:nsec using malloc +~~~~~Error in allocating 34359738368 bites using malloc +allocate 1 bites in 0:2806 sec:nsec using calloc +allocate 2 bites in 0:1147 sec:nsec using calloc +allocate 4 bites in 0:494 sec:nsec using calloc +allocate 8 bites in 0:534 sec:nsec using calloc +allocate 16 bites in 0:758 sec:nsec using calloc +allocate 32 bites in 0:849 sec:nsec using calloc +allocate 64 bites in 0:871 sec:nsec using calloc +allocate 128 bites in 0:1350 sec:nsec using calloc +allocate 256 bites in 0:2565 sec:nsec using calloc +allocate 512 bites in 0:1240 sec:nsec using calloc +allocate 1024 bites in 0:1212 sec:nsec using calloc +allocate 2048 bites in 0:1278 sec:nsec using calloc +allocate 4096 bites in 0:1555 sec:nsec using calloc +allocate 8192 bites in 0:16190 sec:nsec using calloc +allocate 16384 bites in 0:10416 sec:nsec using calloc +allocate 32768 bites in 0:29212 sec:nsec using calloc +allocate 65536 bites in 0:62407 sec:nsec using calloc +allocate 131072 bites in 0:173423 sec:nsec using calloc +allocate 262144 bites in 0:296976 sec:nsec using calloc +allocate 524288 bites in 0:76237 sec:nsec using calloc +allocate 1048576 bites in 0:869904 sec:nsec using calloc +allocate 2097152 bites in 0:1229240 sec:nsec using calloc +allocate 4194304 bites in 0:2145134 sec:nsec using calloc +allocate 8388608 bites in 0:4076600 sec:nsec using calloc +allocate 16777216 bites in 0:8163062 sec:nsec using calloc +allocate 33554432 bites in 0:109078 sec:nsec using calloc +allocate 67108864 bites in 0:20851 sec:nsec using calloc +allocate 134217728 bites in 0:27156 sec:nsec using calloc +allocate 268435456 bites in 0:18779 sec:nsec using calloc +allocate 536870912 bites in 0:13851 sec:nsec using calloc +allocate 1073741824 bites in 0:10697 sec:nsec using calloc +allocate 2147483648 bites in 0:17557 sec:nsec using calloc +allocate 4294967296 bites in 0:11556 sec:nsec using calloc +allocate 8589934592 bites in 0:26658 sec:nsec using calloc +allocate 17179869184 bites in 0:11082 sec:nsec using calloc +~~~~~Error in allocating 34359738368 bites using calloc +allocate 1 bites in 0:183 sec:nsec using calloc +allocate 2 bites in 0:101 sec:nsec using calloc +allocate 4 bites in 0:104 sec:nsec using calloc +allocate 8 bites in 0:103 sec:nsec using calloc +allocate 16 bites in 0:103 sec:nsec using calloc +allocate 32 bites in 0:101 sec:nsec using calloc +allocate 64 bites in 0:106 sec:nsec using calloc +allocate 128 bites in 0:106 sec:nsec using calloc +allocate 256 bites in 0:101 sec:nsec using calloc +allocate 512 bites in 0:104 sec:nsec using calloc +allocate 1024 bites in 0:99 sec:nsec using calloc +allocate 2048 bites in 0:106 sec:nsec using calloc +allocate 4096 bites in 0:103 sec:nsec using calloc +allocate 8192 bites in 0:7366 sec:nsec using calloc +allocate 16384 bites in 0:8144 sec:nsec using calloc +allocate 32768 bites in 0:12292 sec:nsec using calloc +allocate 65536 bites in 0:8924 sec:nsec using calloc +allocate 131072 bites in 0:11900 sec:nsec using calloc +allocate 262144 bites in 0:16167 sec:nsec using calloc +allocate 524288 bites in 0:13975 sec:nsec using calloc +allocate 1048576 bites in 0:18651 sec:nsec using calloc +allocate 2097152 bites in 0:9932 sec:nsec using calloc +[1] 1518 segmentation fault (core dumped) ./mem + diff --git a/06_memory/part2/Makefile b/06_memory/part2/Makefile new file mode 100644 index 0000000..d33bcd3 --- /dev/null +++ b/06_memory/part2/Makefile @@ -0,0 +1,22 @@ +BUILD_KERNEL=/home/dtretiakov/Desktop/Linux-Kernel-ProCamp-2021/linux-stable + + +obj-m+=mem.o +all: build rm-trash file-push-to-qemu + +build: + make -C $(BUILD_KERNEL) M=$(PWD) modules + +clean: + make -C $(BUILD_KERNEL) M=$(PWD) clean + +rm-trash: + rm -f *.mod *.order *.o *. *.symvers *.mod.c .*.cmd + +file-push-to-qemu: + sshpass -p 'pass' scp -P 8022 *.ko script-test user@localhost:~ + + + +# qemu +# !6770 diff --git a/06_memory/part2/mem.c b/06_memory/part2/mem.c new file mode 100644 index 0000000..9558dc6 --- /dev/null +++ b/06_memory/part2/mem.c @@ -0,0 +1,86 @@ +//#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME + +#include // Core header for loading LKMs into the kernel +#include +#include +#include +#include +#include +#include +#include + +static int hello_init(void) +{ + int i = 0; + char *p_mem; + cycles_t my_c1, my_c2; + + int arr_mem_s[ 6 ] = { 1, 1000, 10000, 100000, 1000000, 4000000 }; + int arr_order[ 6 ] = { 1, 3, 4, 6, 8, 10 }; + + for(i = 0; i < 6; i++) + { + my_c1 = get_cycles(); + + p_mem = kmalloc( arr_mem_s[ i ], GFP_KERNEL ); + if( !p_mem ) + { + printk( KERN_ALERT "~~~Eror allocating %d bytes", arr_mem_s[ i ] ); + } + p_mem[0] = 'a'; + p_mem[ i - 1 ] = 'a'; + kfree( p_mem ); + + my_c2 = get_cycles(); + + printk( KERN_ALERT "***Allocating %d bytes by kmalloc in %llu cycles|", arr_mem_s[i], my_c2 - my_c1 ); + } + + for(i = 0; i < 6; i++) + { + my_c1 = get_cycles(); + + p_mem = vmalloc( arr_mem_s[ i ] ); + if( !p_mem ) + { + printk( KERN_ALERT "~~~Eror allocating %d bytes", arr_mem_s[ i ] ); + } + p_mem[0] = 'a'; + p_mem[ arr_mem_s[ i ] - 1 ] = 'a'; + vfree( p_mem ); + + my_c2 = get_cycles(); + + printk( KERN_ALERT "***Allocating %d bytes by vmalloc in %llu cycles|", arr_mem_s[i], my_c2 - my_c1 ); + } + + for(i = 0; i < 6; i++) + { + my_c1 = get_cycles(); + + p_mem = (char *)__get_free_pages( GFP_KERNEL, arr_order[ i ] ); + if( !p_mem ) + { + printk( KERN_ALERT "~~~Eror allocating %d bytes", arr_order[ i ] ); + } + p_mem[0] = 'a'; + p_mem[ arr_order[ i ] - 1 ] = 'a'; + free_pages( (unsigned long)p_mem, arr_order[ i ] ); + + my_c2 = get_cycles(); + + printk( KERN_ALERT "***Allocating %d order by __get_free_page in %llu cycles|", arr_order[i], my_c2 - my_c1 ); + } + + printk( KERN_ALERT "Hi!!!!" ); + + + return -1; +} + + +module_init(hello_init); + + +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); diff --git a/06_memory/part2/module-output.txt b/06_memory/part2/module-output.txt new file mode 100644 index 0000000..e29392f --- /dev/null +++ b/06_memory/part2/module-output.txt @@ -0,0 +1,20 @@ +[ 1008.513434] Hi!!!! +[ 1049.670295] ***Allocating 1 bytes by kmalloc in 38222 cycles| +[ 1049.671985] ***Allocating 1000 bytes by kmalloc in 23151 cycles| +[ 1049.672150] ***Allocating 10000 bytes by kmalloc in 211510 cycles| +[ 1049.672694] ***Allocating 100000 bytes by kmalloc in 995190 cycles| +[ 1049.674384] ***Allocating 1000000 bytes by kmalloc in 3233686 cycles| +[ 1049.674626] ***Allocating 4000000 bytes by kmalloc in 110011 cycles| +[ 1049.674808] ***Allocating 1 bytes by vmalloc in 242158 cycles| +[ 1049.674891] ***Allocating 1000 bytes by vmalloc in 54342 cycles| +[ 1049.674983] ***Allocating 10000 bytes by vmalloc in 55056 cycles| +[ 1049.675159] ***Allocating 100000 bytes by vmalloc in 186199 cycles| +[ 1049.675425] ***Allocating 1000000 bytes by vmalloc in 397430 cycles| +[ 1049.677217] ***Allocating 4000000 bytes by vmalloc in 3335679 cycles| +[ 1049.677338] ***Allocating 1 order by __get_free_page in 57214 cycles| +[ 1049.677402] ***Allocating 3 order by __get_free_page in 15859 cycles| +[ 1049.677475] ***Allocating 4 order by __get_free_page in 63890 cycles| +[ 1049.677929] ***Allocating 6 order by __get_free_page in 721659 cycles| +[ 1049.678010] ***Allocating 8 order by __get_free_page in 24715 cycles| +[ 1049.678079] ***Allocating 10 order by __get_free_page in 51659 cycles| + diff --git a/06_memory/part2/script-test b/06_memory/part2/script-test new file mode 100755 index 0000000..e7dbf93 --- /dev/null +++ b/06_memory/part2/script-test @@ -0,0 +1,5 @@ +#!/bin/bash + +dmesg -c +clear + diff --git a/07_procfs/Makefile b/07_procfs/Makefile new file mode 100644 index 0000000..d166680 --- /dev/null +++ b/07_procfs/Makefile @@ -0,0 +1,24 @@ +BUILD_KERNEL=/home/dtretiakov/Desktop/Linux-Kernel-ProCamp-2021/buildroot/output/build/linux-5.12.2 +export ARCH=arm +export CROSS_COMPILE=/home/dtretiakov/Desktop/Linux-Kernel-ProCamp-2021/buildroot/output/host/usr/bin/arm-linux- + + +obj-m+=kobject-module-update.o +all: build rm-trash file-push-to-qemu + +build: + make -C $(BUILD_KERNEL) M=$(PWD) modules + +clean: + make -C $(BUILD_KERNEL) M=$(PWD) clean + +rm-trash: + rm -f *.mod *.order *.o *. *.symvers *.mod.c .*.cmd + +file-push-to-qemu: + sshpass -p 'pass' scp -P 22 *.ko root@192.168.3.91:~ + + + +# qemu +# !6770 diff --git a/07_procfs/kobject-module-update.c b/07_procfs/kobject-module-update.c new file mode 100644 index 0000000..d0e27a9 --- /dev/null +++ b/07_procfs/kobject-module-update.c @@ -0,0 +1,173 @@ +#include // Macros used to mark up functions __init __exit +#include // Core header for loading LKMs into the kernel +#include // Contains types, macros, functions for the kernel +#include +#include +#include +#include +#include +#include + + +MODULE_LICENSE( "GPL" ); +MODULE_DESCRIPTION("A simple Linux..."); +MODULE_VERSION("0.1"); + +static LIST_HEAD(linkedlist); + +typedef struct my_arr_str_t { + char str [ 20 ]; + struct list_head list; +} my_arr_str_s; + + +static my_arr_str_s my_arr [ 20 ]; +static unsigned int counter = 0; +static unsigned int store_counter = 0; +static unsigned int show_counter = 0; +char *author_name = "denys\n"; +char msg [ 40 ] = { 0 }; + +static ssize_t my_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + int res = 0; + int cursor = 0; + struct my_arr_str_t *cur_node = NULL; + + list_for_each_entry(cur_node, &linkedlist, list){ + res = sprintf(&buf[cursor], "%s\n", cur_node->str); + + if (res > 0) + cursor += res; + + } + show_counter++; + //sprintf(buf, "%u\n", value); + return strlen(buf); +} + +static ssize_t my_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + sscanf(buf, "%s\n", my_arr[counter++].str); + //pr_info("add: |%s|\n", my_arr[counter - 1].str); + //list_add( &my_arr[counter - 1].list, &my_arr[0].list ); + list_add_tail(&my_arr[counter - 1].list, &linkedlist); + store_counter++; + return count; +} + + +static ssize_t myread(struct file *file, char __user *pbuf, size_t count, loff_t *ppos) +{ + sprintf(msg, "%u\n", show_counter); + + int len = strlen( msg ); + //printk( KERN_INFO "=== read : %ld\n", (long)count ); + if( count < len ) return -EINVAL; + if( *ppos != 0 ) { + //printk( KERN_INFO "=== read return : 0\n" ); // EOF + return 0; + } + if( copy_to_user( pbuf, msg, len ) ) return -EINVAL; + *ppos = len; + //printk( KERN_INFO "=== read return : %d\n", len ); + return len; +} + +static ssize_t myread1(struct file *file, char __user *pbuf, size_t count, loff_t *ppos) +{ + sprintf(msg, "%u\n", store_counter); + + int len = strlen( msg ); + //printk( KERN_INFO "=== read : %ld\n", (long)count ); + if( count < len ) return -EINVAL; + if( *ppos != 0 ) { + //printk( KERN_INFO "=== read return : 0\n" ); // EOF + return 0; + } + if( copy_to_user( pbuf, msg, len ) ) return -EINVAL; + *ppos = len; + //printk( KERN_INFO "=== read return : %d\n", len ); + return len; +} + +static ssize_t myread2(struct file *file, char __user *pbuf, size_t count, loff_t *ppos) +{ + int len = strlen( author_name ); + //printk( KERN_INFO "=== read : %ld\n", (long)count ); + if( count < len ) return -EINVAL; + if( *ppos != 0 ) { + //printk( KERN_INFO "=== read return : 0\n" ); // EOF + return 0; + } + if( copy_to_user( pbuf, author_name, len ) ) return -EINVAL; + *ppos = len; + //printk( KERN_INFO "=== read return : %d\n", len ); + return len; +} + +static struct kobj_attribute list_attribute = + __ATTR(param, 0664, my_show, my_store); + +static struct kobject *my_kobj; + +//procfs +static struct proc_ops myops = +{ + .proc_read = myread, +}; +static struct proc_ops myops1 = +{ + .proc_read = myread1, +}; +static struct proc_ops myops2 = +{ + .proc_read = myread2, +}; + +static struct proc_dir_entry *ent; +static struct proc_dir_entry *ent1; +static struct proc_dir_entry *ent2; +// + +static int my_init(void) +{ + int res = 0; +//procfs + ent = proc_create("my-show_counter", 0666, NULL, &myops); + ent1 = proc_create("my-store_counter", 0666, NULL, &myops1); + ent2 = proc_create("my-author_name", 0666, NULL, &myops2); + + INIT_LIST_HEAD(&my_arr[counter].list); + + my_kobj = kobject_create_and_add("my-kobj", kernel_kobj); + if (!my_kobj) + return -ENOMEM; + res = sysfs_create_file(my_kobj, &list_attribute.attr); + if (res) + kobject_put(my_kobj); + return res; +} + + + +static void my_exit(void) +{ + struct my_arr_str_t *cur_node = NULL; + struct my_arr_str_t *tmp_node = NULL; + + list_for_each_entry_safe(cur_node, tmp_node, &linkedlist, list) { + list_del(&cur_node->list); + } + proc_remove(ent); + proc_remove(ent1); + proc_remove(ent2); + kobject_put(my_kobj); + pr_info("module exited\n"); +} + +module_init(my_init); +module_exit(my_exit); + diff --git a/07_procfs/log.txt b/07_procfs/log.txt new file mode 100644 index 0000000..80b5d35 --- /dev/null +++ b/07_procfs/log.txt @@ -0,0 +1,23 @@ +# insmod *.ko +# cat /proc/mydev +cat: can't open '/proc/mydev': No such file or directory +# cat /proc/my- +my-author_name my-show_counter my-store_counter +# cat /proc/my-show_counter +0 +# cat /proc/my-store_counter +0 +# cat /proc/my-author_name +denys +# echo asdfsd > /sys/kernel/my-kobj/param +# cat /proc/my-store_counter +1 +# cat /sys/kernel/my-kobj/param +asdfsd +# cat /proc/my-store_counter +1 +# cat /proc/my-show_counter +1 +# cat /proc/my-author_name +denys +# diff --git a/08_irq_handling/Makefile b/08_irq_handling/Makefile new file mode 100644 index 0000000..2dcff43 --- /dev/null +++ b/08_irq_handling/Makefile @@ -0,0 +1,24 @@ +BUILD_KERNEL=/home/dtretiakov/Desktop/Camps/Linux-Kernel-ProCamp-2021/buildroot/output/build/linux-5.12.2 +export ARCH=arm +export CROSS_COMPILE=/home/dtretiakov/Desktop/Camps/Linux-Kernel-ProCamp-2021/buildroot/output/host/usr/bin/arm-linux- + + +obj-m+=led_mod.o +all: build rm-trash file-push-to-qemu + +build: + make -C $(BUILD_KERNEL) M=$(PWD) modules + +clean: + make -C $(BUILD_KERNEL) M=$(PWD) clean + +rm-trash: + rm -f *.mod *.order *.o *. *.symvers *.mod.c .*.cmd + +file-push-to-qemu: + sshpass -p 'pass' scp -P 22 *.ko root@192.168.3.91:~ + + + +# qemu +# !6770 diff --git a/08_irq_handling/led_mod.c b/08_irq_handling/led_mod.c index 5444623..0394bd3 100644 --- a/08_irq_handling/led_mod.c +++ b/08_irq_handling/led_mod.c @@ -22,7 +22,7 @@ */ #define LED_GREEN GPIO_NUMBER(11, 10) -#define LED_RED GPIO_NUMBER(0, 15) +#define LED_RED GPIO_NUMBER(0, 17) #define BUTTON GPIO_NUMBER(6, 7) //#define TIMER_ENABLE 1 @@ -33,6 +33,10 @@ static int button_gpio = -1; static int button_state = -1; static int button_cnt = -1; +static int button_irq = -1; +static int dev_id = 0; +static int irq_counter = 0; + #ifdef TIMER_ENABLE static ktime_t timer_period; struct hrtimer button_timer; @@ -42,16 +46,25 @@ static enum hrtimer_restart timer_callback(struct hrtimer *timer) int cur_button_state; cur_button_state = gpio_get_value(button_gpio); - button_cnt = (cur_button_state == button_state) ? (button_cnt + 1) : 0; + button_cnt = (cur_button_state == 1) ? (button_cnt + 1) : 0; button_state = cur_button_state; - gpio_set_value(ledr_gpio, ((button_cnt == 20) ? 1 : 0)); - if (button_cnt >= 20) + + gpio_set_value(ledr_gpio, ((button_cnt > 20) ? 1 : 0)); + if (button_cnt < 20) gpio_set_value(ledg_gpio, !button_state); hrtimer_forward(timer, timer->base->get_time(), timer_period); return HRTIMER_RESTART; //restart timer } #endif +static irqreturn_t my_interrupt(int irq, void* devid) +{ + irq_counter++; + pr_info("In the ISR: counter = %d\n", irq_counter); + pr_info("in irq(): %s\n", in_irq()? "Y" : "N"); + return IRQ_NONE; +} + static int led_gpio_init(int gpio, int *led_gpio) { int res; @@ -81,6 +94,9 @@ static int button_gpio_init(int gpio) button_state = gpio_get_value(button_gpio); button_cnt = 0; + + button_irq = gpio_to_irq(gpio); + return 0; err_input: @@ -113,6 +129,16 @@ static int __init gpio_poll_init(void) hrtimer_start(&button_timer, timer_period, HRTIMER_MODE_REL); button_timer.function = timer_callback; #endif +//IRQ + if (request_irq(button_irq, my_interrupt, IRQF_SHARED, "my_interr", &dev_id)) { + res = -1; + pr_info("mymodule: failed to load\n"); + } else { + pr_info("mymodule: module loaded, irq handled on IRQ = %d\n", button_irq); + pr_info("TASK: in irq(): %s\n", in_irq()? "Y" : "N"); + } +// + res = led_gpio_init(LED_GREEN, &ledg_gpio); if (res != 0) { pr_err("Can't set GPIO%d for output\n", LED_GREEN); @@ -126,7 +152,7 @@ static int __init gpio_poll_init(void) pr_err("Can't set GPIO%d for output\n", LED_RED); goto err_led; } - gpio_set_value(ledr_gpio, 1); + gpio_set_value(ledr_gpio, 0); return 0; @@ -140,6 +166,11 @@ static void __exit gpio_poll_exit(void) gpio_set_value(ledg_gpio, 0); gpio_set_value(ledr_gpio, 0); button_gpio_deinit(); +//IRQ + synchronize_irq(button_irq); + free_irq(button_irq, &dev_id); + pr_info("module exited, counter: %d\n", irq_counter); +// #ifdef TIMER_ENABLE hrtimer_cancel(&button_timer); #endif @@ -151,4 +182,8 @@ module_exit(gpio_poll_exit); MODULE_AUTHOR("Oleksandr Posukhov oleksandr.posukhov@gmail.com>"); MODULE_DESCRIPTION("LED Test"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); \ No newline at end of file +MODULE_VERSION("0.1"); + + + +