Add syscalls to linux kernel - c

I'm new in working with kernel.
I want to add a linked list to my kernel, and I try to fix it like this link : Linux Kernel Programming–Linked List
here is code's that I added to sys.c :
syscall defenition:
SYSCALL_DEFINE1(init_process_list,pid_t,ppid)
{
LIST_HEAD(processList);
struct scallNode* newNode;
newNode = kmalloc(sizeof(*newNode), GFP_KERNEL);
newNode->ID = ppid;
INIT_LIST_HEAD(&newNode -> list);
list_add_tail(&newNode -> list , &processList.list);
printk(KERN_INFO "INIT PROCESS UID: %u\n", ppid);
return 0;
}
and my struct for linked list:
struct scallNode{
int ID;
struct file_struct ffs;
struct task_struct ts;
struct list_head list;
};
struct scallNode processList;
and when I compile the kernel, I saw this error:
error: ‘struct list_head’ has no member named ‘list’ list_add_tail(&newNode -> list , &processList.list);
thanks for your replies.
that error disappeared, but another one is still exist.
kernel/sys.c:2136:24: error: field ‘fs’ has incomplete type struct file_struct fs;
again thanks for your replies.

The list_add_tail function is
void list_add_tail(struct list_head *new, struct list_head *head);
The second param should a pointer to a struct list_head so just use like this:
list_add_tail(&newNode -> list , &processList);

I never did any kernel programming. But as per my knowledge below memory allocation is not correct:-
newNode = kmalloc(sizeof(*newNode), GFP_KERNEL);
I think it should be like:-
newNode = (struct scallNode *)kmalloc(sizeof(struct scallNode), GFP_KERNEL);

finally answer finded.
in list_add_tail(&newNode -> list , &processList.list);
, &processList most be use instead of &processList.list .
list_add_tail find list of processList itself.

Related

Attempting to lock a spinlock in the down function results in freezing

I am attempting to implement my own version of a semaphore into a linux vm and am running into a crash when I attempt to lock a spinlock inside the down function. Using GDB I found that the down is called immediately after the create function so the problem is definitely there.
Here is the create function:
asmlinkage long sys_create(int value, char name[32], char key[32]){
struct sem *new_sem = (struct sem*) kmalloc(sizeof(struct sem), GFP_ATOMIC);
struct sem_node *new_sem_node = (struct sem_node*) kmalloc(sizeof(struct sem_node), GFP_ATOMIC);
struct sem_node *curr_sem = sem_list_head;
new_sem_node->sem = new_sem;
spin_lock(&sem_lock);
new_sem->sem_id = IDcntr++;
spin_lock_init(&(new_sem->lock));
strncpy(new_sem->key, key, 32);
strncpy(new_sem->name, name, 32);
if(curr_sem == NULL)
{
sem_list_head = new_sem_node;
}
else
{
while(curr_sem->next != NULL)
{
curr_sem = curr_sem->next;
}
curr_sem->next = new_sem_node;
}
spin_unlock(&sem_lock);
return new_sem->sem_id;
}
Functions spin_lock, spin_unlock, and spin_lock_init are working as intended. The down function calls:
spin_lock(&(sem_list_head->sem->lock));
right at the beginning and freezes. To be more specific, in the gdb terminal, I try and get to the next line and it stops and in the actual machine it's completely stopped. No other functions are called between the create and down function. Below is the header file that defines the sem_node, process_node, and sem objects used in the create and down functions:
int IDcntr = 1;
DEFINE_SPINLOCK(sem_lock);
struct sem_node
{
struct sem* sem;
struct sem_node* next;
};
struct process_node
{
struct process_node* next;
struct task_struct* task;
};
struct sem
{
int value;
long sem_id;
spinlock_t lock;
char key[32];
char name[32];
struct process_node* head;
struct process_node* tail;
};
struct sem_node* sem_list_head = NULL;
Through independent testing the function DEFINE_SPINLOCK and object spinlock_t are working as intended. After thorough debugging the problem is in the create function. I freely admit that I am still learning how semaphores work so chances are I didn't set variables correctly or define things correctly. Any help in pointing me the right way would be greatly appreciated.

