aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Sangdahl <[email protected]>2024-04-02 23:08:19 -0600
committerJack Sangdahl <[email protected]>2024-04-02 23:08:19 -0600
commit4b0d366a6665a70921dedb26c9ed5bdc7cd5c948 (patch)
treeb10db80f6dc3ef49a79a1bff83725d4b31f3b2da
downloadcsci3753-4b0d366a6665a70921dedb26c9ed5bdc7cd5c948.tar.gz
csci3753-4b0d366a6665a70921dedb26c9ed5bdc7cd5c948.zip
pa1
-rw-r--r--.gitignore9
-rw-r--r--pa1_syscalls_lkms/csci3753_mult.c12
-rw-r--r--pa1_syscalls_lkms/csci3753_mult_test.c13
-rw-r--r--pa1_syscalls_lkms/helloworld.c8
-rw-r--r--pa1_syscalls_lkms/helloworld_test.c8
-rw-r--r--pa1_syscalls_lkms/modules/Makefile4
-rw-r--r--pa1_syscalls_lkms/modules/hellomodule.c20
-rw-r--r--pa1_syscalls_lkms/readme.md58
8 files changed, 132 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f1ed751
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+*.pdf
+*.o
+*.ko
+*/.gdb_history
+pa2_file_tester/pa2test
+pa4_shared_array/shared_array
+pa5_dns_resolver/lookup
+pa6_threaded_resolver/multi-lookup
+pa7_lru/test*
diff --git a/pa1_syscalls_lkms/csci3753_mult.c b/pa1_syscalls_lkms/csci3753_mult.c
new file mode 100644
index 0000000..cfe9458
--- /dev/null
+++ b/pa1_syscalls_lkms/csci3753_mult.c
@@ -0,0 +1,12 @@
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/syscalls.h>
+
+SYSCALL_DEFINE3(csci3753_mult, int, number1, int, number2, long *, result) {
+ printk("Numbers being multiplied:\n");
+ printk("Number 1: %d\n", number1);
+ printk("Number 2: %d\n", number2);
+ long product = number1 * number2;
+ printk("Result: %ld\n", product);
+ return copy_to_user(result, &product, sizeof(long)) ? -EFAULT : 0;
+}
diff --git a/pa1_syscalls_lkms/csci3753_mult_test.c b/pa1_syscalls_lkms/csci3753_mult_test.c
new file mode 100644
index 0000000..116737a
--- /dev/null
+++ b/pa1_syscalls_lkms/csci3753_mult_test.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define SYS_CALL_NUM 463
+
+int main(int argc, char **argv) {
+ if (argc < 3)
+ exit(-1);
+ int a = atoi(argv[1]), b = atoi(argv[2]);
+ long c, res = syscall(SYS_CALL_NUM, a, b, &c);
+ printf("%d * %d = %ld\n", a, b, c);
+ exit(res);
+}
diff --git a/pa1_syscalls_lkms/helloworld.c b/pa1_syscalls_lkms/helloworld.c
new file mode 100644
index 0000000..b712465
--- /dev/null
+++ b/pa1_syscalls_lkms/helloworld.c
@@ -0,0 +1,8 @@
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/syscalls.h>
+
+SYSCALL_DEFINE0(helloworld) {
+ printk(KERN_ALERT "hello world\n");
+ return 0;
+}
diff --git a/pa1_syscalls_lkms/helloworld_test.c b/pa1_syscalls_lkms/helloworld_test.c
new file mode 100644
index 0000000..ddb9037
--- /dev/null
+++ b/pa1_syscalls_lkms/helloworld_test.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <stdlib.h>
+#define SYS_CALL_NUM 462
+
+int main() {
+ long res = syscall(SYS_CALL_NUM);
+ exit(res);
+}
diff --git a/pa1_syscalls_lkms/modules/Makefile b/pa1_syscalls_lkms/modules/Makefile
new file mode 100644
index 0000000..34b0157
--- /dev/null
+++ b/pa1_syscalls_lkms/modules/Makefile
@@ -0,0 +1,4 @@
+obj-m += hellomodule.o
+
+all:
+ make -C /lib/modules/`uname -r`/build M=`pwd`
diff --git a/pa1_syscalls_lkms/modules/hellomodule.c b/pa1_syscalls_lkms/modules/hellomodule.c
new file mode 100644
index 0000000..0d92e22
--- /dev/null
+++ b/pa1_syscalls_lkms/modules/hellomodule.c
@@ -0,0 +1,20 @@
+#include <linux/init.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("jasa7131");
+MODULE_LICENSE("GPL");
+
+int hello_init(void);
+void hello_exit(void);
+
+int hello_init(void) {
+ printk(KERN_ALERT "inside %s function\n", __FUNCTION__);
+ return 0;
+}
+
+void hello_exit(void) {
+ printk(KERN_ALERT "inside %s function\n", __FUNCTION__);
+}
+
+module_init(hello_init);
+module_exit(hello_exit);
diff --git a/pa1_syscalls_lkms/readme.md b/pa1_syscalls_lkms/readme.md
new file mode 100644
index 0000000..86855f9
--- /dev/null
+++ b/pa1_syscalls_lkms/readme.md
@@ -0,0 +1,58 @@
+## PA1 - Syscalls & LKMs
+### Adding a system call (6.6.11)
+create file `arch/x86/kernel/helloworld.c` and note the following
+* `kernel.h` header contains many constants and functions in kernel programming
+* `linkage.h` header defines macros used to keep stack safe & orderly
+* `syscalls.h` header contains `SYSCALL_DEFINEn` macros where `n` is the number of parameters being passed to system call
+* `printk()` is used to print kernel messages (eg. dmesg)
+
+add `obj-y+=helloworld.o` to `arch/x86/kernel/Makefile` to link object
+file of our system call. next, add system call to table. edit
+`arch/x86/entry/syscalls/syscall_64.tbl` with
+`454 common helloworld sys_helloworld`. a prototype for our system call
+is needed. add `asmlinkage long sys_helloworld(void);` to
+`include/linux/syscalls.h`. all system calls are prefixed with `sys_`
+by convention. `asmlinkage` keyword tells the compiler that the function
+should not expect to find any of its arguments in registers, but only
+on the cpu's stack (see `linkage.h` file)
+
+### Writing a test program
+an additional userspace program is needed to test the new system call.
+the first argument to `syscall()` function is our system call number,
+and any additional arguments would be passed system call function.
+returns 0 on success, and -1 otherwise. , then compile and test program
+and view the output of `dmesg` and look for our `print()` contents
+```sh
+cc hellotest.c
+./a.out
+echo $?
+0 # no error
+```
+
+### Writing a second system call
+create file `arch/x86/kernel/csci3753_mult.c` and write system call number
+455 named `csci3753_mult()` and define two integer arguments: `num1, num2`
+and a pointer to the integer integer result (long). the system call must
+do the following:
+* use `printk()` to log the numbers being multiplied
+* multiply those two numbers
+* use `printk()` to log the result
+* store the result in userspace via the return pointer
+ * account for the fact that kernel cannot directly write to userspace memory
+* return appropriate status (0 for success, non-zero for failure)
+
+again, a userspace program will be needed to test the system call's
+functionality. see `csci3753_mult_test.c` file and use above steps.
+
+### Loadable Kernel Modules (LKMs)
+allow for code to be loaded into kernel at runtime without the need to
+recompile and reboot kernel. `CONFIG_MODULES` must be built and
+configured. note the following about `modules/hellomodule.c`:
+* `linux/{init.h, module.h}` contain library headers for module initialisation
+* `module_init()` and `module_exit()` bind two functions, `hello_init()`
+and `hello_exit()` to be executed when the module is loaded/unloaded
+
+after compilation (see `modules/Makefile`), the new `*.ko` moddule file
+can be loaded with `insmod hellomodule.ko`, and unloaded using
+`rmmod hellomodule.ko`. now, view output of dmesg to see what's been
+printed.