使用proc文件系统能够非常方便调试驱动。查看驱动中的一些数据

平台:TQ2440

系统版本号:

root@ubuntu:/mnt/shared/kobox# uname -a

Linux ubuntu 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:12:00 UTC 2013 i686 i686 i686 GNU/Linux

事实上在3.x中创建proc文件系统和在2.x中创建是有所差别的,这里须要注意下。在2.6.x中创建起来更加方便

这里是在3.x的内核中创建proc文件的方法

功能:

/proc/key_drv写操作:

这里使用proc文件系统查看TQ2440各按键被按的次数

echo 'a' > /proc/key_drv -- 查看全部按键状态

echo '0' > /proc/key_drv -- 查看key1按键状态 

...

echo 'h' > /proc/key_drv -- 打印帮助

/proc/key_drv读操作:

cat /proc/key_drv -- 查看TQ2440各按键被按的次数

(一)运行结果:

[\u@\h \W]# echo '0'> /proc/key_drv 

key_num:0

key:[key1], pressCnt:3

[\u@\h \W]# echo '1'> /proc/key_drv 

key_num:1

key:[key2], pressCnt:4

[\u@\h \W]# echo '2'> /proc/key_drv 

key_num:2

key:[key3], pressCnt:6

[\u@\h \W]# echo '3'> /proc/key_drv 

key_num:3

key:[key4], pressCnt:0

[\u@\h \W]# echo 'a'> /proc/key_drv 

key_num:a

pressCnt[i]:0

pressCnt[i]:1

pressCnt[i]:2

pressCnt[i]:3

[\u@\h \W]# echo 'h'> /proc/key_drv 

key_num:h

/proc/key_drv help:

echo a > /proc/key_drv -- get all keys' pressCnt!

echo i(0~3) > /proc/key_drv -- get all key[i+1]'s pressCnt!

echo h > /proc/key_drv -- usage help!

(二) proc文件系统的创建:

  1. static int key_drv_proc_show(struct seq_file *m, void *v)
  2. {
  3. int i;
  4.  
  5. read_lock(&key_drv_proc_lock);
  6.  
  7. for(i=0; i<ARRAY_SIZE(key_gpio_res); i++)
  8. {
  9. seq_printf(m, "name:[%s], count:[%d]\n",
  10. key_gpio_res[i].irqName,
  11. pressCnt[i]);
  12. }
  13.  
  14. read_unlock(&key_drv_proc_lock);
  15.  
  16. return 0;
  17. }
  18.  
  19. static int key_drv_proc_open(struct inode *inode, struct file *file)
  20. {
  21. return single_open(file, key_drv_proc_show, NULL);
  22. }
  23.  
  24. static void key_drv_proc_help(void)
  25. {
  26. printk("/proc/key_drv help:\n"
  27. "echo a > /proc/key_drv -- get all keys' pressCnt!\n"
  28. "echo i(0~3) > /proc/key_drv -- get all key[i+1]'s pressCnt!\n"
  29. "echo h > /proc/key_drv -- usage help!\n"
  30. );
  31. return;
  32. }
  33.  
  34. static ssize_t key_drv_proc_write(struct file *file, const char __user *buffer,
  35. size_t count, loff_t *pos)
  36. {
  37. char mode;
  38. char key_num;
  39. int i;
  40.  
  41. if (count > 0) {
  42. if (get_user(key_num, buffer))
  43. return -EFAULT;
  44.  
  45. printk("key_num:%c\n", key_num);
  46.  
  47. switch(key_num)
  48. {
  49. case 'a':
  50. for(i=0; i<ARRAY_SIZE(pressCnt); i++)
  51. {
  52. printk("pressCnt[i]:%d\n", i, pressCnt[i]);
  53. }
  54. break;
  55.  
  56. case '0':
  57. printk("key:[%s], pressCnt:%d\n", key_gpio_res[0].irqName,pressCnt[0]);
  58. break;
  59.  
  60. case '1':
  61. printk("key:[%s], pressCnt:%d\n", key_gpio_res[1].irqName,pressCnt[1]);
  62. break;
  63.  
  64. case '2':
  65. printk("key:[%s], pressCnt:%d\n", key_gpio_res[2].irqName,pressCnt[2]);
  66. break;
  67.  
  68. case '3':
  69. printk("key:[%s], pressCnt:%d\n", key_gpio_res[3].irqName,pressCnt[3]);
  70. break;
  71.  
  72. case 'h':
  73. default:
  74. key_drv_proc_help();
  75. return -1;
  76. }
  77. }
  78. return count;
  79. }
  80.  
  81. static const struct file_operations key_drv_fops = {
  82. .open = key_drv_proc_open,
  83. .read =seq_read,
  84. .write = key_drv_proc_write,
  85. .release = single_release,
  86. };
  87.  
  88. static int key_proc_file_init(void)
  89. {
  90. proc_create("key_drv", 0, NULL, &key_drv_fops);
  91. return 0;
  92. }
  93.  
  94. key_proc_file_init();

