mirror of
https://github.com/sysprog21/lkmpg.git
synced 2024-11-22 15:05:54 +08:00
Enforce Linux kernel coding style (#88)
The only exception is to indent with four spaces rather than tabs for sticking to compact layout of source listing. Close #87
This commit is contained in:
parent
6110f8ee3c
commit
eef2bc4395
|
@ -1,15 +1,94 @@
|
||||||
BasedOnStyle: Chromium
|
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
MaxEmptyLinesToKeep: 3
|
|
||||||
IndentCaseLabels: false
|
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
PointerAlignment: Right
|
|
||||||
SpaceAfterCStyleCast: true
|
|
||||||
TabWidth: 4
|
|
||||||
UseTab: Never
|
|
||||||
IndentWidth: 4
|
|
||||||
BreakBeforeBraces: Linux
|
|
||||||
AccessModifierOffset: -4
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakBeforeTernaryOperators: false
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: false
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: false
|
||||||
|
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: false
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp03
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
|
@ -36,3 +36,6 @@ all:
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
||||||
$(RM) other/cat_noblock *.plist
|
$(RM) other/cat_noblock *.plist
|
||||||
|
|
||||||
|
indent:
|
||||||
|
clang-format -i *[.ch]
|
||||||
|
|
|
@ -21,19 +21,19 @@
|
||||||
#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L)
|
#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int button_irqs[] = {-1, -1};
|
static int button_irqs[] = { -1, -1 };
|
||||||
|
|
||||||
/* Define GPIOs for LEDs.
|
/* Define GPIOs for LEDs.
|
||||||
* TODO: Change the numbers for the GPIO on your board.
|
* TODO: Change the numbers for the GPIO on your board.
|
||||||
*/
|
*/
|
||||||
static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}};
|
static struct gpio leds[] = { { 4, GPIOF_OUT_INIT_LOW, "LED 1" } };
|
||||||
|
|
||||||
/* Define GPIOs for BUTTONS
|
/* Define GPIOs for BUTTONS
|
||||||
* TODO: Change the numbers for the GPIO on your board.
|
* TODO: Change the numbers for the GPIO on your board.
|
||||||
*/
|
*/
|
||||||
static struct gpio buttons[] = {
|
static struct gpio buttons[] = {
|
||||||
{17, GPIOF_IN, "LED 1 ON BUTTON"},
|
{ 17, GPIOF_IN, "LED 1 ON BUTTON" },
|
||||||
{18, GPIOF_IN, "LED 1 OFF BUTTON"},
|
{ 18, GPIOF_IN, "LED 1 OFF BUTTON" },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tasklet containing some non-trivial amount of processing */
|
/* Tasklet containing some non-trivial amount of processing */
|
||||||
|
@ -106,7 +106,6 @@ static int __init bottomhalf_init(void)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = gpio_to_irq(buttons[1].gpio);
|
ret = gpio_to_irq(buttons[1].gpio);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -21,14 +21,14 @@ static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
|
||||||
|
|
||||||
#define SUCCESS 0
|
#define SUCCESS 0
|
||||||
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */
|
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */
|
||||||
#define BUF_LEN 80 /* Max length of the message from the device */
|
#define BUF_LEN 80 /* Max length of the message from the device */
|
||||||
|
|
||||||
/* Global variables are declared as static, so are global within the file. */
|
/* Global variables are declared as static, so are global within the file. */
|
||||||
|
|
||||||
static int major; /* major number assigned to our device driver */
|
static int major; /* major number assigned to our device driver */
|
||||||
static int open_device_cnt = 0; /* Is device open?
|
static int open_device_cnt = 0; /* Is device open?
|
||||||
* Used to prevent multiple access to device */
|
* Used to prevent multiple access to device */
|
||||||
static char msg[BUF_LEN]; /* The msg the device will give when asked */
|
static char msg[BUF_LEN]; /* The msg the device will give when asked */
|
||||||
static char *msg_ptr;
|
static char *msg_ptr;
|
||||||
|
|
||||||
static struct class *cls;
|
static struct class *cls;
|
||||||
|
@ -105,8 +105,8 @@ static int device_release(struct inode *inode, struct file *file)
|
||||||
* read from it.
|
* read from it.
|
||||||
*/
|
*/
|
||||||
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
|
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
|
||||||
char *buffer, /* buffer to fill with data */
|
char *buffer, /* buffer to fill with data */
|
||||||
size_t length, /* length of the buffer */
|
size_t length, /* length of the buffer */
|
||||||
loff_t *offset)
|
loff_t *offset)
|
||||||
{
|
{
|
||||||
/* Number of bytes actually written to the buffer */
|
/* Number of bytes actually written to the buffer */
|
||||||
|
@ -134,9 +134,7 @@ static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when a process writes to dev file: echo "hi" > /dev/hello */
|
/* Called when a process writes to dev file: echo "hi" > /dev/hello */
|
||||||
static ssize_t device_write(struct file *filp,
|
static ssize_t device_write(struct file *filp, const char *buff, size_t len,
|
||||||
const char *buff,
|
|
||||||
size_t len,
|
|
||||||
loff_t *off)
|
loff_t *off)
|
||||||
{
|
{
|
||||||
pr_alert("Sorry, this operation is not supported.\n");
|
pr_alert("Sorry, this operation is not supported.\n");
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
/* Get the n'th byte of the message */
|
/* Get the n'th byte of the message */
|
||||||
#define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int)
|
#define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int)
|
||||||
/* The IOCTL is used for both input and output. It receives from the user
|
/* The IOCTL is used for both input and output. It receives from the user
|
||||||
* a number, n, and returns Message[n].
|
* a number, n, and returns message[n].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The name of the device file */
|
/* The name of the device file */
|
||||||
|
|
|
@ -20,15 +20,15 @@
|
||||||
/* Is the device open right now? Used to prevent concurrent access into
|
/* Is the device open right now? Used to prevent concurrent access into
|
||||||
* the same device
|
* the same device
|
||||||
*/
|
*/
|
||||||
static int Device_Open = 0;
|
static int open_device_cnt = 0;
|
||||||
|
|
||||||
/* The message the device will give when asked */
|
/* The message the device will give when asked */
|
||||||
static char Message[BUF_LEN];
|
static char message[BUF_LEN];
|
||||||
|
|
||||||
/* How far did the process reading the message get? Useful if the message
|
/* How far did the process reading the message get? Useful if the message
|
||||||
* is larger than the size of the buffer we get to fill in device_read.
|
* is larger than the size of the buffer we get to fill in device_read.
|
||||||
*/
|
*/
|
||||||
static char *Message_Ptr;
|
static char *message_ptr;
|
||||||
|
|
||||||
static struct class *cls;
|
static struct class *cls;
|
||||||
|
|
||||||
|
@ -38,12 +38,12 @@ static int device_open(struct inode *inode, struct file *file)
|
||||||
pr_info("device_open(%p)\n", file);
|
pr_info("device_open(%p)\n", file);
|
||||||
|
|
||||||
/* We don't want to talk to two processes at the same time. */
|
/* We don't want to talk to two processes at the same time. */
|
||||||
if (Device_Open)
|
if (open_device_cnt)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
Device_Open++;
|
open_device_cnt++;
|
||||||
/* Initialize the message */
|
/* Initialize the message */
|
||||||
Message_Ptr = Message;
|
message_ptr = message;
|
||||||
try_module_get(THIS_MODULE);
|
try_module_get(THIS_MODULE);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ static int device_release(struct inode *inode, struct file *file)
|
||||||
pr_info("device_release(%p,%p)\n", inode, file);
|
pr_info("device_release(%p,%p)\n", inode, file);
|
||||||
|
|
||||||
/* We're now ready for our next caller */
|
/* We're now ready for our next caller */
|
||||||
Device_Open--;
|
open_device_cnt--;
|
||||||
|
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -62,9 +62,9 @@ static int device_release(struct inode *inode, struct file *file)
|
||||||
/* This function is called whenever a process which has already opened the
|
/* This function is called whenever a process which has already opened the
|
||||||
* device file attempts to read from it.
|
* device file attempts to read from it.
|
||||||
*/
|
*/
|
||||||
static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
|
static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
|
||||||
char __user *buffer, /* buffer to be filled */
|
char __user *buffer, /* buffer to be filled */
|
||||||
size_t length, /* length of the buffer */
|
size_t length, /* length of the buffer */
|
||||||
loff_t *offset)
|
loff_t *offset)
|
||||||
{
|
{
|
||||||
/* Number of bytes actually written to the buffer */
|
/* Number of bytes actually written to the buffer */
|
||||||
|
@ -73,17 +73,17 @@ static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
|
||||||
pr_info("device_read(%p,%p,%ld)\n", file, buffer, length);
|
pr_info("device_read(%p,%p,%ld)\n", file, buffer, length);
|
||||||
|
|
||||||
/* If at the end of message, return 0 (which signifies end of file). */
|
/* If at the end of message, return 0 (which signifies end of file). */
|
||||||
if (*Message_Ptr == 0)
|
if (*message_ptr == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Actually put the data into the buffer */
|
/* Actually put the data into the buffer */
|
||||||
while (length && *Message_Ptr) {
|
while (length && *message_ptr) {
|
||||||
/* Because the buffer is in the user data segment, not the kernel
|
/* Because the buffer is in the user data segment, not the kernel
|
||||||
* data segment, assignment would not work. Instead, we have to
|
* data segment, assignment would not work. Instead, we have to
|
||||||
* use put_user which copies data from the kernel data segment to
|
* use put_user which copies data from the kernel data segment to
|
||||||
* the user data segment.
|
* the user data segment.
|
||||||
*/
|
*/
|
||||||
put_user(*(Message_Ptr++), buffer++);
|
put_user(*(message_ptr++), buffer++);
|
||||||
length--;
|
length--;
|
||||||
bytes_read++;
|
bytes_read++;
|
||||||
}
|
}
|
||||||
|
@ -97,19 +97,17 @@ static ssize_t device_read(struct file *file, /* see include/linux/fs.h */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called when somebody tries to write into our device file. */
|
/* called when somebody tries to write into our device file. */
|
||||||
static ssize_t device_write(struct file *file,
|
static ssize_t device_write(struct file *file, const char __user *buffer,
|
||||||
const char __user *buffer,
|
size_t length, loff_t *offset)
|
||||||
size_t length,
|
|
||||||
loff_t *offset)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pr_info("device_write(%p,%s,%ld)", file, buffer, length);
|
pr_info("device_write(%p,%s,%ld)", file, buffer, length);
|
||||||
|
|
||||||
for (i = 0; i < length && i < BUF_LEN; i++)
|
for (i = 0; i < length && i < BUF_LEN; i++)
|
||||||
get_user(Message[i], buffer + i);
|
get_user(message[i], buffer + i);
|
||||||
|
|
||||||
Message_Ptr = Message;
|
message_ptr = message;
|
||||||
|
|
||||||
/* Again, return the number of input characters used. */
|
/* Again, return the number of input characters used. */
|
||||||
return i;
|
return i;
|
||||||
|
@ -123,7 +121,7 @@ static ssize_t device_write(struct file *file,
|
||||||
* If the ioctl is write or read/write (meaning output is returned to the
|
* If the ioctl is write or read/write (meaning output is returned to the
|
||||||
* calling process), the ioctl call returns the output of this function.
|
* calling process), the ioctl call returns the output of this function.
|
||||||
*/
|
*/
|
||||||
long device_ioctl(struct file *file, /* ditto */
|
long device_ioctl(struct file *file, /* ditto */
|
||||||
unsigned int ioctl_num, /* number and param for ioctl */
|
unsigned int ioctl_num, /* number and param for ioctl */
|
||||||
unsigned long ioctl_param)
|
unsigned long ioctl_param)
|
||||||
{
|
{
|
||||||
|
@ -138,33 +136,33 @@ long device_ioctl(struct file *file, /* ditto */
|
||||||
* be the device's message. Get the parameter given to ioctl by
|
* be the device's message. Get the parameter given to ioctl by
|
||||||
* the process.
|
* the process.
|
||||||
*/
|
*/
|
||||||
temp = (char *) ioctl_param;
|
temp = (char *)ioctl_param;
|
||||||
|
|
||||||
/* Find the length of the message */
|
/* Find the length of the message */
|
||||||
get_user(ch, temp);
|
get_user(ch, temp);
|
||||||
for (i = 0; ch && i < BUF_LEN; i++, temp++)
|
for (i = 0; ch && i < BUF_LEN; i++, temp++)
|
||||||
get_user(ch, temp);
|
get_user(ch, temp);
|
||||||
|
|
||||||
device_write(file, (char *) ioctl_param, i, 0);
|
device_write(file, (char *)ioctl_param, i, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_GET_MSG:
|
case IOCTL_GET_MSG:
|
||||||
/* Give the current message to the calling process - the parameter
|
/* Give the current message to the calling process - the parameter
|
||||||
* we got is a pointer, fill it.
|
* we got is a pointer, fill it.
|
||||||
*/
|
*/
|
||||||
i = device_read(file, (char *) ioctl_param, 99, 0);
|
i = device_read(file, (char *)ioctl_param, 99, 0);
|
||||||
|
|
||||||
/* Put a zero at the end of the buffer, so it will be properly
|
/* Put a zero at the end of the buffer, so it will be properly
|
||||||
* terminated.
|
* terminated.
|
||||||
*/
|
*/
|
||||||
put_user('\0', (char *) ioctl_param + i);
|
put_user('\0', (char *)ioctl_param + i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_GET_NTH_BYTE:
|
case IOCTL_GET_NTH_BYTE:
|
||||||
/* This ioctl is both input (ioctl_param) and output (the return
|
/* This ioctl is both input (ioctl_param) and output (the return
|
||||||
* value of this function).
|
* value of this function).
|
||||||
*/
|
*/
|
||||||
return Message[ioctl_param];
|
return message[ioctl_param];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +176,7 @@ long device_ioctl(struct file *file, /* ditto */
|
||||||
* is kept in the devices table, it can't be local to init_module. NULL is
|
* is kept in the devices table, it can't be local to init_module. NULL is
|
||||||
* for unimplemented functions.
|
* for unimplemented functions.
|
||||||
*/
|
*/
|
||||||
struct file_operations Fops = {
|
struct file_operations fops = {
|
||||||
.read = device_read,
|
.read = device_read,
|
||||||
.write = device_write,
|
.write = device_write,
|
||||||
.unlocked_ioctl = device_ioctl,
|
.unlocked_ioctl = device_ioctl,
|
||||||
|
@ -190,7 +188,7 @@ struct file_operations Fops = {
|
||||||
static int __init chardev2_init(void)
|
static int __init chardev2_init(void)
|
||||||
{
|
{
|
||||||
/* Register the character device (atleast try) */
|
/* Register the character device (atleast try) */
|
||||||
int ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
|
int ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
|
||||||
|
|
||||||
/* Negative values signify an error */
|
/* Negative values signify an error */
|
||||||
if (ret_val < 0) {
|
if (ret_val < 0) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ static void show_hash_result(char *plaintext, char *hash_sha256)
|
||||||
|
|
||||||
pr_info("sha256 test for string: \"%s\"\n", plaintext);
|
pr_info("sha256 test for string: \"%s\"\n", plaintext);
|
||||||
for (i = 0; i < SHA256_LENGTH; i++)
|
for (i = 0; i < SHA256_LENGTH; i++)
|
||||||
sprintf(&str[i * 2], "%02x", (unsigned char) hash_sha256[i]);
|
sprintf(&str[i * 2], "%02x", (unsigned char)hash_sha256[i]);
|
||||||
str[i * 2] = 0;
|
str[i * 2] = 0;
|
||||||
pr_info("%s\n", str);
|
pr_info("%s\n", str);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,9 @@ int cryptosha256_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cryptosha256_exit(void) {}
|
void cryptosha256_exit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
module_init(cryptosha256_init);
|
module_init(cryptosha256_init);
|
||||||
module_exit(cryptosha256_exit);
|
module_exit(cryptosha256_exit);
|
||||||
|
|
|
@ -93,8 +93,7 @@ static void test_skcipher_callback(struct crypto_async_request *req, int error)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_skcipher_encrypt(char *plaintext,
|
static int test_skcipher_encrypt(char *plaintext, char *password,
|
||||||
char *password,
|
|
||||||
struct skcipher_def *sk)
|
struct skcipher_def *sk)
|
||||||
{
|
{
|
||||||
int ret = -EFAULT;
|
int ret = -EFAULT;
|
||||||
|
@ -121,10 +120,10 @@ static int test_skcipher_encrypt(char *plaintext,
|
||||||
test_skcipher_callback, &sk->result);
|
test_skcipher_callback, &sk->result);
|
||||||
|
|
||||||
/* clear the key */
|
/* clear the key */
|
||||||
memset((void *) key, '\0', SYMMETRIC_KEY_LENGTH);
|
memset((void *)key, '\0', SYMMETRIC_KEY_LENGTH);
|
||||||
|
|
||||||
/* Use the world's favourite password */
|
/* Use the world's favourite password */
|
||||||
sprintf((char *) key, "%s", password);
|
sprintf((char *)key, "%s", password);
|
||||||
|
|
||||||
/* AES 256 with given symmetric key */
|
/* AES 256 with given symmetric key */
|
||||||
if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) {
|
if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) {
|
||||||
|
@ -153,7 +152,7 @@ static int test_skcipher_encrypt(char *plaintext,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sprintf((char *) sk->scratchpad, "%s", plaintext);
|
sprintf((char *)sk->scratchpad, "%s", plaintext);
|
||||||
|
|
||||||
sg_init_one(&sk->sg, sk->scratchpad, CIPHER_BLOCK_SIZE);
|
sg_init_one(&sk->sg, sk->scratchpad, CIPHER_BLOCK_SIZE);
|
||||||
skcipher_request_set_crypt(sk->req, &sk->sg, &sk->sg, CIPHER_BLOCK_SIZE,
|
skcipher_request_set_crypt(sk->req, &sk->sg, &sk->sg, CIPHER_BLOCK_SIZE,
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct devicemodel_data {
|
||||||
static int devicemodel_probe(struct platform_device *dev)
|
static int devicemodel_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct devicemodel_data *pd =
|
struct devicemodel_data *pd =
|
||||||
(struct devicemodel_data *) (dev->dev.platform_data);
|
(struct devicemodel_data *)(dev->dev.platform_data);
|
||||||
|
|
||||||
pr_info("devicemodel probe\n");
|
pr_info("devicemodel probe\n");
|
||||||
pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number);
|
pr_info("devicemodel greeting: %s; %d\n", pd->greeting, pd->number);
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
|
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
|
||||||
#define BYTE_TO_BINARY(byte) \
|
#define BYTE_TO_BINARY(byte) \
|
||||||
(byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), \
|
(byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), \
|
||||||
(byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), \
|
(byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), \
|
||||||
(byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), \
|
(byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), \
|
||||||
(byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')
|
(byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')
|
||||||
|
|
||||||
static void atomic_add_subtract(void)
|
static void atomic_add_subtract(void)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* hello-2.c - Demonstrating the module_init() and module_exit() macros.
|
* hello-2.c - Demonstrating the module_init() and module_exit() macros.
|
||||||
* This is preferred over using init_module() and cleanup_module().
|
* This is preferred over using init_module() and cleanup_module().
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h> /* Needed for the macros */
|
#include <linux/init.h> /* Needed for the macros */
|
||||||
#include <linux/kernel.h> /* Needed for pr_info() */
|
#include <linux/kernel.h> /* Needed for pr_info() */
|
||||||
#include <linux/module.h> /* Needed by all modules */
|
#include <linux/module.h> /* Needed by all modules */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* hello-3.c - Illustrating the __init, __initdata and __exit macros.
|
* hello-3.c - Illustrating the __init, __initdata and __exit macros.
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h> /* Needed for the macros */
|
#include <linux/init.h> /* Needed for the macros */
|
||||||
#include <linux/kernel.h> /* Needed for pr_info() */
|
#include <linux/kernel.h> /* Needed for pr_info() */
|
||||||
#include <linux/module.h> /* Needed by all modules */
|
#include <linux/module.h> /* Needed by all modules */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* hello-4.c - Demonstrates module documentation.
|
* hello-4.c - Demonstrates module documentation.
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h> /* Needed for the macros */
|
#include <linux/init.h> /* Needed for the macros */
|
||||||
#include <linux/kernel.h> /* Needed for pr_info() */
|
#include <linux/kernel.h> /* Needed for pr_info() */
|
||||||
#include <linux/module.h> /* Needed by all modules */
|
#include <linux/module.h> /* Needed by all modules */
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ static short int myshort = 1;
|
||||||
static int myint = 420;
|
static int myint = 420;
|
||||||
static long int mylong = 9999;
|
static long int mylong = 9999;
|
||||||
static char *mystring = "blah";
|
static char *mystring = "blah";
|
||||||
static int myintArray[2] = {420, 420};
|
static int myintarray[2] = { 420, 420 };
|
||||||
static int arr_argc = 0;
|
static int arr_argc = 0;
|
||||||
|
|
||||||
/* module_param(foo, int, 0000)
|
/* module_param(foo, int, 0000)
|
||||||
|
@ -38,22 +38,23 @@ MODULE_PARM_DESC(mystring, "A character string");
|
||||||
* of elements of the array initialized by the user at module loading time.
|
* of elements of the array initialized by the user at module loading time.
|
||||||
* The fourth argument is the permission bits.
|
* The fourth argument is the permission bits.
|
||||||
*/
|
*/
|
||||||
module_param_array(myintArray, int, &arr_argc, 0000);
|
module_param_array(myintarray, int, &arr_argc, 0000);
|
||||||
MODULE_PARM_DESC(myintArray, "An array of integers");
|
MODULE_PARM_DESC(myintarray, "An array of integers");
|
||||||
|
|
||||||
static int __init hello_5_init(void)
|
static int __init hello_5_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pr_info("Hello, world 5\n=============\n");
|
pr_info("Hello, world 5\n=============\n");
|
||||||
pr_info("myshort is a short integer: %hd\n", myshort);
|
pr_info("myshort is a short integer: %hd\n", myshort);
|
||||||
pr_info("myint is an integer: %d\n", myint);
|
pr_info("myint is an integer: %d\n", myint);
|
||||||
pr_info("mylong is a long integer: %ld\n", mylong);
|
pr_info("mylong is a long integer: %ld\n", mylong);
|
||||||
pr_info("mystring is a string: %s\n", mystring);
|
pr_info("mystring is a string: %s\n", mystring);
|
||||||
|
|
||||||
for (i = 0; i < (sizeof myintArray / sizeof(int)); i++)
|
for (i = 0; i < ARRAY_SIZE(myintarray); i++)
|
||||||
pr_info("myintArray[%d] = %d\n", i, myintArray[i]);
|
pr_info("myintarray[%d] = %d\n", i, myintarray[i]);
|
||||||
|
|
||||||
pr_info("got %d arguments for myintArray.\n", arr_argc);
|
pr_info("got %d arguments for myintarray.\n", arr_argc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,24 +14,21 @@ static struct kobject *mymodule;
|
||||||
static int myvariable = 0;
|
static int myvariable = 0;
|
||||||
|
|
||||||
static ssize_t myvariable_show(struct kobject *kobj,
|
static ssize_t myvariable_show(struct kobject *kobj,
|
||||||
struct kobj_attribute *attr,
|
struct kobj_attribute *attr, char *buf)
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
return sprintf(buf, "%d\n", myvariable);
|
return sprintf(buf, "%d\n", myvariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t myvariable_store(struct kobject *kobj,
|
static ssize_t myvariable_store(struct kobject *kobj,
|
||||||
struct kobj_attribute *attr,
|
struct kobj_attribute *attr, char *buf,
|
||||||
char *buf,
|
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
sscanf(buf, "%du", &myvariable);
|
sscanf(buf, "%du", &myvariable);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct kobj_attribute myvariable_attribute =
|
static struct kobj_attribute myvariable_attribute =
|
||||||
__ATTR(myvariable, 0660, myvariable_show, (void *) myvariable_store);
|
__ATTR(myvariable, 0660, myvariable_show, (void *)myvariable_store);
|
||||||
|
|
||||||
static int __init mymodule_init(void)
|
static int __init mymodule_init(void)
|
||||||
{
|
{
|
||||||
|
@ -45,9 +42,8 @@ static int __init mymodule_init(void)
|
||||||
|
|
||||||
error = sysfs_create_file(mymodule, &myvariable_attribute.attr);
|
error = sysfs_create_file(mymodule, &myvariable_attribute.attr);
|
||||||
if (error) {
|
if (error) {
|
||||||
pr_info(
|
pr_info("failed to create the myvariable file "
|
||||||
"failed to create the myvariable file "
|
"in /sys/kernel/mymodule\n");
|
||||||
"in /sys/kernel/mymodule\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -13,18 +13,18 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
static int button_irqs[] = {-1, -1};
|
static int button_irqs[] = { -1, -1 };
|
||||||
|
|
||||||
/* Define GPIOs for LEDs.
|
/* Define GPIOs for LEDs.
|
||||||
* TODO: Change the numbers for the GPIO on your board.
|
* TODO: Change the numbers for the GPIO on your board.
|
||||||
*/
|
*/
|
||||||
static struct gpio leds[] = {{4, GPIOF_OUT_INIT_LOW, "LED 1"}};
|
static struct gpio leds[] = { { 4, GPIOF_OUT_INIT_LOW, "LED 1" } };
|
||||||
|
|
||||||
/* Define GPIOs for BUTTONS
|
/* Define GPIOs for BUTTONS
|
||||||
* TODO: Change the numbers for the GPIO on your board.
|
* TODO: Change the numbers for the GPIO on your board.
|
||||||
*/
|
*/
|
||||||
static struct gpio buttons[] = {{17, GPIOF_IN, "LED 1 ON BUTTON"},
|
static struct gpio buttons[] = { { 17, GPIOF_IN, "LED 1 ON BUTTON" },
|
||||||
{18, GPIOF_IN, "LED 1 OFF BUTTON"}};
|
{ 18, GPIOF_IN, "LED 1 OFF BUTTON" } };
|
||||||
|
|
||||||
/* interrupt function triggered when a button is pressed. */
|
/* interrupt function triggered when a button is pressed. */
|
||||||
static irqreturn_t button_isr(int irq, void *data)
|
static irqreturn_t button_isr(int irq, void *data)
|
||||||
|
@ -83,7 +83,6 @@ static int __init intrpt_init(void)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ret = gpio_to_irq(buttons[1].gpio);
|
ret = gpio_to_irq(buttons[1].gpio);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -35,8 +35,7 @@ struct test_ioctl_data {
|
||||||
rwlock_t lock;
|
rwlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static long test_ioctl_ioctl(struct file *filp,
|
static long test_ioctl_ioctl(struct file *filp, unsigned int cmd,
|
||||||
unsigned int cmd,
|
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
{
|
{
|
||||||
struct test_ioctl_data *ioctl_data = filp->private_data;
|
struct test_ioctl_data *ioctl_data = filp->private_data;
|
||||||
|
@ -47,7 +46,7 @@ static long test_ioctl_ioctl(struct file *filp,
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case IOCTL_VALSET:
|
case IOCTL_VALSET:
|
||||||
if (copy_from_user(&data, (int __user *) arg, sizeof(data))) {
|
if (copy_from_user(&data, (int __user *)arg, sizeof(data))) {
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +63,7 @@ static long test_ioctl_ioctl(struct file *filp,
|
||||||
read_unlock(&ioctl_data->lock);
|
read_unlock(&ioctl_data->lock);
|
||||||
data.val = val;
|
data.val = val;
|
||||||
|
|
||||||
if (copy_to_user((int __user *) arg, &data, sizeof(data))) {
|
if (copy_to_user((int __user *)arg, &data, sizeof(data))) {
|
||||||
retval = -EFAULT;
|
retval = -EFAULT;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,7 @@ static long test_ioctl_ioctl(struct file *filp,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_VALGET_NUM:
|
case IOCTL_VALGET_NUM:
|
||||||
retval = __put_user(ioctl_num, (int __user *) arg);
|
retval = __put_user(ioctl_num, (int __user *)arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_VALSET_NUM:
|
case IOCTL_VALSET_NUM:
|
||||||
|
@ -87,15 +86,14 @@ done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t test_ioctl_read(struct file *filp,
|
ssize_t test_ioctl_read(struct file *filp, char __user *buf, size_t count,
|
||||||
char __user *buf,
|
|
||||||
size_t count,
|
|
||||||
loff_t *f_pos)
|
loff_t *f_pos)
|
||||||
{
|
{
|
||||||
struct test_ioctl_data *ioctl_data = filp->private_data;
|
struct test_ioctl_data *ioctl_data = filp->private_data;
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
int retval;
|
int retval;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
read_lock(&ioctl_data->lock);
|
read_lock(&ioctl_data->lock);
|
||||||
val = ioctl_data->val;
|
val = ioctl_data->val;
|
||||||
read_unlock(&ioctl_data->lock);
|
read_unlock(&ioctl_data->lock);
|
||||||
|
@ -127,16 +125,17 @@ static int test_ioctl_close(struct inode *inode, struct file *filp)
|
||||||
static int test_ioctl_open(struct inode *inode, struct file *filp)
|
static int test_ioctl_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct test_ioctl_data *ioctl_data;
|
struct test_ioctl_data *ioctl_data;
|
||||||
|
|
||||||
pr_alert("%s call.\n", __func__);
|
pr_alert("%s call.\n", __func__);
|
||||||
ioctl_data = kmalloc(sizeof(struct test_ioctl_data), GFP_KERNEL);
|
ioctl_data = kmalloc(sizeof(struct test_ioctl_data), GFP_KERNEL);
|
||||||
|
|
||||||
if (ioctl_data == NULL) {
|
if (ioctl_data == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
rwlock_init(&ioctl_data->lock);
|
rwlock_init(&ioctl_data->lock);
|
||||||
ioctl_data->val = 0xFF;
|
ioctl_data->val = 0xFF;
|
||||||
filp->private_data = ioctl_data;
|
filp->private_data = ioctl_data;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,37 +154,31 @@ static int ioctl_init(void)
|
||||||
int cdev_ret = 0;
|
int cdev_ret = 0;
|
||||||
alloc_ret = alloc_chrdev_region(&dev, 0, num_of_dev, DRIVER_NAME);
|
alloc_ret = alloc_chrdev_region(&dev, 0, num_of_dev, DRIVER_NAME);
|
||||||
|
|
||||||
if (alloc_ret) {
|
if (alloc_ret)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
test_ioctl_major = MAJOR(dev);
|
test_ioctl_major = MAJOR(dev);
|
||||||
cdev_init(&test_ioctl_cdev, &fops);
|
cdev_init(&test_ioctl_cdev, &fops);
|
||||||
cdev_ret = cdev_add(&test_ioctl_cdev, dev, num_of_dev);
|
cdev_ret = cdev_add(&test_ioctl_cdev, dev, num_of_dev);
|
||||||
|
|
||||||
if (cdev_ret) {
|
if (cdev_ret)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
pr_alert("%s driver(major: %d) installed.\n", DRIVER_NAME,
|
pr_alert("%s driver(major: %d) installed.\n", DRIVER_NAME,
|
||||||
test_ioctl_major);
|
test_ioctl_major);
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
|
if (cdev_ret == 0)
|
||||||
if (cdev_ret == 0) {
|
|
||||||
cdev_del(&test_ioctl_cdev);
|
cdev_del(&test_ioctl_cdev);
|
||||||
}
|
if (alloc_ret == 0)
|
||||||
|
|
||||||
if (alloc_ret == 0) {
|
|
||||||
unregister_chrdev_region(dev, num_of_dev);
|
unregister_chrdev_region(dev, num_of_dev);
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ioctl_exit(void)
|
static void ioctl_exit(void)
|
||||||
{
|
{
|
||||||
dev_t dev = MKDEV(test_ioctl_major, 0);
|
dev_t dev = MKDEV(test_ioctl_major, 0);
|
||||||
|
|
||||||
cdev_del(&test_ioctl_cdev);
|
cdev_del(&test_ioctl_cdev);
|
||||||
unregister_chrdev_region(dev, num_of_dev);
|
unregister_chrdev_region(dev, num_of_dev);
|
||||||
pr_alert("%s driver removed.\n", DRIVER_NAME);
|
pr_alert("%s driver removed.\n", DRIVER_NAME);
|
||||||
|
|
|
@ -35,7 +35,7 @@ char kbledstatus = 0;
|
||||||
|
|
||||||
static void my_timer_func(unsigned long ptr)
|
static void my_timer_func(unsigned long ptr)
|
||||||
{
|
{
|
||||||
unsigned long *pstatus = (unsigned long *) ptr;
|
unsigned long *pstatus = (unsigned long *)ptr;
|
||||||
struct tty_struct *t = vc_cons[fg_console].d->port.tty;
|
struct tty_struct *t = vc_cons[fg_console].d->port.tty;
|
||||||
|
|
||||||
if (*pstatus == ALL_LEDS_ON)
|
if (*pstatus == ALL_LEDS_ON)
|
||||||
|
@ -59,7 +59,7 @@ static int __init kbleds_init(void)
|
||||||
if (!vc_cons[i].d)
|
if (!vc_cons[i].d)
|
||||||
break;
|
break;
|
||||||
pr_info("poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES,
|
pr_info("poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES,
|
||||||
vc_cons[i].d->vc_num, (unsigned long) vc_cons[i].d->port.tty);
|
vc_cons[i].d->vc_num, (unsigned long)vc_cons[i].d->port.tty);
|
||||||
}
|
}
|
||||||
pr_info("kbleds: finished scanning consoles\n");
|
pr_info("kbleds: finished scanning consoles\n");
|
||||||
|
|
||||||
|
@ -67,8 +67,7 @@ static int __init kbleds_init(void)
|
||||||
pr_info("kbleds: tty driver magic %x\n", my_driver->magic);
|
pr_info("kbleds: tty driver magic %x\n", my_driver->magic);
|
||||||
|
|
||||||
/* Set up the LED blink timer the first time. */
|
/* Set up the LED blink timer the first time. */
|
||||||
timer_setup(&my_timer, (void *) &my_timer_func,
|
timer_setup(&my_timer, (void *)&my_timer_func, (unsigned long)&kbledstatus);
|
||||||
(unsigned long) &kbledstatus);
|
|
||||||
my_timer.expires = jiffies + BLINK_DELAY;
|
my_timer.expires = jiffies + BLINK_DELAY;
|
||||||
add_timer(&my_timer);
|
add_timer(&my_timer);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/sched.h> /* For current */
|
#include <linux/sched.h> /* For current */
|
||||||
#include <linux/tty.h> /* For the tty declarations */
|
#include <linux/tty.h> /* For the tty declarations */
|
||||||
|
|
||||||
static void print_string(char *str)
|
static void print_string(char *str)
|
||||||
{
|
{
|
||||||
|
@ -37,8 +37,8 @@ static void print_string(char *str)
|
||||||
* section 2 of
|
* section 2 of
|
||||||
* linux/Documentation/SubmittingPatches
|
* linux/Documentation/SubmittingPatches
|
||||||
*/
|
*/
|
||||||
(ttyops->write)(my_tty, /* The tty itself */
|
(ttyops->write)(my_tty, /* The tty itself */
|
||||||
str, /* String */
|
str, /* String */
|
||||||
strlen(str)); /* Length */
|
strlen(str)); /* Length */
|
||||||
|
|
||||||
/* ttys were originally hardware devices, which (usually) strictly
|
/* ttys were originally hardware devices, which (usually) strictly
|
||||||
|
|
|
@ -14,13 +14,10 @@
|
||||||
|
|
||||||
#define procfs_name "helloworld"
|
#define procfs_name "helloworld"
|
||||||
|
|
||||||
struct proc_dir_entry *Our_Proc_File;
|
struct proc_dir_entry *our_proc_file;
|
||||||
|
|
||||||
|
ssize_t procfile_read(struct file *filePointer, char *buffer,
|
||||||
ssize_t procfile_read(struct file *filePointer,
|
size_t buffer_length, loff_t *offset)
|
||||||
char *buffer,
|
|
||||||
size_t buffer_length,
|
|
||||||
loff_t *offset)
|
|
||||||
{
|
{
|
||||||
char s[13] = "HelloWorld!\n";
|
char s[13] = "HelloWorld!\n";
|
||||||
int len = sizeof(s);
|
int len = sizeof(s);
|
||||||
|
@ -49,9 +46,9 @@ static const struct file_operations proc_file_fops = {
|
||||||
|
|
||||||
static int __init procfs1_init(void)
|
static int __init procfs1_init(void)
|
||||||
{
|
{
|
||||||
Our_Proc_File = proc_create(procfs_name, 0644, NULL, &proc_file_fops);
|
our_proc_file = proc_create(procfs_name, 0644, NULL, &proc_file_fops);
|
||||||
if (NULL == Our_Proc_File) {
|
if (NULL == our_proc_file) {
|
||||||
proc_remove(Our_Proc_File);
|
proc_remove(our_proc_file);
|
||||||
pr_alert("Error:Could not initialize /proc/%s\n", procfs_name);
|
pr_alert("Error:Could not initialize /proc/%s\n", procfs_name);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +59,7 @@ static int __init procfs1_init(void)
|
||||||
|
|
||||||
static void __exit procfs1_exit(void)
|
static void __exit procfs1_exit(void)
|
||||||
{
|
{
|
||||||
proc_remove(Our_Proc_File);
|
proc_remove(our_proc_file);
|
||||||
pr_info("/proc/%s removed\n", procfs_name);
|
pr_info("/proc/%s removed\n", procfs_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* procfs2.c - create a "file" in /proc
|
* procfs2.c - create a "file" in /proc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h> /* We're doing kernel work */
|
#include <linux/kernel.h> /* We're doing kernel work */
|
||||||
#include <linux/module.h> /* Specifically, a module */
|
#include <linux/module.h> /* Specifically, a module */
|
||||||
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
|
#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
|
||||||
#include <linux/uaccess.h> /* for copy_from_user */
|
#include <linux/uaccess.h> /* for copy_from_user */
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
#define PROCFS_NAME "buffer1k"
|
#define PROCFS_NAME "buffer1k"
|
||||||
|
|
||||||
/* This structure hold information about the /proc file */
|
/* This structure hold information about the /proc file */
|
||||||
static struct proc_dir_entry *Our_Proc_File;
|
static struct proc_dir_entry *our_proc_file;
|
||||||
|
|
||||||
/* The buffer used to store character for this module */
|
/* The buffer used to store character for this module */
|
||||||
static char procfs_buffer[PROCFS_MAX_SIZE];
|
static char procfs_buffer[PROCFS_MAX_SIZE];
|
||||||
|
@ -25,10 +25,8 @@ static char procfs_buffer[PROCFS_MAX_SIZE];
|
||||||
static unsigned long procfs_buffer_size = 0;
|
static unsigned long procfs_buffer_size = 0;
|
||||||
|
|
||||||
/* This function is called then the /proc file is read */
|
/* This function is called then the /proc file is read */
|
||||||
ssize_t procfile_read(struct file *filePointer,
|
ssize_t procfile_read(struct file *filePointer, char *buffer,
|
||||||
char *buffer,
|
size_t buffer_length, loff_t *offset)
|
||||||
size_t buffer_length,
|
|
||||||
loff_t *offset)
|
|
||||||
{
|
{
|
||||||
char s[13] = "HelloWorld!\n";
|
char s[13] = "HelloWorld!\n";
|
||||||
int len = sizeof(s);
|
int len = sizeof(s);
|
||||||
|
@ -46,9 +44,7 @@ ssize_t procfile_read(struct file *filePointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called with the /proc file is written. */
|
/* This function is called with the /proc file is written. */
|
||||||
static ssize_t procfile_write(struct file *file,
|
static ssize_t procfile_write(struct file *file, const char *buff, size_t len,
|
||||||
const char *buff,
|
|
||||||
size_t len,
|
|
||||||
loff_t *off)
|
loff_t *off)
|
||||||
{
|
{
|
||||||
procfs_buffer_size = len;
|
procfs_buffer_size = len;
|
||||||
|
@ -76,9 +72,9 @@ static const struct file_operations proc_file_fops = {
|
||||||
|
|
||||||
static int __init procfs2_init(void)
|
static int __init procfs2_init(void)
|
||||||
{
|
{
|
||||||
Our_Proc_File = proc_create(PROCFS_NAME, 0644, NULL, &proc_file_fops);
|
our_proc_file = proc_create(PROCFS_NAME, 0644, NULL, &proc_file_fops);
|
||||||
if (NULL == Our_Proc_File) {
|
if (NULL == our_proc_file) {
|
||||||
proc_remove(Our_Proc_File);
|
proc_remove(our_proc_file);
|
||||||
pr_alert("Error:Could not initialize /proc/%s\n", PROCFS_NAME);
|
pr_alert("Error:Could not initialize /proc/%s\n", PROCFS_NAME);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +85,7 @@ static int __init procfs2_init(void)
|
||||||
|
|
||||||
static void __exit procfs2_exit(void)
|
static void __exit procfs2_exit(void)
|
||||||
{
|
{
|
||||||
proc_remove(Our_Proc_File);
|
proc_remove(our_proc_file);
|
||||||
pr_info("/proc/%s removed\n", PROCFS_NAME);
|
pr_info("/proc/%s removed\n", PROCFS_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,30 +16,29 @@
|
||||||
#define PROCFS_MAX_SIZE 2048
|
#define PROCFS_MAX_SIZE 2048
|
||||||
#define PROCFS_ENTRY_FILENAME "buffer2k"
|
#define PROCFS_ENTRY_FILENAME "buffer2k"
|
||||||
|
|
||||||
struct proc_dir_entry *Our_Proc_File;
|
struct proc_dir_entry *our_proc_file;
|
||||||
static char procfs_buffer[PROCFS_MAX_SIZE];
|
static char procfs_buffer[PROCFS_MAX_SIZE];
|
||||||
static unsigned long procfs_buffer_size = 0;
|
static unsigned long procfs_buffer_size = 0;
|
||||||
|
|
||||||
static ssize_t procfs_read(struct file *filp,
|
static ssize_t procfs_read(struct file *filp, char *buffer, size_t length,
|
||||||
char *buffer,
|
|
||||||
size_t length,
|
|
||||||
loff_t *offset)
|
loff_t *offset)
|
||||||
{
|
{
|
||||||
static int finished = 0;
|
static int finished = 0;
|
||||||
|
|
||||||
if (finished) {
|
if (finished) {
|
||||||
pr_debug("procfs_read: END\n");
|
pr_debug("procfs_read: END\n");
|
||||||
finished = 0;
|
finished = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
finished = 1;
|
finished = 1;
|
||||||
|
|
||||||
if (copy_to_user(buffer, procfs_buffer, procfs_buffer_size))
|
if (copy_to_user(buffer, procfs_buffer, procfs_buffer_size))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
pr_debug("procfs_read: read %lu bytes\n", procfs_buffer_size);
|
pr_debug("procfs_read: read %lu bytes\n", procfs_buffer_size);
|
||||||
return procfs_buffer_size;
|
return procfs_buffer_size;
|
||||||
}
|
}
|
||||||
static ssize_t procfs_write(struct file *file,
|
static ssize_t procfs_write(struct file *file, const char *buffer, size_t len,
|
||||||
const char *buffer,
|
|
||||||
size_t len,
|
|
||||||
loff_t *off)
|
loff_t *off)
|
||||||
{
|
{
|
||||||
if (len > PROCFS_MAX_SIZE)
|
if (len > PROCFS_MAX_SIZE)
|
||||||
|
@ -48,6 +47,7 @@ static ssize_t procfs_write(struct file *file,
|
||||||
procfs_buffer_size = len;
|
procfs_buffer_size = len;
|
||||||
if (copy_from_user(procfs_buffer, buffer, procfs_buffer_size))
|
if (copy_from_user(procfs_buffer, buffer, procfs_buffer_size))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
pr_debug("procfs_write: write %lu bytes\n", procfs_buffer_size);
|
pr_debug("procfs_write: write %lu bytes\n", procfs_buffer_size);
|
||||||
return procfs_buffer_size;
|
return procfs_buffer_size;
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,14 @@ int procfs_close(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PROC_OPS
|
#ifdef HAVE_PROC_OPS
|
||||||
static struct proc_ops File_Ops_4_Our_Proc_File = {
|
static struct proc_ops file_ops_4_our_proc_file = {
|
||||||
.proc_read = procfs_read,
|
.proc_read = procfs_read,
|
||||||
.proc_write = procfs_write,
|
.proc_write = procfs_write,
|
||||||
.proc_open = procfs_open,
|
.proc_open = procfs_open,
|
||||||
.proc_release = procfs_close,
|
.proc_release = procfs_close,
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
static const struct file_operations File_Ops_4_Our_Proc_File = {
|
static const struct file_operations file_ops_4_our_proc_file = {
|
||||||
.read = procfs_read,
|
.read = procfs_read,
|
||||||
.write = procfs_write,
|
.write = procfs_write,
|
||||||
.open = procfs_open,
|
.open = procfs_open,
|
||||||
|
@ -80,16 +80,16 @@ static const struct file_operations File_Ops_4_Our_Proc_File = {
|
||||||
|
|
||||||
static int __init procfs3_init(void)
|
static int __init procfs3_init(void)
|
||||||
{
|
{
|
||||||
Our_Proc_File = proc_create(PROCFS_ENTRY_FILENAME, 0644, NULL,
|
our_proc_file = proc_create(PROCFS_ENTRY_FILENAME, 0644, NULL,
|
||||||
&File_Ops_4_Our_Proc_File);
|
&file_ops_4_our_proc_file);
|
||||||
if (Our_Proc_File == NULL) {
|
if (our_proc_file == NULL) {
|
||||||
remove_proc_entry(PROCFS_ENTRY_FILENAME, NULL);
|
remove_proc_entry(PROCFS_ENTRY_FILENAME, NULL);
|
||||||
pr_debug("Error: Could not initialize /proc/%s\n",
|
pr_debug("Error: Could not initialize /proc/%s\n",
|
||||||
PROCFS_ENTRY_FILENAME);
|
PROCFS_ENTRY_FILENAME);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
proc_set_size(Our_Proc_File, 80);
|
proc_set_size(our_proc_file, 80);
|
||||||
proc_set_user(Our_Proc_File, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID);
|
proc_set_user(our_proc_file, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID);
|
||||||
|
|
||||||
pr_debug("/proc/%s created\n", PROCFS_ENTRY_FILENAME);
|
pr_debug("/proc/%s created\n", PROCFS_ENTRY_FILENAME);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
* This program uses the seq_file library to manage the /proc file.
|
* This program uses the seq_file library to manage the /proc file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h> /* We are doing kernel work */
|
#include <linux/kernel.h> /* We are doing kernel work */
|
||||||
#include <linux/module.h> /* Specifically, a module */
|
#include <linux/module.h> /* Specifically, a module */
|
||||||
#include <linux/proc_fs.h> /* Necessary because we use proc fs */
|
#include <linux/proc_fs.h> /* Necessary because we use proc fs */
|
||||||
#include <linux/seq_file.h> /* for seq_file */
|
#include <linux/seq_file.h> /* for seq_file */
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ static void *my_seq_start(struct seq_file *s, loff_t *pos)
|
||||||
/* yes => return a non null value to begin the sequence */
|
/* yes => return a non null value to begin the sequence */
|
||||||
return &counter;
|
return &counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no => it is the end of the sequence, return end to stop reading */
|
/* no => it is the end of the sequence, return end to stop reading */
|
||||||
*pos = 0;
|
*pos = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -39,7 +40,7 @@ static void *my_seq_start(struct seq_file *s, loff_t *pos)
|
||||||
*/
|
*/
|
||||||
static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
||||||
{
|
{
|
||||||
unsigned long *tmp_v = (unsigned long *) v;
|
unsigned long *tmp_v = (unsigned long *)v;
|
||||||
(*tmp_v)++;
|
(*tmp_v)++;
|
||||||
(*pos)++;
|
(*pos)++;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -54,7 +55,7 @@ static void my_seq_stop(struct seq_file *s, void *v)
|
||||||
/* This function is called for each "step" of a sequence. */
|
/* This function is called for each "step" of a sequence. */
|
||||||
static int my_seq_show(struct seq_file *s, void *v)
|
static int my_seq_show(struct seq_file *s, void *v)
|
||||||
{
|
{
|
||||||
loff_t *spos = (loff_t *) v;
|
loff_t *spos = (loff_t *)v;
|
||||||
|
|
||||||
seq_printf(s, "%Ld\n", *spos);
|
seq_printf(s, "%Ld\n", *spos);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -18,7 +18,6 @@ static int __init sched_init(void)
|
||||||
queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1);
|
queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1);
|
||||||
INIT_WORK(&work, work_handler);
|
INIT_WORK(&work, work_handler);
|
||||||
schedule_work(&work);
|
schedule_work(&work);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
* at the same time, put all but one to sleep.
|
* at the same time, put all but one to sleep.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h> /* We're doing kernel work */
|
#include <linux/kernel.h> /* We're doing kernel work */
|
||||||
#include <linux/module.h> /* Specifically, a module */
|
#include <linux/module.h> /* Specifically, a module */
|
||||||
#include <linux/proc_fs.h> /* Necessary because we use proc fs */
|
#include <linux/proc_fs.h> /* Necessary because we use proc fs */
|
||||||
#include <linux/sched.h> /* For putting processes to sleep and
|
#include <linux/sched.h> /* For putting processes to sleep and
|
||||||
waking them up */
|
waking them up */
|
||||||
#include <linux/uaccess.h> /* for get_user and put_user */
|
#include <linux/uaccess.h> /* for get_user and put_user */
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
* input.
|
* input.
|
||||||
*/
|
*/
|
||||||
#define MESSAGE_LENGTH 80
|
#define MESSAGE_LENGTH 80
|
||||||
static char Message[MESSAGE_LENGTH];
|
static char message[MESSAGE_LENGTH];
|
||||||
|
|
||||||
static struct proc_dir_entry *Our_Proc_File;
|
static struct proc_dir_entry *our_proc_file;
|
||||||
#define PROC_ENTRY_FILENAME "sleep"
|
#define PROC_ENTRY_FILENAME "sleep"
|
||||||
|
|
||||||
/* Since we use the file operations struct, we can't use the special proc
|
/* Since we use the file operations struct, we can't use the special proc
|
||||||
|
@ -29,14 +29,14 @@ static struct proc_dir_entry *Our_Proc_File;
|
||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
||||||
char *buf, /* The buffer to put data to
|
char *buf, /* The buffer to put data to
|
||||||
(in the user segment) */
|
(in the user segment) */
|
||||||
size_t len, /* The length of the buffer */
|
size_t len, /* The length of the buffer */
|
||||||
loff_t *offset)
|
loff_t *offset)
|
||||||
{
|
{
|
||||||
static int finished = 0;
|
static int finished = 0;
|
||||||
int i;
|
int i;
|
||||||
char message[MESSAGE_LENGTH + 30];
|
char output_msg[MESSAGE_LENGTH + 30];
|
||||||
|
|
||||||
/* Return 0 to signify end of file - that we have nothing more to say
|
/* Return 0 to signify end of file - that we have nothing more to say
|
||||||
* at this point.
|
* at this point.
|
||||||
|
@ -46,9 +46,9 @@ static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(message, "Last input:%s\n", Message);
|
sprintf(output_msg, "Last input:%s\n", message);
|
||||||
for (i = 0; i < len && message[i]; i++)
|
for (i = 0; i < len && output_msg[i]; i++)
|
||||||
put_user(message[i], buf + i);
|
put_user(output_msg[i], buf + i);
|
||||||
|
|
||||||
finished = 1;
|
finished = 1;
|
||||||
return i; /* Return the number of bytes "read" */
|
return i; /* Return the number of bytes "read" */
|
||||||
|
@ -58,9 +58,9 @@ static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
||||||
* /proc file.
|
* /proc file.
|
||||||
*/
|
*/
|
||||||
static ssize_t module_input(struct file *file, /* The file itself */
|
static ssize_t module_input(struct file *file, /* The file itself */
|
||||||
const char *buf, /* The buffer with input */
|
const char *buf, /* The buffer with input */
|
||||||
size_t length, /* The buffer's length */
|
size_t length, /* The buffer's length */
|
||||||
loff_t *offset) /* offset to file - ignore */
|
loff_t *offset) /* offset to file - ignore */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -68,19 +68,19 @@ static ssize_t module_input(struct file *file, /* The file itself */
|
||||||
* to use it.
|
* to use it.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < MESSAGE_LENGTH - 1 && i < length; i++)
|
for (i = 0; i < MESSAGE_LENGTH - 1 && i < length; i++)
|
||||||
get_user(Message[i], buf + i);
|
get_user(message[i], buf + i);
|
||||||
/* we want a standard, zero terminated string */
|
/* we want a standard, zero terminated string */
|
||||||
Message[i] = '\0';
|
message[i] = '\0';
|
||||||
|
|
||||||
/* We need to return the number of input characters used */
|
/* We need to return the number of input characters used */
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1 if the file is currently open by somebody */
|
/* 1 if the file is currently open by somebody */
|
||||||
int Already_Open = 0;
|
int already_open = 0;
|
||||||
|
|
||||||
/* Queue of processes who want our file */
|
/* Queue of processes who want our file */
|
||||||
DECLARE_WAIT_QUEUE_HEAD(WaitQ);
|
DECLARE_WAIT_QUEUE_HEAD(waitq);
|
||||||
|
|
||||||
/* Called when the /proc file is opened */
|
/* Called when the /proc file is opened */
|
||||||
static int module_open(struct inode *inode, struct file *file)
|
static int module_open(struct inode *inode, struct file *file)
|
||||||
|
@ -90,7 +90,7 @@ static int module_open(struct inode *inode, struct file *file)
|
||||||
* we should fail with -EAGAIN, meaning "you will have to try again",
|
* we should fail with -EAGAIN, meaning "you will have to try again",
|
||||||
* instead of blocking a process which would rather stay awake.
|
* instead of blocking a process which would rather stay awake.
|
||||||
*/
|
*/
|
||||||
if ((file->f_flags & O_NONBLOCK) && Already_Open)
|
if ((file->f_flags & O_NONBLOCK) && already_open)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
/* This is the correct place for try_module_get(THIS_MODULE) because if
|
/* This is the correct place for try_module_get(THIS_MODULE) because if
|
||||||
|
@ -100,17 +100,17 @@ static int module_open(struct inode *inode, struct file *file)
|
||||||
try_module_get(THIS_MODULE);
|
try_module_get(THIS_MODULE);
|
||||||
|
|
||||||
/* If the file is already open, wait until it is not. */
|
/* If the file is already open, wait until it is not. */
|
||||||
while (Already_Open) {
|
while (already_open) {
|
||||||
int i, is_sig = 0;
|
int i, is_sig = 0;
|
||||||
|
|
||||||
/* This function puts the current process, including any system
|
/* This function puts the current process, including any system
|
||||||
* calls, such as us, to sleep. Execution will be resumed right
|
* calls, such as us, to sleep. Execution will be resumed right
|
||||||
* after the function call, either because somebody called
|
* after the function call, either because somebody called
|
||||||
* wake_up(&WaitQ) (only module_close does that, when the file
|
* wake_up(&waitq) (only module_close does that, when the file
|
||||||
* is closed) or when a signal, such as Ctrl-C, is sent
|
* is closed) or when a signal, such as Ctrl-C, is sent
|
||||||
* to the process
|
* to the process
|
||||||
*/
|
*/
|
||||||
wait_event_interruptible(WaitQ, !Already_Open);
|
wait_event_interruptible(waitq, !already_open);
|
||||||
|
|
||||||
/* If we woke up because we got a signal we're not blocking,
|
/* If we woke up because we got a signal we're not blocking,
|
||||||
* return -EINTR (fail the system call). This allows processes
|
* return -EINTR (fail the system call). This allows processes
|
||||||
|
@ -133,27 +133,27 @@ static int module_open(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we got here, Already_Open must be zero. */
|
/* If we got here, already_open must be zero. */
|
||||||
|
|
||||||
/* Open the file */
|
/* Open the file */
|
||||||
Already_Open = 1;
|
already_open = 1;
|
||||||
return 0; /* Allow the access */
|
return 0; /* Allow the access */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when the /proc file is closed */
|
/* Called when the /proc file is closed */
|
||||||
int module_close(struct inode *inode, struct file *file)
|
int module_close(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
/* Set Already_Open to zero, so one of the processes in the WaitQ will
|
/* Set already_open to zero, so one of the processes in the waitq will
|
||||||
* be able to set Already_Open back to one and to open the file. All
|
* be able to set already_open back to one and to open the file. All
|
||||||
* the other processes will be called when Already_Open is back to one,
|
* the other processes will be called when already_open is back to one,
|
||||||
* so they'll go back to sleep.
|
* so they'll go back to sleep.
|
||||||
*/
|
*/
|
||||||
Already_Open = 0;
|
already_open = 0;
|
||||||
|
|
||||||
/* Wake up all the processes in WaitQ, so if anybody is waiting for the
|
/* Wake up all the processes in waitq, so if anybody is waiting for the
|
||||||
* file, they can have it.
|
* file, they can have it.
|
||||||
*/
|
*/
|
||||||
wake_up(&WaitQ);
|
wake_up(&waitq);
|
||||||
|
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
|
|
||||||
|
@ -169,14 +169,14 @@ int module_close(struct inode *inode, struct file *file)
|
||||||
* means we don't want to deal with something.
|
* means we don't want to deal with something.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_PROC_OPS
|
#ifdef HAVE_PROC_OPS
|
||||||
static const struct proc_ops File_Ops_4_Our_Proc_File = {
|
static const struct proc_ops file_ops_4_our_proc_file = {
|
||||||
.proc_read = module_output, /* "read" from the file */
|
.proc_read = module_output, /* "read" from the file */
|
||||||
.proc_write = module_input, /* "write" to the file */
|
.proc_write = module_input, /* "write" to the file */
|
||||||
.proc_open = module_open, /* called when the /proc file is opened */
|
.proc_open = module_open, /* called when the /proc file is opened */
|
||||||
.proc_release = module_close, /* called when it's closed */
|
.proc_release = module_close, /* called when it's closed */
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
static const struct file_operations File_Ops_4_Our_Proc_File = {
|
static const struct file_operations file_ops_4_our_proc_file = {
|
||||||
.read = module_output,
|
.read = module_output,
|
||||||
.write = module_input,
|
.write = module_input,
|
||||||
.open = module_open,
|
.open = module_open,
|
||||||
|
@ -187,15 +187,15 @@ static const struct file_operations File_Ops_4_Our_Proc_File = {
|
||||||
/* Initialize the module - register the proc file */
|
/* Initialize the module - register the proc file */
|
||||||
static int __init sleep_init(void)
|
static int __init sleep_init(void)
|
||||||
{
|
{
|
||||||
Our_Proc_File =
|
our_proc_file =
|
||||||
proc_create(PROC_ENTRY_FILENAME, 0644, NULL, &File_Ops_4_Our_Proc_File);
|
proc_create(PROC_ENTRY_FILENAME, 0644, NULL, &file_ops_4_our_proc_file);
|
||||||
if (Our_Proc_File == NULL) {
|
if (our_proc_file == NULL) {
|
||||||
remove_proc_entry(PROC_ENTRY_FILENAME, NULL);
|
remove_proc_entry(PROC_ENTRY_FILENAME, NULL);
|
||||||
pr_debug("Error: Could not initialize /proc/%s\n", PROC_ENTRY_FILENAME);
|
pr_debug("Error: Could not initialize /proc/%s\n", PROC_ENTRY_FILENAME);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
proc_set_size(Our_Proc_File, 80);
|
proc_set_size(our_proc_file, 80);
|
||||||
proc_set_user(Our_Proc_File, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID);
|
proc_set_user(our_proc_file, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID);
|
||||||
|
|
||||||
pr_info("/proc/%s created\n", PROC_ENTRY_FILENAME);
|
pr_info("/proc/%s created\n", PROC_ENTRY_FILENAME);
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ static int __init sleep_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup - unregister our file from /proc. This could get dangerous if
|
/* Cleanup - unregister our file from /proc. This could get dangerous if
|
||||||
* there are still processes waiting in WaitQ, because they are inside our
|
* there are still processes waiting in waitq, because they are inside our
|
||||||
* open function, which will get unloaded. I'll explain how to avoid removal
|
* open function, which will get unloaded. I'll explain how to avoid removal
|
||||||
* of a kernel module in such a case in chapter 10.
|
* of a kernel module in such a case in chapter 10.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h> /* which will have params */
|
#include <linux/moduleparam.h> /* which will have params */
|
||||||
#include <linux/unistd.h> /* The list of system calls */
|
#include <linux/unistd.h> /* The list of system calls */
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
/* For the current (process) structure, we need this to know who the
|
/* For the current (process) structure, we need this to know who the
|
||||||
|
@ -23,7 +23,6 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
|
||||||
/* The way we access "sys_call_table" varies as kernel internal changes.
|
/* The way we access "sys_call_table" varies as kernel internal changes.
|
||||||
* - ver <= 5.4 : manual symbol lookup
|
* - ver <= 5.4 : manual symbol lookup
|
||||||
* - 5.4 < ver < 5.7 : kallsyms_lookup_name
|
* - 5.4 < ver < 5.7 : kallsyms_lookup_name
|
||||||
|
@ -56,9 +55,9 @@
|
||||||
*/
|
*/
|
||||||
static unsigned long sym = 0;
|
static unsigned long sym = 0;
|
||||||
module_param(sym, ulong, 0644);
|
module_param(sym, ulong, 0644);
|
||||||
#endif
|
#endif /* CONFIG_KPROBES */
|
||||||
|
|
||||||
#endif
|
#endif /* Version < v5.7 */
|
||||||
|
|
||||||
unsigned long **sys_call_table;
|
unsigned long **sys_call_table;
|
||||||
|
|
||||||
|
@ -115,9 +114,9 @@ static unsigned long **aquire_sys_call_table(void)
|
||||||
unsigned long **sct;
|
unsigned long **sct;
|
||||||
|
|
||||||
while (offset < ULLONG_MAX) {
|
while (offset < ULLONG_MAX) {
|
||||||
sct = (unsigned long **) offset;
|
sct = (unsigned long **)offset;
|
||||||
|
|
||||||
if (sct[__NR_close] == (unsigned long *) ksys_close)
|
if (sct[__NR_close] == (unsigned long *)ksys_close)
|
||||||
return sct;
|
return sct;
|
||||||
|
|
||||||
offset += sizeof(void *);
|
offset += sizeof(void *);
|
||||||
|
@ -128,23 +127,20 @@ static unsigned long **aquire_sys_call_table(void)
|
||||||
|
|
||||||
#ifdef HAVE_PARAM
|
#ifdef HAVE_PARAM
|
||||||
const char sct_name[15] = "sys_call_table";
|
const char sct_name[15] = "sys_call_table";
|
||||||
char symbol[40] = {0};
|
char symbol[40] = { 0 };
|
||||||
|
|
||||||
if (sym == 0) {
|
if (sym == 0) {
|
||||||
pr_alert(
|
pr_alert("For Linux v5.7+, Kprobes is the preferable way to get "
|
||||||
"For Linux v5.7+, Kprobes is the preferable way to get "
|
"symbol.\n");
|
||||||
"symbol.\n");
|
pr_info("If Kprobes is absent, you have to specify the address of "
|
||||||
pr_info(
|
"sys_call_table symbol\n");
|
||||||
"If Kprobes is absent, you have to specify the address of "
|
pr_info("by /boot/System.map or /proc/kallsyms, which contains all the "
|
||||||
"sys_call_table symbol\n");
|
"symbol addresses, into sym parameter.\n");
|
||||||
pr_info(
|
|
||||||
"by /boot/System.map or /proc/kallsyms, which contains all the "
|
|
||||||
"symbol addresses, into sym parameter.\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprint_symbol(symbol, sym);
|
sprint_symbol(symbol, sym);
|
||||||
if (!strncmp(sct_name, symbol, sizeof(sct_name) - 1))
|
if (!strncmp(sct_name, symbol, sizeof(sct_name) - 1))
|
||||||
return (unsigned long **) sym;
|
return (unsigned long **)sym;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,11 +153,11 @@ static unsigned long **aquire_sys_call_table(void)
|
||||||
|
|
||||||
if (register_kprobe(&kp) < 0)
|
if (register_kprobe(&kp) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
kallsyms_lookup_name = (unsigned long (*)(const char *name)) kp.addr;
|
kallsyms_lookup_name = (unsigned long (*)(const char *name))kp.addr;
|
||||||
unregister_kprobe(&kp);
|
unregister_kprobe(&kp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (unsigned long **) kallsyms_lookup_name("sys_call_table");
|
return (unsigned long **)kallsyms_lookup_name("sys_call_table");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
|
||||||
|
@ -195,10 +191,10 @@ static int __init syscall_start(void)
|
||||||
disable_write_protection();
|
disable_write_protection();
|
||||||
|
|
||||||
/* keep track of the original open function */
|
/* keep track of the original open function */
|
||||||
original_call = (void *) sys_call_table[__NR_open];
|
original_call = (void *)sys_call_table[__NR_open];
|
||||||
|
|
||||||
/* use our open function instead */
|
/* use our open function instead */
|
||||||
sys_call_table[__NR_open] = (unsigned long *) our_sys_open;
|
sys_call_table[__NR_open] = (unsigned long *)our_sys_open;
|
||||||
|
|
||||||
enable_write_protection();
|
enable_write_protection();
|
||||||
|
|
||||||
|
@ -213,7 +209,7 @@ static void __exit syscall_end(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Return the system call back to normal */
|
/* Return the system call back to normal */
|
||||||
if (sys_call_table[__NR_open] != (unsigned long *) our_sys_open) {
|
if (sys_call_table[__NR_open] != (unsigned long *)our_sys_open) {
|
||||||
pr_alert("Somebody else also played with the ");
|
pr_alert("Somebody else also played with the ");
|
||||||
pr_alert("open system call\n");
|
pr_alert("open system call\n");
|
||||||
pr_alert("The system may be left in ");
|
pr_alert("The system may be left in ");
|
||||||
|
@ -221,7 +217,7 @@ static void __exit syscall_end(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_write_protection();
|
disable_write_protection();
|
||||||
sys_call_table[__NR_open] = (unsigned long *) original_call;
|
sys_call_table[__NR_open] = (unsigned long *)original_call;
|
||||||
enable_write_protection();
|
enable_write_protection();
|
||||||
|
|
||||||
msleep(2000);
|
msleep(2000);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user