Deleting The Head of The List in Linux Kernel

We are developing a kernel device. There is a list in a device that keeps the messages. We want to delete the head of the list. The related part of the code is below:
Device Message and Device Struct:
typedef struct dev_message
{
char *data;
int *message_count;
struct list_head list;
}device_message;
typedef struct queue_dev
{
device_message *message_head;
struct semaphore sem;
struct cdev cdev;
}queue_device;
Adding to head of the list is done with
INIT_LIST_HEAD(&(dev->message_head->list));
and adding the other entries are done with
list_add_tail(&newMsg->list,&dev->message_head->list);
We can delete every element of the list except the head of the list. How can we delete the only head of the list?
Sincerely.

Static allocation of struct members within another static struct?

I am trying to implement a low-level thread lock without the use of dynamic memory allocation; this code will basically be used on a completely bare-bones kernel.
However, I am running into the problem of receiving a seg fault when I am trying to dereference a member inside this global static struct. My code is as such
My wrapper struct
/** LOCKING STRUCT & FUNCTIONS **/
struct lock {
int free;
struct thread_list* wait_list;
struct thread* current_holder;
};
The nested struct(intended as a linked list sort of deal)
struct thread_list {
struct thread *head;
};
And the member inside this list
struct thread {
void *top; // top of the stack for this thread
void *sp; // current stack pointer for this thread (context)
void (*start_func)(void *);
void *arg;
int state;
int exit_value;
struct thread *join_thread;
struct thread *next_thread;
int id;
};
The method I'm trying to implement is as such
void lock_init (struct lock *lk) {
lk->free = 1; //Set lock as free
struct thread_list waiting = lk->wait_list; //Get waitlist, works fine
waiting->head = NULL; //Set waitlist's head to null, SEGFAULTS HERE
}
I am not super proficient at C, but I can't seem to figure out the correct methodology/syntax to make my code work like this.
struct thread_list waiting = lk->wait_list; //Get waitlist, works fine
waiting->head = NULL; //Set waitlist's head to null, SEGFAULTS HERE
waiting is not a struct pointer but a struct variable . To access member using it you need to use . operator -
waiting.head = NULL;
Or to use -> operator declare it as a struct pointer .

How to make a link : chained list and pointer in c

Helle everyone, I'm stuck in a problem for 1 week and I come here..
I have few structures:
typedef struct s_task{
unsigned int id;
char *name;
}task
typedef struct s_element_task{
task *t;
struct s_element_task *next_element;
} element_task;
typedef element_task* task_list;
typedef struct s_agenda{
task_list *task_by_date;
} agenda;
I want to add a task to an agenda but I don't know how to make the link betewwen theses structures..
I start with:
task* my_task = malloc(sizeof(task));
but that's all..
thank you un advance
task* my_task = malloc(sizeof(task)); // data object
element_task* my_node = malloc(sizeof(element_task)); // node object
my_node.t = my_stask; // node now knows where data is
element_task* next_node = malloc(sizeof(element_task)); // next node object
my_node.next_element = next_node; // "link" to next node in linked list
As a side note, I'd make sure to initialize element_task.next_element to NULL so you can tell whether that node HAS a child or not.

linux kernel list_head vs empty entry that contains list_head

I'm trying to understand how this list works, by looking at the macro expansion of list_for_each_entry, the condition to exit the for is
&pos->list_member != head
but I see code that written like this and works fine, I don't understand why it works
struct entry {
int some_var;
struct list_head list;
};
struct global {
struct list_head entries_list;
};
struct global Global;
INIT_LIST_HEAD(&global.entries_list)
entry = kmalloc(new_entry..)
list_add_tail(&entry,&Global.entries_list);
list_for_each_entry(entry,&Global.entries_list,list) {
}
So by the end of the for, I should expect &entry->list == &Global.entries_list?
How is this possible?
So by the end of the for, I should expect &entry->list == &Global.entries_list?
Yes.
How is this possible?
Condition above means that entry is fake: it is not an element in the list, but just a raw pointer, which satisfies to given condition.

Resources