(三)key_proc.c所有源代码

  1. #include "key.h"
  2. #include <linux/seq_file.h>
  3.  
  4. #define S3C_ADDR_BASE 0xF6000000
  5. //#define S3C_ADDR(x) (S3C_ADDR_BASE + (x))
  6. #define S3C2410_PA_UART (0x50000000)
  7. #define S3C2410_PA_GPIO (0x56000000)
  8. #define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
  9. #define S3C24XX_PA_UART S3C2410_PA_UART
  10. #define S3C24XX_VA_UART S3C_VA_UART
  11. #define S3C24XX_PA_GPIO S3C2410_PA_GPIO
  12. #define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
  13.  
  14. #define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
  15.  
  16. #define S3C2410_GPBCON S3C2410_GPIOREG(0x10)
  17. #define S3C2410_GPBDAT S3C2410_GPIOREG(0x14)
  18. #define S3C2410_GPBUP S3C2410_GPIOREG(0x18)
  19.  
  20. #define S3C2410_GPFCON S3C2410_GPIOREG(0x50)
  21. #define S3C2410_GPFDAT S3C2410_GPIOREG(0x54)
  22. #define S3C2410_GPFUP S3C2410_GPIOREG(0x58)
  23.  
  24. #define S3C2410_EXTINT0 S3C2410_GPIOREG(0x88)
  25. #define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C)
  26. #define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90)
  27.  
  28. #define S3C2410_CPUIRQ_OFFSET (16)
  29. #define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET)
  30. /* main cpu interrupts */
  31. #define IRQ_EINT0 S3C2410_IRQ(0) /* 16 */
  32. #define IRQ_EINT1 S3C2410_IRQ(1) /* 17 */
  33. #define IRQ_EINT2 S3C2410_IRQ(2) /* 18 */
  34. #define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */
  35. #define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */
  36.  
  37. #define IRQF_DISABLED 0x00000020
  38. #define IRQF_SHARED 0x00000080
  39. #define IRQF_PROBE_SHARED 0x00000100
  40. #define __IRQF_TIMER 0x00000200
  41. #define IRQF_PERCPU 0x00000400
  42. #define IRQF_NOBALANCING 0x00000800
  43. #define IRQF_IRQPOLL 0x00001000
  44. #define IRQF_ONESHOT 0x00002000
  45. #define IRQF_NO_SUSPEND 0x00004000
  46. #define IRQF_FORCE_RESUME 0x00008000
  47. #define IRQF_NO_THREAD 0x00010000
  48. #define IRQF_EARLY_RESUME 0x00020000
  49.  
  50. typedef struct gpioRes
  51. {
  52. int irqNum; /* 中断号 */
  53. unsigned int ctrlReg; /* 控制寄存器,用于设置复用为GPIO */
  54. unsigned int ctrlBit; /* 控制寄存器的哪一位,用于复用为GPIO */
  55. unsigned int trigReg; /* 中断方式寄存器,设置中断的触发方式 */
  56. unsigned int trigBit; /* 中断方式寄存器哪一位。设置中断的触发方式 */
  57. unsigned int irqFlag; /* 共享还是不共享,注冊中断的flag */
  58. char irqName[32]; /* 中断名称 */
  59. unsigned int gpfPin; /* GPF的第几个pin */
  60. char Reserved[10]; /* 保留 */
  61. }gpioRes;
  62.  
  63. unsigned int pressCnt[4] = {0, 0, 0, 0};
  64.  
  65. //#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
  66.  
  67. static int kobox_key_open(struct inode *inode, struct file *file)
  68. {
  69. return 0;
  70. }
  71.  
  72. static int kobox_key_release(struct inode *inode, struct file *file)
  73. {
  74. return 0;
  75. }
  76.  
  77. static long kobox_key_ioctl(struct file *file, unsigned int cmd,
  78. unsigned long arg)
  79. {
  80. return 0;
  81. }
  82.  
  83. static int kobox_key_read(struct file *file, char __user *buff, size_t count, loff_t *pos)
  84. {
  85. printk("Enter [%s][%d]\n", __FUNCTION__,__LINE__);
  86. copy_to_user(buff, &pressCnt[0], sizeof(pressCnt));
  87.  
  88. return 0;
  89. }
  90.  
  91. /*
  92. GPF相关寄存器:
  93.  
  94. GPFCON 0x56000050 R/W Configures the pins of port F 0x0
  95. GPFDAT 0x56000054 R/W The data register for port F Undef.
  96. GPFUP 0x56000058 R/W Pull-up disable register for port F 0x000
  97.  
  98. K1: GPF1 -EINT1: GPF1 [3:2] 00 = Input 01 = Output 10 = EINT[1] 11 = Reserved
  99. K2: GPF4 -EINT4: GPF4 [9:8] 00 = Input 01 = Output 10 = EINT[4] 11 = Reserved
  100. K3: GPF2 -EINT2: GPF2 [5:4] 00 = Input 01 = Output 10 = EINT2] 11 = Reserved
  101. K4: GPF0 -EINT0: GPF0 [1:0] 00 = Input 01 = Output 10 = EINT[0] 11 = Reserved
  102. */
  103.  
  104. gpioRes key_gpio_res[4] =
  105. {
  106. {IRQ_EINT1, S3C2410_GPFCON, 2, S3C2410_EXTINT0, 5, NULL, "key1", 1}, /* key1 */
  107. {IRQ_EINT4, S3C2410_GPFCON, 8, S3C2410_EXTINT0, 17, IRQF_SHARED, "key2", 4}, /* key2 */
  108. {IRQ_EINT2, S3C2410_GPFCON, 4, S3C2410_EXTINT0, 9, NULL, "key3", 2}, /* key3 */
  109. {IRQ_EINT0, S3C2410_GPFCON, 0, S3C2410_EXTINT0, 1, NULL, "key4", 0}, /* key4 */
  110. };
  111.  
  112. #define KEY_TIMER_DELAY1 (HZ/50) //按键按下去抖延时20毫秒
  113. #define KEY_TIMER_DELAY2 (HZ/10) //按键抬起去抖延时100毫秒
  114. #define KEY_COUNT 4
  115. static struct timer_list key_timers[KEY_COUNT]; //定义4个按键去抖动定时器
  116. static DECLARE_WAIT_QUEUE_HEAD(button_waitq); //定义并初始化等待队列
  117.  
  118. static void set_gpio_as_eint(void)
  119. {
  120. int i;
  121. unsigned uiVal = 0;
  122.  
  123. for(i=0; i< ARRAY_SIZE(key_gpio_res); i++)
  124. {
  125. uiVal = readl(key_gpio_res[i].ctrlReg);
  126. uiVal &= ~(0x01 << key_gpio_res[i].ctrlBit);
  127. uiVal |= (0x01 << (key_gpio_res[i].ctrlBit + 1));
  128. writel(uiVal, key_gpio_res[i].ctrlReg);
  129. }
  130.  
  131. return;
  132. }
  133.  
  134. static void set_gpio_as_gpio(void)
  135. {
  136. int i;
  137. unsigned uiVal = 0;
  138.  
  139. for(i=0; i< ARRAY_SIZE(key_gpio_res); i++)
  140. {
  141. uiVal = readl(key_gpio_res[i].ctrlReg);
  142. uiVal &= ~(0x01 << key_gpio_res[i].ctrlBit);
  143. uiVal &= ~(0x01 << (key_gpio_res[i].ctrlBit + 1));
  144. writel(uiVal, key_gpio_res[i].ctrlReg);
  145. }
  146.  
  147. return;
  148. }
  149.  
  150. static irqreturn_t kobox_gpio_irq_handle(int irq, void *dev_id)
  151. {
  152. int key;
  153.  
  154. disable_irq_nosync(irq);
  155.  
  156. printk("irq = %d\n", irq);
  157.  
  158. if(dev_id)
  159. printk("dev_id:%s\n", dev_id);
  160.  
  161. switch(irq)
  162. {
  163. case IRQ_EINT1:
  164. key = 0;
  165. break;
  166. case IRQ_EINT4:
  167. key = 1;
  168. break;
  169. case IRQ_EINT2:
  170. key = 2;
  171. break;
  172. case IRQ_EINT0:
  173. key = 3;
  174. break;
  175. default:
  176. printk("invalid irq:%d\n", irq);
  177. return IRQ_HANDLED;
  178. }
  179.  
  180. /* 去抖:延时100ms后,在buttons_timer中读取按键状态。假设还是按下的。就说明是被正常按下的
  181. 使用timer是一种方式。后面再採用工作队列、tasklet中的方式来处理 */
  182. mod_timer(&key_timers[key], jiffies + KEY_TIMER_DELAY2);
  183.  
  184. enable_irq(irq);
  185.  
  186. return IRQ_RETVAL(IRQ_HANDLED);
  187. }
  188.  
  189. /*
  190. GPF相关寄存器:
  191.  
  192. GPFCON 0x56000050 R/W Configures the pins of port F 0x0
  193. GPFDAT 0x56000054 R/W The data register for port F Undef.
  194. GPFUP 0x56000058 R/W Pull-up disable register for port F 0x000
  195.  
  196. K1: GPF1 -EINT1: GPF1 [3:2] 00 = Input 01 = Output 10 = EINT[1] 11 = Reserved
  197. K2: GPF4 -EINT4: GPF4 [9:8] 00 = Input 01 = Output 10 = EINT[4] 11 = Reserved
  198. K3: GPF2 -EINT2: GPF2 [5:4] 00 = Input 01 = Output 10 = EINT2] 11 = Reserved
  199. K4: GPF0 -EINT0: GPF0 [1:0] 00 = Input 01 = Output 10 = EINT[0] 11 = Reserved
  200. */
  201. /* 该函数返回0表示按键被按下。返回非0表示没有再被按下,觉得这是电平毛刺导致的,是噪声信号
  202. 所以。该函数返回0,表示有按键被按下,返回非0表示是抖动 */
  203. static int get_gpio_portf_value(unsigned int pin)
  204. {
  205. int ret;
  206. unsigned int uiVal = 0;
  207.  
  208. printk("I AM @ [%s][%d], pin:%d\n", __FUNCTION__,__LINE__, pin);
  209.  
  210. uiVal = readl(S3C2410_GPFDAT);
  211. ret = (0x1 << pin) & uiVal;
  212.  
  213. printk("I AM @ [%s][%d], ret:%d\n", __FUNCTION__,__LINE__, ret);
  214.  
  215. return ret;
  216. }
  217.  
  218. /* 去抖:中断中设置定时器100ms,在buttons_timer中读取按键状态,假设还是按下的,就说明是被正常按下的 */
  219. static void buttons_timer(unsigned long arg)
  220. {
  221. int ret;
  222. unsigned int pin;
  223.  
  224. /* 中断后100ms才会导致。运行该函数 */
  225. printk("i am at [%s][%d], arg:%d\n", __FUNCTION__, __LINE__, arg);
  226.  
  227. pin = key_gpio_res[arg].gpfPin;
  228.  
  229. /* 将引脚由EINTX设置会GPIO */
  230. set_gpio_as_gpio();
  231.  
  232. /* 读取相应引脚GPIO的值,返回0表示按键真正被按下。返回1表示抖动 */
  233. ret = get_gpio_portf_value(pin);
  234. if(0 == ret)
  235. {
  236. pressCnt[arg]++;
  237. printk("key%d pressed: pressCnt[arg]:%d\n", arg, pressCnt[arg]);
  238. }
  239.  
  240. /* 将引脚设置回EINTX */
  241. set_gpio_as_eint();
  242.  
  243. return;
  244. }
  245.  
  246. static int request_irq_for_gpio(void)
  247. {
  248. int i;
  249. int ret;
  250. unsigned uiVal;
  251. int nouse;
  252.  
  253. for(i=0; i<ARRAY_SIZE(key_gpio_res);i++)
  254. {
  255. /* 设置中断触发方式:下降沿有效,触发中断,以便依据GPIO的值来推断是否仍在按下 */
  256. uiVal = readl(key_gpio_res[i].trigReg);
  257. uiVal |= (0x1 << (key_gpio_res[i].trigBit));
  258. uiVal &= ~(0x1 << (key_gpio_res[i].trigBit + 1));
  259. writel(uiVal, key_gpio_res[i].trigReg);
  260.  
  261. /* 注冊中断 */
  262. ret = request_irq(key_gpio_res[i].irqNum,
  263. kobox_gpio_irq_handle,
  264. key_gpio_res[i].irqFlag,
  265. key_gpio_res[i].irqName,
  266. (void *)key_gpio_res[i].irqName);
  267. if(ret)
  268. printk("[func:%s][line:%d] request_irq failed, ret:%d!\n", __FUNCTION__,__LINE__,ret);
  269. else
  270. printk("[func:%s][line:%d] request_irq ok, irq:%d!\n", __FUNCTION__,__LINE__, key_gpio_res[i].irqNum);
  271.  
  272. /* 初始化定时器,后面用于去抖动 */
  273. setup_timer(&key_timers[i], buttons_timer, i);
  274. key_timers[i].expires = jiffies + KEY_TIMER_DELAY1*i;
  275. add_timer(&key_timers[i]);
  276. }
  277.  
  278. return 0;
  279. }
  280.  
  281. struct file_operations kobox_key_operations = {
  282. .owner = THIS_MODULE,
  283. .open = kobox_key_open,
  284. .read = kobox_key_read,
  285. .release = kobox_key_release,
  286. .unlocked_ioctl = kobox_key_ioctl,
  287. };
  288.  
  289. static DEFINE_RWLOCK(key_drv_proc_lock);
  290. extern int seq_printf(struct seq_file *m, const char *f, ...);
  291.  
  292. static int key_drv_proc_show(struct seq_file *m, void *v)
  293. {
  294. int i;
  295.  
  296. read_lock(&key_drv_proc_lock);
  297.  
  298. for(i=0; i<ARRAY_SIZE(key_gpio_res); i++)
  299. {
  300. seq_printf(m, "name:[%s], count:[%d]\n",
  301. key_gpio_res[i].irqName,
  302. pressCnt[i]);
  303. }
  304.  
  305. read_unlock(&key_drv_proc_lock);
  306.  
  307. return 0;
  308. }
  309.  
  310. static int key_drv_proc_open(struct inode *inode, struct file *file)
  311. {
  312. return single_open(file, key_drv_proc_show, NULL);
  313. }
  314.  
  315. static void key_drv_proc_help(void)
  316. {
  317. printk("/proc/key_drv help:\n"
  318. "echo a > /proc/key_drv -- get all keys' pressCnt!\n"
  319. "echo i(0~3) > /proc/key_drv -- get all key[i+1]'s pressCnt!\n"
  320. "echo h > /proc/key_drv -- usage help!\n"
  321. );
  322. return;
  323. }
  324.  
  325. static ssize_t key_drv_proc_write(struct file *file, const char __user *buffer,
  326. size_t count, loff_t *pos)
  327. {
  328. char mode;
  329. char key_num;
  330. int i;
  331.  
  332. if (count > 0) {
  333. if (get_user(key_num, buffer))
  334. return -EFAULT;
  335.  
  336. printk("key_num:%c\n", key_num);
  337.  
  338. switch(key_num)
  339. {
  340. case 'a':
  341. for(i=0; i<ARRAY_SIZE(pressCnt); i++)
  342. {
  343. printk("pressCnt[i]:%d\n", i, pressCnt[i]);
  344. }
  345. break;
  346.  
  347. case '0':
  348. printk("key:[%s], pressCnt:%d\n", key_gpio_res[0].irqName,pressCnt[0]);
  349. break;
  350.  
  351. case '1':
  352. printk("key:[%s], pressCnt:%d\n", key_gpio_res[1].irqName,pressCnt[1]);
  353. break;
  354.  
  355. case '2':
  356. printk("key:[%s], pressCnt:%d\n", key_gpio_res[2].irqName,pressCnt[2]);
  357. break;
  358.  
  359. case '3':
  360. printk("key:[%s], pressCnt:%d\n", key_gpio_res[3].irqName,pressCnt[3]);
  361. break;
  362.  
  363. case 'h':
  364. default:
  365. key_drv_proc_help();
  366. return -1;
  367. }
  368. }
  369. return count;
  370. }
  371.  
  372. static const struct file_operations key_drv_fops = {
  373. .open = key_drv_proc_open,
  374. .read =seq_read,
  375. .write = key_drv_proc_write,
  376. .release = single_release,
  377. };
  378.  
  379. static int key_proc_file_init(void)
  380. {
  381. proc_create("key_drv", 0, NULL, &key_drv_fops);
  382. return 0;
  383. }
  384.  
  385. //GPB0
  386. int major;
  387. int minor;
  388. struct cdev cdev;
  389. struct class *kobox_key_class;
  390. struct device *pstdev = NULL;
  391. #define GPIO_KEY_NAME "kobox_key"
  392.  
  393. int __init key_drv_init(void)
  394. {
  395. int error;
  396. dev_t dev;
  397.  
  398. printk("#####enter key_drv_init!\n");
  399.  
  400. major = register_chrdev(0, GPIO_KEY_NAME, &kobox_key_operations);
  401. if (major < 0)
  402. {
  403. printk(" can't register major number\n");
  404. return major;
  405. }
  406.  
  407. /* create class */
  408. kobox_key_class = class_create(THIS_MODULE, GPIO_KEY_NAME);
  409. if(IS_ERR(kobox_key_class))
  410. {
  411. printk("class_create failed!\n");
  412. goto fail;
  413. }
  414.  
  415. /* create /dev/kobox_gpio */
  416. pstdev = device_create(kobox_key_class, NULL, MKDEV(major, 0), NULL, GPIO_KEY_NAME);
  417. if(!pstdev)
  418. {
  419. printk("device_create failed!\n");
  420. goto fail1;
  421. }
  422.  
  423. /* set gpf0/1/2/4 as extern interrupt pins */
  424. set_gpio_as_eint();
  425.  
  426. request_irq_for_gpio();
  427.  
  428. /* create proc files */
  429. key_proc_file_init();
  430.  
  431. printk("#####key_drv_init ok!\n");
  432.  
  433. return 0;
  434. fail1:
  435. class_destroy(kobox_key_class);
  436. fail:
  437. unregister_chrdev(major, GPIO_KEY_NAME);
  438. return -1;
  439. }
  440.  
  441. void __exit key_drv_exit(void)
  442. {
  443. printk("exit gpio drv!\n");
  444.  
  445. device_destroy(kobox_key_class, MKDEV(major, 0));
  446. class_destroy(kobox_key_class);
  447. unregister_chrdev(major, GPIO_KEY_NAME);
  448.  
  449. return;
  450. }
  451.  
  452. module_init(key_drv_init);
  453. module_exit(key_drv_exit);
  454. MODULE_LICENSE("GPL");

