20150501调试分析之 自制工具<寄存器编辑器>

20150501调试分析之 自制工具<寄存器编辑器>

2015-05-1 Lover雪儿


今天还是继续我们内核错误调试,今天是制作一个寄存器编辑器,可以自由的读写某些我们需要调试的寄存器.

.首先完成一个可自动创建设备节点的字符设备驱动程序

这儿我们前面都写过了N,此处不再赘述,直接附上代码:

 1 /******************************
 2 内核调试之自制寄存器读写工具(驱动)
 3  *****************************/
 4 #include <linux/module.h>
 5 #include <linux/init.h>
 6 #include <linux/kernel.h>
 7 #include <linux/delay.h>
 8 #include <linux/types.h>
 9 #include <linux/ioctl.h>
10 #include <linux/gpio.h>
11 #include <linux/fs.h>
12 #include <linux/device.h>
13 #include <linux/uaccess.h>
14 #include <linux/irq.h>
15 #include <linux/wait.h>
16 #include <linux/sched.h>
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 
20 
21 static int major;
22 
23 //auto to create device node
24 static struct class *class;
25 static struct class_device *kernel_class_dev;
26 
27 
28 static int kernel1_rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
29 {
30 
31     return 0;
32 }
33 
34 //定义字符设备结构体
35 static struct file_operations kernel_rw_ops = {
36     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
37     .ioctl  =   kernel1_rw_ioctl,
38 };
39 
40 static int kernel_rw_init(void)
41 {
42     printk("<0>kernel_rw_init\n");
43     major = register_chrdev(0, "kernel_rw", &kernel_rw_ops);
44     class = class_create(THIS_MODULE,"kernel_rw");
45     kernel_class_dev = device_create(class,NULL,MKDEV(major,0),NULL,"kernel_rw");    /*/dev/kernel_rw*/
46     
47     
48     return 0;
49 }
50 
51 static void kernel_rw_exit(void)
52 {
53     printk("<0>kernel_rw_exit\n");
54     device_unregister((void *)kernel_class_dev);
55     class_destroy((struct class *)class);
56     unregister_chrdev(major,"kernel_rw");
57 }
58 
59 module_init(kernel_rw_init);
60 module_exit(kernel_rw_exit);
61 MODULE_LICENSE("GPL");
62 MODULE_AUTHOR("Lover雪儿");
kernel_rw_1.c

 


.ioctl中增加寄存器的读写功能

定义ioctlcommand命令.

1 #define KERNEL_RW_R8     0
2 #define KERNEL_RW_R16     1
3 #define KERNEL_RW_R32     6
4 
5 #define KERNEL_RW_W8     3
6 #define KERNEL_RW_W16     4
7 #define KERNEL_RW_W32     5

 

实现ioctl函数.

 1 static int kernel1_rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 2 {
 3     volatile unsigned char  *p8;
 4     volatile unsigned short *p16;
 5     volatile unsigned int   *p32;
 6     unsigned long val;
 7     unsigned long addr;
 8 
 9     unsigned int buf[2];
10 
11     
12     copy_from_user(buf, (const void __user *)arg, 8);
13     addr = buf[0];
14     val  = buf[1];
15     printk("<0>\naddr %x : %d \n",addr, val);
16     p8  = (volatile unsigned char *)ioremap(addr, 4);
17     p16 = p8;
18     p32 = p8;
19 
20     switch (cmd)
21     {
22         case KERNEL_RW_R8:
23         {
24             val = *p8;
25             copy_to_user((void __user *)(arg+4), &val, 4);
26             printk("<0>enter r8\n");
27             break;
28         }
29 
30         case KERNEL_RW_R16:
31         {
32             val = *p16;
33             copy_to_user((void __user *)(arg+4), &val, 4);
34             printk("<0>enter r16\n");
35             break;
36         }
37 
38         case KERNEL_RW_R32:
39         {
40             val = *p32;
41             copy_to_user((void __user *)(arg+4), &val, 4);
42             printk("<0>enter r32\n");
43             break;
44         }
45 
46         case KERNEL_RW_W8:
47         {
48             *p8 = val;
49             printk("<0>enter w8, val = %x\n",val);
50             break;
51         }
52 
53         case KERNEL_RW_W16:
54         {
55             *p16 = val;
56             printk("<0>enter w16, val = %x\n",val);
57             break;
58         }
59 
60         case KERNEL_RW_W32:
61         {
62             *p32 = val;
63             printk("<0>enter w32, val = %x\n",val);
64             break;
65         }
66         default:
67             printk("<0>enter default\n");
68             break;
69     }    
70 
71     iounmap(p8);
72     return 0;
73 }

 


