what is the 'magic' value in tty_driver struct
struct tty_driver {
int magic; /* magic number for this structure */
struct kref kref; /* Reference management */
struct cdev cdev;
struct module *owner;
const char *driver_name;
....
....
/* tty driver magic number */
#define TTY_DRIVER_MAGIC 0x5402
From tty_driver.h listing here.
Related
Here's my code
#include <linux/list.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/slab.h>
typedef struct list_head list;
typedef struct student *ptr;
typedef struct student *studentDemo;
static LIST_HEAD(student_list);
struct student{
int studentNumber;
int courseCredit;
float grade;
studentDemo = kmalloc(sizeof(*studentDemp), GFP_KERNEL);
studentDemo -> studentNumber = 760120495;
studentDemo -> courseCredit = 3;
studentDemo -> grade = 3.0;
INIT_LIST_HEAD(&studentDemo->list);
}
I keep getting these errors
You have few problems:
typedef declaration is not creating a memory, therefore you can't assign something to a "typedef" string. typedef struct student * studentDemo - can be read "whenever the compiler will encoutner the string "studentDemo", replace with a pointer to a struct of type student". Obviously you can't assign anything to such a definition.
You can't assign memory to a pointer during the definition of the class/struct - this should be done during main where memory can be allocated from the stack.
You should first declare a member of type studentDemo (actually the pointer to the student struct) and then you can assign to it.
You should assign the memory during main().
Here is an example of C
#include <stdio.h>
#include <stdlib.h>
typedef struct student *studentDemo;
struct student
{
studentDemo myStruct;
};
void main()
{
struct student my_variable;
my_variable.myStruct = (studentDemo)malloc(1 * sizeof(studentDemo));
return;
}
Here:
typedef struct student *studentDemo;
you defined studentDemo as an alias-name for type (struct student *)
and here:
XXXX -> studentNumber
XXXX should be a pointer expression (posibly a variable of type struct student *), but not the type itself.
I was going though chapter 14 of LDD3 and found following in the section 4;
As a general rule, device->kobj->parent is equal to
&device->parent->kobj
Can someone please explain why so?
I read section 1,2,3. But I guess I missed something or couldn't digest it.
You can think this as inheritance of the object oriented concept.
A struct kobject represents a kernel object, so device is kind subclass of a kobject.
struct device {
struct device * parent;
struct device_private * p;
struct kobject kobj;
..
}
struct kobject {
char *k_name;
char name[KOBJ_NAME_LEN];
struct kref kref;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct dentry *dentry;
};
A device has its parent device, and parent device's kobject is also parent of device's kobject. This relationship is taken care by the the linux kernel.
That's why device->kobj->parent equal to device->parent->kobj. (Device's kobject's parent equals to device's parent's kobject).
It's strange that struct cdev has struct kobject member, do any body knows the reason?
When kobjects are embedded inside other structures, the structures receive the standardized functions that a kobject provides. Most importantly, the structure's embedded kobject now enables the structure to become part of an object hierarchy. For example the cdev structure is presentable in an object hierarchy via the parent pointer cdev->kobj.parent and the list cdev->kobj.entry
Source: Linux Kernel Development by Robert Love
Sysfs is a Virtual filesystem that describes the devices available to the system in hierarchical pattern. This is done by using struct kobj.
struct kobject {
char *k_name;
char name[KOBJ_NAME_LEN];
struct kref kref;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct dentry *dentry;
};
For any driver kobj is required to export the device attributes to sysfs
if we consider like i2c_client spi_device(spi client). we have kobj inside member struct dev to export the driver attributes to the user space virtual filesystem(Sysfs). The Kobj structure members handles all the operations including referring to the device numbers(major/minor) and file operations involved for open, read/write,close etc... of device.
In your case cdev_init & cdev_add will internally uses kobj to do the above operation.
There are two reasons:
for reference counting, which is offered by kref internally.
static struct kobject *cdev_get(struct cdev *p)
{
struct module *owner = p->owner;
struct kobject *kobj;
if (owner && !try_module_get(owner))
return NULL;
kobj = kobject_get_unless_zero(&p->kobj);
if (!kobj)
module_put(owner);
return kobj;
}
void cdev_put(struct cdev *p)
{
if (p) {
struct module *owner = p->owner;
kobject_put(&p->kobj);
module_put(owner);
}
}
for release, that's also why kref is not enough(kref doesn't have a release hook).
static void cdev_default_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
struct kobject *parent = kobj->parent;
cdev_purge(p);
kobject_put(parent);
}
static void cdev_dynamic_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
struct kobject *parent = kobj->parent;
cdev_purge(p);
kfree(p);
kobject_put(parent);
}
static struct kobj_type ktype_cdev_default = {
.release = cdev_default_release,
};
static struct kobj_type ktype_cdev_dynamic = {
.release = cdev_dynamic_release,
};
i'm trying to study the linux kernel and reading the kernel code,
but i can't understand the structure they use for the page structure as shown below:
i mean,why they use union nested in the struct which nested in the union
(the code is simplified...)
struct page {
unsigned long flags;
struct address_space *mapping;
struct {
union {
pgoff_t index;
void *freelist;
};
union {
unsigned counters;
struct {
union {
atomic_t _mapcount;
struct {
unsigned inuse:16;
unsigned objects:15;
unsigned frozen:1;
};
};
atomic_t _count;
};
};
};
}
It is used to bring clarity into the code. It will be easier to read and understand if members are grouped.
Since you are not using the 'sub-structures' in any other data-structure, they are nested. Else, they would be declared separate and included as members, like below:
struct list_based{
pgoff_t index;
void *freelist;
};
struct page {
unsigned long flags;
struct address_space *mapping;
struct list_based lpage;
};
struct sector {
unsigned long sub sect;
struct list_based lsect;
};
I know if we have task_struct, surly we can get the contained sched_entity because it's one field in the task struct. But can we get the pointer to the task_struct given the shed_entity? Following is the sched_entity structure:
struct sched_entity {
struct load_weight load; /* for load-balancing */
struct rb_node run_node;
struct list_head group_node;
unsigned int on_rq;
u64 exec_start;
u64 sum_exec_runtime;
u64 vruntime;
u64 prev_sum_exec_runtime;
u64 nr_migrations;
#ifdef CONFIG_SCHEDSTATS
struct sched_statistics statistics;
#endif
#ifdef CONFIG_FAIR_GROUP_SCHED
struct sched_entity *parent;
/* rq on which this entity is (to be) queued: */
struct cfs_rq *cfs_rq;
/* rq "owned" by this entity/group: */
struct cfs_rq *my_q;
#endif
};
It seems that there is no place where I can get the task_struct. My final goal is to get the sched_entity of the task group_leader containing the task with this shed_entity :>
The Linux kernel code provides a standard way to take a pointer to an element contained within a structure, and get back a pointer to the containing structure: the container_of macro, which is used extensively throughout the kernel.
In this case, if you have a struct sched_entity *foo, you can get the enclosing task_struct with:
struct task_struct *task = container_of(foo, struct task_struct, se);
(Obviously this is only safe if you know for sure that the original struct sched_entity * pointer is pointing to a struct sched_entity which is inside a struct task_struct, so be careful...)