kobox: key_proc.c -v1 怎样使用proc文件系统调试驱动的更多相关文章

  1. linux 使用/proc文件系统 实现用户空间与内核模块之间通信

    项目中可能会用到用户态和内核模块之间进行通信的功能.想到linux系统本身很多通信都是通过/proc文件系统来的,比如修改网络中连接跟踪表连接数限制/proc/sys/net/netfilter/nf ...

  2. proc文件系统

    在shell终端里不带任何参数,直接运行mount命令可以显示正在挂载的文件系统.其中有这么一行 none on /proc type proc (rw) 这就是/proc文件系统.第一个域显示non ...

  3. proc文件系统在内核中的表现

    当Linux内核启动起来之后,我们可以通过proc虚拟文件系统来查看内的中的一些动态信息. 例如:可以 cat  /proc/misc  来查看系统中装载的所有misc类设备 cat  /proc/d ...

  4. 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解

    http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...

  5. <解说linux下proc文件系统>

    proc文件系统的作用是访问系统内核信息 proc不是一个真实的文件系统,它不占系统的外存空间,只是以文件的形式为用户访问linux内核数据提供接口,因为系统内核总是动态的变化,所以我们所捕捉到的也只 ...

  6. (转)使用 /proc 文件系统来访问 Linux 内核的内容

    转载网址:http://www.ibm.com/developerworks/cn/linux/l-proc.html 这个虚拟文件系统在内核空间和用户空间之间打开了一个通信窗口/proc 文件系统是 ...

  7. linux中proc文件系统 -- ldd3读书笔记

    1./proc 文件系统概述 /proc 文件系统是由软件创建,被内核用来向外界报告信息的一个文件系统./proc 下面的每一个文件都和一个内核函数相关联,当文件的被读取时,与之对应的内核函数用于产生 ...

  8. 在/proc文件系统中增加一个目录hello,并在这个目录中增加一个文件world,文件的内容为hello world

    一.题目 编写一个内核模块,在/proc文件系统中增加一个目录hello,并在这个目录中增加一个文件world,文件的内容为hello world.内核版本要求2.6.18 二.实验环境 物理主机:w ...

  9. linux kernel (proc文件系统)参数

    http://blog.csdn.net/guowake/article/details/3279796 Linux Proc文件系统,通过对Proc文件系统进行调整,达到性能优化的目的. 二./pr ...

