设备驱动杂记

来源:互联网 发布:真丝枕巾 知乎 推荐 编辑:程序博客网 时间:2024/05/25 12:22

1、  大部分的编程问题其实可以划分为2个部分,提供什么能力(机制)和如何使用这些能力(策略)。如果这两方面由程序的不同部分来表达,或者甚至由不同的程序共同表达,软件包时非常揉弄故意开发和适应特殊的需求。

2、  一个设备驱动可以只包含<linux/sched.h>并且引用当前进程。

3、  在内核中可以通过包含头文件<linux/sched.h>后使用current来使用当前进程的信息。

例如,下面的语句打印了当前进程的进程ID和命令名称。

Printk(KERN_INFO “The process is /” %s/” (pid %i) /n”),current->comm.,current->pid);

 

Current并不是一个真正的全局变量,它定义在arch/***/include/asmcurrent.h文件中,定义如下:

static __always_inline struct task_struct *get_current(void)

{

                            return percpu_read_stable(current_task);

}

#define current get_current()

以上定义使得current为指向task_struct结构的指针。

Task_struct结构如下:

 

structtask_struct {

     volatilelong state;  /* -1 unrunnable, 0 runnable,>0 stopped */

     void*stack;

     atomic_tusage;

     unsignedint flags;   /* per process flags, definedbelow */

     unsignedint ptrace;

 

     intlock_depth;                   /* BKL lockdepth */

 

#ifdef CONFIG_SMP

#ifdef __ARCH_WANT_UNLOCKED_CTXSW

     intoncpu;

#endif

#endif

 

     intprio, static_prio, normal_prio;

     unsignedint rt_priority;

     conststruct sched_class *sched_class;

     structsched_entity se;

     structsched_rt_entity rt;

 

#ifdef CONFIG_PREEMPT_NOTIFIERS

     /*list of struct preempt_notifier: */

     structhlist_head preempt_notifiers;

#endif

 

     /*

      * fpu_counter contains the number ofconsecutive context switches

      * that the FPU is used. If this is over athreshold, the lazy fpu

      * saving becomes unlazy to save the trap. Thisis an unsigned char

      * so that after 256 times the counter wrapsand the behavior turns

      * lazy again; this to deal with bursty appsthat only use FPU for

      * a short time

      */

     unsignedchar fpu_counter;

#ifdef CONFIG_BLK_DEV_IO_TRACE

     unsignedint btrace_seq;

#endif

 

     unsignedint policy;

     cpumask_tcpus_allowed;

 

#ifdef CONFIG_TREE_PREEMPT_RCU

     intrcu_read_lock_nesting;

     charrcu_read_unlock_special;

     structrcu_node *rcu_blocked_node;

     structlist_head rcu_node_entry;

#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU*/

 

#if defined(CONFIG_SCHEDSTATS) ||defined(CONFIG_TASK_DELAY_ACCT)

     structsched_info sched_info;

#endif

 

     structlist_head tasks;

     structplist_node pushable_tasks;

 

     structmm_struct *mm, *active_mm;

#if defined(SPLIT_RSS_COUNTING)

     structtask_rss_stat        rss_stat;

#endif

/* task state */

     intexit_state;

     intexit_code, exit_signal;

     intpdeath_signal;  /*  The signal sent when the parent dies  */

     /*??? */

     unsignedint personality;

     unsigneddid_exec:1;

     unsignedin_execve:1;     /* Tell the LSMs that theprocess is doing an

                                  * execve */

     unsignedin_iowait:1;

 

 

     /*Revert to default priority/policy when forking */

     unsignedsched_reset_on_fork:1;

 

  //进程标识号

  //在内核中pid对进程而言是进程号,对于线程而言是线程号,同一进程的不同线程的pid是不同的,但是同一进程的不同线程有统一的tgid

     pid_tpid;

     pid_ttgid;

 

#ifdef CONFIG_CC_STACKPROTECTOR

     /*Canary value for the -fstack-protector gcc feature */

     unsignedlong stack_canary;

#endif

 

     /*

      * pointers to (original) parent process,youngest child, younger sibling,

      * older sibling, respectively.  (p->father can be replaced with

      * p->real_parent->pid)

      */

     structtask_struct *real_parent; /* real parent process */

     structtask_struct *parent; /* recipient of SIGCHLD, wait4() reports */

     /*

      * children/sibling forms the list of mynatural children

      */

     structlist_head children;         /* list of mychildren */

     structlist_head sibling;   /* linkage in myparent's children list */

     structtask_struct *group_leader; /* threadgroupleader */

 

     /*

      * ptraced is the list of tasks this task isusing ptrace on.

      * This includes both natural children andPTRACE_ATTACH targets.

      * p->ptrace_entry is p's link on thep->parent->ptraced list.

      */

     structlist_head ptraced;

     structlist_head ptrace_entry;

 

     /*

      * This is the tracer handle for the ptrace BTSextension.

      * This field actually belongs to the ptracertask.

      */

     structbts_context *bts;

 

     /*PID/PID hash table linkage. */

     structpid_link pids[PIDTYPE_MAX];

     structlist_head thread_group;

 

     structcompletion *vfork_done;                /*for vfork() */

     int__user *set_child_tid;                 /*CLONE_CHILD_SETTID */

     int__user *clear_child_tid;              /*CLONE_CHILD_CLEARTID */

 

     cputime_tutime, stime, utimescaled, stimescaled;

     cputime_tgtime;

#ifndef CONFIG_VIRT_CPU_ACCOUNTING

     cputime_tprev_utime, prev_stime;

#endif

     unsignedlong nvcsw, nivcsw; /* context switch counts */

     structtimespec start_time;            /*monotonic time */

     structtimespec real_start_time;   /* boot basedtime */

/* mm fault and swap info: this canarguably be seen as either mm-specific or thread-specific */

     unsignedlong min_flt, maj_flt;

 

     structtask_cputime cputime_expires;

     structlist_head cpu_timers[3];

 

/* process credentials */

     conststruct cred *real_cred; /* objective andreal subjective task

                                           * credentials (COW) */

     conststruct cred *cred;  /* effective(overridable) subjective task

                                           * credentials (COW) */

     structmutex cred_guard_mutex;   /* guard againstforeign influences on

                                           * credential calculations

                                           * (notably. ptrace) */

     structcred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */

 

  //进程正在运行的可执行文件名称

     charcomm[TASK_COMM_LEN]; /* executable name excluding path

                                      - access with [gs]et_task_comm (which lock

                                        it with task_lock())

                                      - initialized normally by setup_new_exec*/

/* file system info */

     intlink_count, total_link_count;

#ifdef CONFIG_SYSVIPC

/* ipc stuff */

     structsysv_sem sysvsem;

#endif

#ifdef CONFIG_DETECT_HUNG_TASK

/* hung task detection */

     unsignedlong last_switch_count;

#endif

/* CPU-specific state of this task */

     structthread_struct thread;

/* filesystem information */

     structfs_struct *fs;

/* open file information */

     structfiles_struct *files;

/* namespaces */

     structnsproxy *nsproxy;

/* signal handlers */

     structsignal_struct *signal;

     structsighand_struct *sighand;

 

     sigset_tblocked, real_blocked;

     sigset_tsaved_sigmask;          /* restored ifset_restore_sigmask() was used */

     structsigpending pending;

 

     unsignedlong sas_ss_sp;

     size_tsas_ss_size;

     int(*notifier)(void *priv);

     void*notifier_data;

     sigset_t*notifier_mask;

     structaudit_context *audit_context;

#ifdef CONFIG_AUDITSYSCALL

     uid_tloginuid;

     unsignedint sessionid;

#endif

     seccomp_tseccomp;

 

/* Thread group tracking */

          u32 parent_exec_id;

          u32 self_exec_id;

/* Protection of (de-)allocation: mm,files, fs, tty, keyrings, mems_allowed,

 *mempolicy */

     spinlock_talloc_lock;

 

#ifdef CONFIG_GENERIC_HARDIRQS

     /*IRQ handler threads */

     structirqaction *irqaction;

#endif

 

     /*Protection of the PI data structures: */

     raw_spinlock_tpi_lock;

 

#ifdef CONFIG_RT_MUTEXES

     /*PI waiters blocked on a rt_mutex held by this task */

     structplist_head pi_waiters;

     /*Deadlock detection and priority inheritance handling */

     structrt_mutex_waiter *pi_blocked_on;

#endif

 

#ifdef CONFIG_DEBUG_MUTEXES

     /*mutex deadlock detection */

     structmutex_waiter *blocked_on;

#endif

#ifdef CONFIG_TRACE_IRQFLAGS

     unsignedint irq_events;

     unsignedlong hardirq_enable_ip;

     unsignedlong hardirq_disable_ip;

     unsignedint hardirq_enable_event;

     unsignedint hardirq_disable_event;

     inthardirqs_enabled;

     inthardirq_context;

     unsignedlong softirq_disable_ip;

     unsignedlong softirq_enable_ip;

     unsignedint softirq_disable_event;

     unsignedint softirq_enable_event;

     intsoftirqs_enabled;

     intsoftirq_context;

#endif

#ifdef CONFIG_LOCKDEP

# define MAX_LOCK_DEPTH 48UL

     u64curr_chain_key;

     intlockdep_depth;

     unsignedint lockdep_recursion;

     structheld_lock held_locks[MAX_LOCK_DEPTH];

     gfp_tlockdep_reclaim_gfp;

#endif

 

/* journalling filesystem info */

     void*journal_info;

 

/* stacked block device info */

     structbio_list *bio_list;

 

/* VM state */

     structreclaim_state *reclaim_state;

 

     structbacking_dev_info *backing_dev_info;

 

     structio_context *io_context;

 

     unsignedlong ptrace_message;

     siginfo_t*last_siginfo; /* For ptrace use.  */

     structtask_io_accounting ioac;

#if defined(CONFIG_TASK_XACCT)

     u64acct_rss_mem1;       /* accumulated rssusage */

     u64acct_vm_mem1;       /* accumulated virtualmemory usage */

     cputime_tacct_timexpd;         /* stime + utimesince last update */

#endif

#ifdef CONFIG_CPUSETS

     nodemask_tmems_allowed;  /* Protected by alloc_lock*/

     intcpuset_mem_spread_rotor;

#endif

#ifdef CONFIG_CGROUPS

     /*Control Group info protected by css_set_lock */

     structcss_set *cgroups;

     /*cg_list protected by css_set_lock and tsk->alloc_lock */

     structlist_head cg_list;

#endif

#ifdef CONFIG_FUTEX

     structrobust_list_head __user *robust_list;

#ifdef CONFIG_COMPAT

     structcompat_robust_list_head __user *compat_robust_list;

#endif

     structlist_head pi_state_list;

     structfutex_pi_state *pi_state_cache;

#endif

#ifdef CONFIG_PERF_EVENTS

     structperf_event_context *perf_event_ctxp;

     structmutex perf_event_mutex;

     structlist_head perf_event_list;

#endif

#ifdef CONFIG_NUMA

     structmempolicy *mempolicy;        /* Protectedby alloc_lock */

     shortil_next;

#endif

     atomic_tfs_excl;     /* holding fs exclusiveresources */

     structrcu_head rcu;

 

     /*

      * cache last used pipe for splice

      */

     structpipe_inode_info *splice_pipe;

#ifdef    CONFIG_TASK_DELAY_ACCT

     structtask_delay_info *delays;

#endif

#ifdef CONFIG_FAULT_INJECTION

     intmake_it_fail;

#endif

     structprop_local_single dirties;

#ifdef CONFIG_LATENCYTOP

     intlatency_record_count;

     structlatency_record latency_record[LT_SAVECOUNT];

#endif

     /*

      * time slack values; these are used to roundup poll() and

      * select() etc timeout values. These are innanoseconds.

      */

     unsignedlong timer_slack_ns;

     unsignedlong default_timer_slack_ns;

 

     structlist_head        *scm_work_list;

#ifdef CONFIG_FUNCTION_GRAPH_TRACER

     /*Index of current stored address in ret_stack */

     intcurr_ret_stack;

     /*Stack of return addresses for return function tracing */

     structftrace_ret_stack   *ret_stack;

     /*time stamp for last schedule */

     unsignedlong long ftrace_timestamp;

     /*

      * Number of functions that haven't been traced

      * because of depth overrun.

      */

     atomic_ttrace_overrun;

     /*Pause for the tracing */

     atomic_ttracing_graph_pause;

#endif

#ifdef CONFIG_TRACING

     /*state flags for use by tracers */

     unsignedlong trace;

     /*bitmask of trace recursion */

     unsignedlong trace_recursion;

#endif /* CONFIG_TRACING */

#ifdef CONFIG_CGROUP_MEM_RES_CTLR /*memcg uses this to do batch job */

     structmemcg_batch_info {

              intdo_batch;   /* incremented when batchuncharge started */

              structmem_cgroup *memcg; /* target memcg of uncharge */

              unsignedlong bytes;                /* unchargedusage */

              unsignedlong memsw_bytes; /* uncharged mem+swap usage */

     }memcg_batch;

#endif

};

 

4、  lsmod通过读取/proc/modules虚拟文件工作,当前加载的模块的信息也可在位于/sys/modulesysfs虚拟文件系统中找到。

5、  查看一个内核模块***.ko究竟包含哪些符号?

nm –l ***.ko

6、  查看内核符号表

cat /proc/kallsyms

7、  导出符号的两种方式:

     EXPORT_SYMBOL(get_process_info);

EXPORT_SYMBOL_GPL(get_process_info_gpl);

8、  查看模块信息

modinfo ***.ko

9、  内核加载时传递参数

需要如下几个步骤:

    <1>、在内核中添加如下语句:

                                static char * whom = "xu_guo";

int howmany =1;

module_param(whom,charp,S_IRUGO);

module_param(howmany,int,S_IRUGO);

           <2>、加载时如下方式执行:

                      Insmod e1.ko whom=”xu”howmany=10  <enter>

10、             模块加载时的数组参数传递方式:

     Module_param_array(name,type,num,perm);

如果确实需要一个没有出现在上面列表中的类型,在模块代码里有钩子会允许你来定义它们。

11、每个PCI外设有一个总线号,一个设备号,一个功能标识号。

原创粉丝点击