附上驱动程序kernel_rw.c

 

  1 /******************************
  2 内核调试之自制寄存器读写工具(驱动)
  3  *****************************/
  4 #include <linux/module.h>
  5 #include <linux/init.h>
  6 #include <linux/kernel.h>
  7 #include <linux/delay.h>
  8 #include <linux/types.h>
  9 #include <linux/ioctl.h>
 10 #include <linux/gpio.h>
 11 #include <linux/fs.h>
 12 #include <linux/device.h>
 13 #include <linux/uaccess.h>
 14 #include <linux/irq.h>
 15 #include <linux/wait.h>
 16 #include <linux/sched.h>
 17 #include <linux/interrupt.h>
 18 #include <linux/io.h>
 19 
 20 #define KERNEL_RW_R8     0
 21 #define KERNEL_RW_R16     1
 22 #define KERNEL_RW_R32     6
 23 
 24 #define KERNEL_RW_W8     3
 25 #define KERNEL_RW_W16     4
 26 #define KERNEL_RW_W32     5
 27 
 28 static int major;
 29 
 30 //auto to create device node
 31 static struct class *class;
 32 static struct class_device *kernel_class_dev;
 33 
 34 
 35 static int kernel1_rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 36 {
 37     volatile unsigned char  *p8;
 38     volatile unsigned short *p16;
 39     volatile unsigned int   *p32;
 40     unsigned long val;
 41     unsigned long addr;
 42 
 43     unsigned int buf[2];
 44 
 45     
 46     copy_from_user(buf, (const void __user *)arg, 8);
 47     addr = buf[0];
 48     val  = buf[1];
 49     printk("<0>\naddr %x : %d \n",addr, val);
 50     p8  = (volatile unsigned char *)ioremap(addr, 4);
 51     p16 = p8;
 52     p32 = p8;
 53 
 54     switch (cmd)
 55     {
 56         case KERNEL_RW_R8:
 57         {
 58             val = *p8;
 59             copy_to_user((void __user *)(arg+4), &val, 4);
 60             printk("<0>enter r8\n");
 61             break;
 62         }
 63 
 64         case KERNEL_RW_R16:
 65         {
 66             val = *p16;
 67             copy_to_user((void __user *)(arg+4), &val, 4);
 68             printk("<0>enter r16\n");
 69             break;
 70         }
 71 
 72         case KERNEL_RW_R32:
 73         {
 74             val = *p32;
 75             copy_to_user((void __user *)(arg+4), &val, 4);
 76             printk("<0>enter r32\n");
 77             break;
 78         }
 79 
 80         case KERNEL_RW_W8:
 81         {
 82             *p8 = val;
 83             printk("<0>enter w8, val = %x\n",val);
 84             break;
 85         }
 86 
 87         case KERNEL_RW_W16:
 88         {
 89             *p16 = val;
 90             printk("<0>enter w16, val = %x\n",val);
 91             break;
 92         }
 93 
 94         case KERNEL_RW_W32:
 95         {
 96             *p32 = val;
 97             printk("<0>enter w32, val = %x\n",val);
 98             break;
 99         }
100         default:
101             printk("<0>enter default\n");
102             break;
103     }    
104 
105     iounmap(p8);
106     return 0;
107 }
108 
109 //定义字符设备结构体
110 static struct file_operations kernel_rw_ops = {
111     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
112     .ioctl  =   kernel1_rw_ioctl,
113 };
114 
115 static int kernel_rw_init(void)
116 {
117     printk("<0>kernel_rw_init\n");
118     major = register_chrdev(0, "kernel_rw", &kernel_rw_ops);
119     class = class_create(THIS_MODULE,"kernel_rw");
120     kernel_class_dev = device_create(class,NULL,MKDEV(major,0),NULL,"kernel_rw");    /*/dev/kernel_rw*/
121     
122     
123     return 0;
124 }
125 
126 static void kernel_rw_exit(void)
127 {
128     printk("<0>kernel_rw_exit\n");
129     device_unregister((void *)kernel_class_dev);
130     class_destroy((struct class *)class);
131     unregister_chrdev(major,"kernel_rw");
132 }
133 
134 module_init(kernel_rw_init);
135 module_exit(kernel_rw_exit);
136 MODULE_LICENSE("GPL");
137 MODULE_AUTHOR("Lover雪儿");
kernel_rw.c

 

 

 

 

