-
Notifications
You must be signed in to change notification settings - Fork 564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GSoC Warm Up Kernel Task #234
base: 5.4-rt
Are you sure you want to change the base?
Changes from 1 commit
c5e4c6b
22a2dc9
c3a3c6b
2f57cda
8281f5b
0bc8f99
54153c8
8f19c19
3c0d1df
003a340
e622153
1077271
b353c94
04f98f1
1fe65cd
5a0574b
19d6993
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -535,6 +535,12 @@ config ADI | |
and SSM (Silicon Secured Memory). Intended consumers of this | ||
driver include crash and makedumpfile. | ||
|
||
config GSOC_DUMMY_CHAR_DEVICE | ||
tristate "GSoC Warmup Driver" | ||
help | ||
This builds the GSoC Dummy Char Driver, which is required for the warmup task. | ||
Say Y to build it into the kernel, M to build it as a module and N to not build it. | ||
|
||
endmenu | ||
|
||
config RANDOM_TRUST_CPU | ||
|
@@ -559,4 +565,5 @@ config RANDOM_TRUST_BOOTLOADER | |
device randomness. Say Y here to assume the entropy provided by the | ||
booloader is trustworthy so it will be added to the kernel's entropy | ||
pool. Otherwise, say N here so it will be regarded as device input that | ||
only mixes the entropy pool. | ||
only mixes the entropy pool. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Watch out for unintentional changes like editors that automatically add a newline at the end of the file. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/* | ||
* GSoC Dummy Driver for warm up exercise | ||
* | ||
* Author: Niklas Wantrupp <[email protected]> | ||
* based on | ||
* Dummy character driver by | ||
* John Madieu <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using SPDX license identifier is used nowdays instead of license paragraphs. https://www.kernel.org/doc/html/latest/process/license-rules.html |
||
* modify it under the terms of the GNU General Public License | ||
* version 2 as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <linux/fs.h> | ||
#include <linux/version.h> | ||
#include <linux/device.h> | ||
#include <linux/cdev.h> | ||
#include <linux/uaccess.h> | ||
|
||
static int gsoc_char_dev_open(struct inode * inode, struct file * file); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It probably depends on the area of the kernel but most code I have seen tries to avoid forward declarations if possible by rearranging the code. |
||
static int gsoc_char_dev_close(struct inode * inode, struct file * file); | ||
static ssize_t gsoc_char_dev_read(struct file *file, char __user * buf, size_t count, | ||
loff_t * offset); | ||
static ssize_t gsoc_char_dev_write(struct file * file, const char __user * buf, size_t count, | ||
loff_t * offset); | ||
static int gsoc_char_dev_uevent(struct device *dev, struct kobj_uevent_env *env); | ||
|
||
static unsigned int major; | ||
static struct class *gsoc_dummy_class; | ||
static struct cdev gsoc_dummy_device; | ||
|
||
static const struct file_operations gsoc_dummy_dev_file_ops = { | ||
.open = gsoc_char_dev_open, | ||
.release = gsoc_char_dev_close, | ||
.read = gsoc_char_dev_read, | ||
.write = gsoc_char_dev_write, | ||
}; | ||
|
||
static int __init gsoc_dummy_char_dev_init_module(void) | ||
{ | ||
struct device *dummy_device; | ||
int err; | ||
dev_t gsoc_dev; | ||
|
||
// register a range of char dev numbers 0 to 1 in this case | ||
err = alloc_chrdev_region(&gsoc_dev, 0, 1, "gsoc_dummy_char_dev"); | ||
if (err < 0) { | ||
pr_err("Can't get major number\n"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a good idea to include the module name in the error message so users know which module the error came from. |
||
return err; | ||
} | ||
major = MAJOR(gsoc_dev); | ||
pr_info("gsoc_dummy_char_dev major number = %d\n",major); | ||
|
||
// Create sysfs class | ||
gsoc_dummy_class = class_create(THIS_MODULE, "gsoc_dummy_char_dev_class"); | ||
|
||
if (IS_ERR(gsoc_dummy_class)) { | ||
pr_err("GSoC char device class could not be created.\n"); | ||
unregister_chrdev_region(MKDEV(major, 0), 1); | ||
return PTR_ERR(gsoc_dummy_class); | ||
} | ||
|
||
gsoc_dummy_class->dev_uevent = gsoc_char_dev_uevent; | ||
|
||
// Create device and bind file ops | ||
cdev_init(&gsoc_dummy_device, &gsoc_dummy_dev_file_ops); | ||
gsoc_dummy_device.owner = THIS_MODULE; | ||
|
||
// add device to system | ||
cdev_add(&gsoc_dummy_device, gsoc_dev, 1); | ||
|
||
// create device node | ||
dummy_device = device_create(gsoc_dummy_class, NULL, gsoc_dev, NULL, "gsoc_dummy_char_dev"); | ||
|
||
if (IS_ERR(dummy_device)) { | ||
pr_err("GSoC char device could not be created.\n"); | ||
class_destroy(gsoc_dummy_class); | ||
unregister_chrdev_region(gsoc_dev, 1); | ||
return -1; | ||
} | ||
|
||
pr_info("loaded GSoC dummy driver\n"); | ||
return 0; | ||
} | ||
|
||
static void __exit gsoc_dummy_char_dev_exit_module(void) | ||
{ | ||
unregister_chrdev_region(MKDEV(major, 0), 1); | ||
device_destroy(gsoc_dummy_class, MKDEV(major, 0)); | ||
cdev_del(&gsoc_dummy_device); | ||
class_destroy(gsoc_dummy_class); | ||
|
||
pr_info("unloaded GSoC dummy driver\n"); | ||
} | ||
|
||
static int gsoc_char_dev_open(struct inode * inode, struct file * file) | ||
{ | ||
pr_info("Open function of GSoC dummy driver called.\n"); | ||
return 0; | ||
} | ||
|
||
static int gsoc_char_dev_close(struct inode * inode, struct file * file) | ||
{ | ||
pr_info("Close function of GSoC dummy driver called.\n"); | ||
return 0; | ||
} | ||
|
||
static ssize_t gsoc_char_dev_read(struct file *file, char __user * buf, size_t count, | ||
loff_t * offset) | ||
{ | ||
pr_info("Read function of GSoC dummy driver called.\n"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be fun to actually put something in the buffer so that you can actually read something from the character device. |
||
return 0; | ||
} | ||
|
||
static ssize_t gsoc_char_dev_write(struct file * file, const char __user * buf, size_t count, | ||
loff_t * offset) | ||
{ | ||
pr_info("Write function of GSoC dummy driver called.\n"); | ||
return count; | ||
} | ||
|
||
static int gsoc_char_dev_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
{ | ||
add_uevent_var(env, "DEVMODE=%#o", 0666); | ||
return 0; | ||
} | ||
|
||
module_init(gsoc_dummy_char_dev_init_module); | ||
module_exit(gsoc_dummy_char_dev_exit_module); | ||
|
||
MODULE_AUTHOR("Niklas Wantrupp <[email protected]>"); | ||
MODULE_DESCRIPTION("GSoC warm up dummy char device driver"); | ||
MODULE_LICENSE("GPL"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Help lines should be indented with 1 tab + 2 spaces