随机推荐

  1. 何謂COB (Chip On Board) ?介紹COB的演進歷史

    COB (Chip On Board)在電子製造業已經是一項成熟的技術了,可是一般的組裝工廠對它的製程並不熟悉,也許是因為它使用到一些 wire bond 的積體電路(IC)封裝技術,所以很多的成品或 ...

  2. JTextPane 的 undo 、 redo

    实现文本框输入内容的单条记录撤销,重做,通过按钮实现 以及通过JList的多条撤销.重做操作(类似PS) 昨天还在为自己写不出代码怎么办而伤心,没想到今天上午就实现了,并且还完善了功能: 可以在撤销一 ...

  3. "NO 3D support is available from the host"

    https://forums.opensuse.org/showthread.php/494522-No-3d-Support-or-graphics-accelleration http://ask ...

  4. Java基础笔记-String类2

    StringBuffer 特点: 是字符串缓冲区. 是一个容器,其长度可变,可以操作添加多个数据类型. 最后通过toString方法变成字符串. 被final锁修饰,因此不能被继承. 存储: 方法1: ...

  5. Arcgis for Silverlight学习(一)

    1.地图的加载 arcgis server for silverlight 通过控件map实现地图的浏览功能.map控件的使用方法如下: <esri:Map x:Name="MyMap ...

  6. oracle权限的分配

    一.创建 sys:   //系统管理员,拥有最高权限 system://本地管理员,次高权限 scott: //普通用户,密码默认为tiger,默认未解锁 二.登陆 sqlplus / as sysd ...

  7. c#部分常用方法

    此文章不断补充 1.判断该字符串是否存在于字符串数组中 string[] arr = {"aaa","bbb","aba","cc ...

  8. HTML7常用的类型刮刮乐 光棒效果

    常用的类型: 1.数学: Math.ceil():天花板数 Math.floor():地板数 Math.round():四舍五入取整数 Math.random():生成0-1之间的随机数   2.日期 ...

  9. Mongodb常见错误

    1. log目录没有创建,而在logpath中有设定 2. SECONDARY默认不可以读取数据,需要db.getMongo().setSlaveOk(); 3. SECONDARY不可以写数据 4. ...

  10. zoj1108 FatMouse's Speed

    给你每个物体两个参数,求最长的链要求第一个参数递增,第二个参数递减,要求输出任意最长路径. 首先第一反应根据第二个参数排个序,然后不就是最长上升子序列的问题吗? O(nlogn)的复杂度,当然这样可以 ...