.编写测试函数

  1 /******************************
  2 内核调试之自制寄存器读写工具(应用)
  3  *****************************/
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <unistd.h>
  7 #include <sys/types.h>
  8 #include <sys/stat.h>
  9 #include <fcntl.h>
 10 #include <termios.h>
 11 #include <errno.h>
 12 #include <limits.h>
 13 #include <asm/ioctls.h>
 14 #include <time.h>
 15 #include <pthread.h>
 16 #include <poll.h>
 17 #include <string.h>
 18 
 19 #define KERNEL_RW_R8     (unsigned int)0
 20 #define KERNEL_RW_R16     (unsigned int)1
 21 #define KERNEL_RW_R32     (unsigned int)6
 22 
 23 #define KERNEL_RW_W8     (unsigned int)3
 24 #define KERNEL_RW_W16     (unsigned int)4
 25 #define KERNEL_RW_W32     (unsigned int)5
 26 
 27 /* 
 28 Usage: ./reg_editor bit位数  读的地址  数据的个数
 29 读取内核寄存器:
 30     ./reg_editor r8  addr [num]
 31     ./reg_editor r16 addr [num]
 32     ./reg_editor r32 addr [num]
 33     
 34 Usage: ./reg_editor bit位数  写的地址  数据    
 35 写入内核寄存器:
 36     ./reg_editor w8  addr val
 37     ./reg_editor w16 addr val
 38     ./reg_editor w32 addr val
 39 */
 40 
 41 void print_usage(char *file)
 42 {
 43     printf("Usage: \n");
 44     printf("%s <r8|r16|r32> <phy addr> [num]\n",file);
 45     printf("%s <w8|w16|w32> <phy addr> <val>\n",file);
 46 }
 47 
 48 int main(int argc, char **argv)
 49 {
 50     int fd;
 51     unsigned int buf[2];
 52     unsigned int i;
 53     unsigned int num;
 54     
 55     buf[0] = 0;
 56     buf[1] = 1;
 57     
 58     if((argc != 3) && (argc != 4)){
 59         print_usage(argv[0]);
 60         return -1;
 61     }
 62     
 63     fd = open("/dev/kernel_rw", O_RDWR);
 64     if(fd < 0){
 65         printf("can't open /dev/kernel_rw ");
 66         return -1;
 67     }
 68     buf[0] = strtoul(argv[2], NULL, 0);
 69 
 70     if (argc == 4)
 71     {
 72         buf[1] = strtoul(argv[3], NULL, 0);
 73         num    = buf[1];
 74     }
 75     else
 76     {
 77         num = 1;
 78     }
 79 
 80     if(strcmp(argv[1], "r8") == 0){
 81         for(i = 0; i< num; i++){
 82             ioctl(fd, KERNEL_RW_R8, buf);  //结果放在buf[1]里
 83             printf("%02d. [%08x] = %02x\n",i,buf[0],(unsigned char )buf[1]);
 84             buf[0] += 1;  //地址加1
 85         }
 86     }else if(strcmp(argv[1], "r16") == 0){
 87         for(i = 0; i< num; i++){
 88             ioctl(fd, KERNEL_RW_R16, buf);  //结果放在buf[1]里
 89             printf("%02d. [%08x] = %02x\n",i,buf[0],(unsigned short )buf[1]);
 90             buf[0] += 2;  //地址加2
 91         }
 92     }else if(strcmp(argv[1], "r32") == 0){
 93         for(i = 0; i< num; i++){
 94             ioctl(fd, KERNEL_RW_R32, buf);  //结果放在buf[1]里
 95             
 96             printf("%02d. [%08x] = %02x\n",i,buf[0],(unsigned short )buf[1]);
 97             buf[0] += 2;  //地址加2
 98         }
 99     }else if(strcmp(argv[1], "w8") == 0){
100         ioctl(fd, KERNEL_RW_W8, buf);   //addr = buf[0]   val = buf[1]
101     }else if(strcmp(argv[1], "w16") == 0){
102         ioctl(fd, KERNEL_RW_W16, buf);   //addr = buf[0]   val = buf[1]
103     }else if(strcmp(argv[1], "w32") == 0){
104         ioctl(fd, KERNEL_RW_W32, buf);   //addr = buf[0]   val = buf[1]
105     }else{
106         print_usage(argv[0]);
107         return -1;
108     }
109         
110     return 0;
111 }
112 
113 /*
114 0x53FCC000 0x53FC_FFFF 16 Kbytes GPIO-1
115 
116 */
reg_editor.c

 


.err_led驱动程序

  1 #include<linux/cdev.h>
  2 #include<linux/module.h>
  3 #include<linux/types.h>
  4 #include<linux/fs.h>
  5 #include<linux/errno.h>
  6 #include<linux/mm.h>
  7 #include<linux/sched.h>
  8 #include<linux/init.h>
  9 #include<asm/io.h>
 10 #include<asm/system.h>
 11 #include<asm/uaccess.h>
 12 #include<linux/device.h>
 13 #include <linux/delay.h>
 14 
 15 #define Driver_NAME "err_led_dev"
 16 #define DEVICE_NAME "err_led_dev"
 17 
 18 static int major = 0;
 19 
 20 #define LED_ON     0
 21 #define LED_OFF 1
 22 
 23 
 24 //auto to create device node
 25 static struct class *drv_class = NULL;
 26 static struct class_device *drv_class_dev = NULL;
 27 
 28 //寄存器基址;
 29 static unsigned long mem_iomux;
 30 static unsigned long mem_gpio3;
 31 static unsigned long base_iomux;      //iomux基址 0X 43FA C000 -  0X 43FA FFFF
 32 static unsigned long base_gpio3;    //gpio3      0X 53FA 4000 -  0X 53FA 7FFF
 33 // MUX_CTL模式选择  配置寄存器
 34 #define MUX_CTL  (*(volatile unsigned long *)(base_iomux + 0x0060))
 35 // PAD_CTL GPIO常用功能设置
 36 #define PAD_CTL  (*(volatile unsigned long *)(base_iomux + 0x0270))
 37 // GPIO DR   数据寄存器  DR
 38 #define DR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0000))
 39 // GPIO GDIR 方向控制寄存器  GDIR
 40 #define GDIR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0004))
 41 
 42 
 43 static int key_open(struct inode *inode, struct file *file)
 44 {
 45     printk("<0>function open!\n\n");
 46     return 0;
 47 }
 48 
 49 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
 50 {
 51     return 0;
 52 }
 53 
 54 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
 55 {
 56     printk("<0>function write!\n\n");
 57     return 1;
 58 }
 59 
 60 static int  key_release(struct inode *inode, struct file *filp)
 61 {
 62     printk("<0>function write!\n\n");
 63     return 0;
 64 }
 65 
 66 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
 67 {
 68     printk("<0>function ioctl!\n\n");
 69     
 70     switch(command)
 71     {
 72         case LED_ON:
 73             DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零  亮
 74             break;
 75         case LED_OFF:
 76             
 77             DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1  灭
 78             break;
 79         default:
 80             break;
 81     }
 82     
 83     return 0;
 84 }
 85 static struct file_operations key_fops = {
 86     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
 87     .open   =   key_open,
 88     .read   =   key_read,
 89     .write  =   key_write,
 90     .release=   key_release,
 91     .ioctl  =   key_ioctl,
 92 };
 93 
 94 void gpio_addr(void){
 95     printk("<0>addr base_iomux : %x \n",base_iomux);
 96     printk("<0>addr base_gpio3 : %x \n",base_gpio3);
 97     printk("<0>addr MUX_CTL : %x \n",&MUX_CTL);
 98     printk("<0>addr PAD_CTL : %x \n",&PAD_CTL);
 99     printk("<0>addr GDIR_GPIO3 : %x \n",&GDIR_GPIO3);
100     printk("<0>addr DR_GPIO3 : %x \n",&DR_GPIO3);
101 }
102 
103 
104 
105 void led_on_off(void){
106     ssleep(1);
107     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
108     ssleep(1);
109     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
110     ssleep(1);
111     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
112     ssleep(1);
113     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
114     ssleep(1);
115     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
116     ssleep(1);
117     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
118     ssleep(1);
119     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
120     ssleep(1);
121     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
122     ssleep(1);
123     DR_GPIO3 |= (0x01 << 23);        //将GPIO2_23置1
124 }
125 
126 static int __init  key_irq_init(void)
127 {
128     printk("<0>\nHello,this is %s module!\n\n",Driver_NAME);
129     //register and mknod
130     major = register_chrdev(0,Driver_NAME,&key_fops);
131     drv_class = class_create(THIS_MODULE,Driver_NAME);
132     drv_class_dev = device_create(drv_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME);  /*/dev/key_query*/
133     
134     //IO端口申请 ioremap  可以直接通过指针来访问这些地址
135     base_iomux = ioremap(0x43FAC000,0xFFF);
136     base_gpio3 = ioremap(0x53FA4000,0xFFF);
137 
138     //MUX_CTL
139     MUX_CTL &= ~(0x07 << 0);    
140     MUX_CTL |= (0X05 << 0);    //设置为ALT5  GPIO3_23 ERR_LED
141     //PAD_CTL
142     PAD_CTL &= ~(0x01<<13 | 0x01<<3 | 0x03<<1 | 0x01<<0);   //1.8v 不需要上拉下拉  CMOS输出 slew rate
143     //GDIR_GPIO3    配置为输出模式
144     GDIR_GPIO3 &= ~(0x01 << 23);    
145     GDIR_GPIO3 |= (0x01 << 23);    //配置为输出模式    
146 
147     //DR_GPIO3        配置为输出0 点亮ERR_LED
148     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
149     DR_GPIO3 &= ~(0x01 << 23);        //将GPIO2_23清零
150     gpio_addr();
151     led_on_off();
152     return 0; 
153 }
154                      
155 static void __exit key_irq_exit(void)
156 {
157     gpio_addr();
158     printk("<0>\nGoodbye,%s!\n\n",Driver_NAME);
159     led_on_off();
160 
161        unregister_chrdev(major,Driver_NAME);
162     device_unregister(drv_class_dev);
163     class_destroy(drv_class);
164     
165     //释放IO端口
166     iounmap(base_iomux);
167     iounmap(base_gpio3);
168 }
169 
170 
171 /* 这两行指定驱动程序的初始化函数和卸载函数 */
172 module_init(key_irq_init);
173 module_exit(key_irq_exit);
174 
175 /* 描述驱动程序的一些信息,不是必须的 */
176 MODULE_AUTHOR("Lover雪儿");
177 MODULE_VERSION("0.1.0");
178 MODULE_DESCRIPTION("IMX257 key Driver");
179 MODULE_LICENSE("GPL");
err_led.c

 


.err_led测试程序.

 1 /******************************
 2 内核调试之自制寄存器读写工具(应用)
 3  *****************************/
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include <unistd.h>
 7 #include <sys/types.h>
 8 #include <sys/stat.h>
 9 #include <fcntl.h>
10 #include <termios.h>
11 #include <errno.h>
12 #include <limits.h>
13 #include <asm/ioctls.h>
14 #include <time.h>
15 #include <pthread.h>
16 #include <poll.h>
17 
18 #define LED_ON     0
19 #define LED_OFF 1
20 
21 /* 
22 Usage: 
23     ./err_led_test <on | off>
24 */
25 
26 void print_usage(char *file)
27 {
28     printf("Usage: \n");
29     printf("%s <on | off>\n",file);
30 }
31 
32 int main(int argc, char **argv)
33 {
34     int fd ;
35     
36     if(argc != 2){
37         print_usage(argv[0]);
38         return -1;
39     }
40     
41     fd = open("/dev/err_led_dev", O_RDWR);
42     if(fd < 0){
43         printf("can't open /dev/err_led_dev \n");
44         return -1;
45     }
46     
47     if(strcmp(argv[1], "on") == 0){
48         ioctl(fd, LED_ON); 
49     }else if(strcmp(argv[1], "off") == 0){
50         ioctl(fd, LED_OFF);
51     }else{
52         print_usage(argv[0]);
53         return -1;
54     }
55         
56     return 0;
57 }
err_led_test.c

 


.编译测试

步骤:

加载err_led.ko

加载kernel_rw.ko

使用reg_editor应用程序读取 0x53fa4002 led灯引脚的数据

使用err_led的应用程序熄灭led

再次使用reg_editor应用程序读取 0x53fa4002 led灯引脚的数据

使用reg_editor应用程序往0x53fa4000地址写入1000000,观察LED是否熄灭

使用reg_editor应用程序往0x53fa4000地址写入0000000,观察LED是否点亮

 1 //加载 kernel_rw.ko
 2 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# insmod kernel_rw.ko 
 3 kernel_rw_init
 4 //读取地址 0x53fa4002的数据,由于此时灯是亮的,所以数据为0x05
 5 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# ./app/reg_editor r32 0x53fa4002 
 6 enter r32
 7 00. [53fa4002] = 05
 8 //熄灭led灯,也就是给led的引脚高电平
 9 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# ./err_gpio/app/err_led_test off
10 function open!
11 //再次 读取地址 0x53fa4002的数据,发现数据变为85了
12 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# ./app/reg_editor r32 0x53fa4002 
13 enter r32
14 00. [53fa4002] = 85
15 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw#
16 
17 *********************************************************************
18 写地址:灭灯
19 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# ./app/reg_editor w32 0x5
20 3fa4000 10000000
21 er w32, val = 989680  灯被熄灭
22 
23 写地址:亮灯
24 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# ./app/reg_editor w32 0x5
25 3fa4000 00000000
26  val = 0   写完后,发现IMX257板子的LED被点亮
27 
28 root@EasyARM-iMX257 /mnt/nfs/module/38_debug_kernel_rw# 

 

如图所示:




你可能感兴趣的:(编辑器)