首页 > 技术文章 > Linux

dlutccj 2018-12-06 22:03 原文

1、在 32 位系统上, Linux 内核将 4G 空间分为 1G 内核空间(3~4G)和 3G0~3G)用户空间,通过内存管理,每个进程都可以使用 3G 的用户空间

2、基于linux主机调试开发板时,目标板需要gdbserver。将生成的二进制文件作为网络路径挂载在目标板上进行在线调试;

基于windows主机调试开发板时,目标板需要ssh,tftp功能,需要将编译的二进制文件下载到开发板进行在线调试;

3、通过windows主机调试i.mx283开发板时无法通过SSH传输文件,经查开发板未开SSH,参照

https://blog.csdn.net/sements/article/details/84106094

进行编译后,执行sshd,返回“Segmentation fault”,怀疑板载内存不够,内存越界,待研究

4、使用64位Ubuntu时在安装完ARM交叉编译器并设置环境变量后

“运行arm-linux-gcc命令,提示No such file or directory”

原因是需要安装32位兼容包

sudo apt-get install lib32z1

5、电脑能ping通板子,板子ping不通电脑----关闭防火墙。

6、安装vmware tools:https://blog.csdn.net/qq_52310755/article/details/111216213

7、aarch64-none.... 报错,找不到库,aarch64-none-elf-gcc test.c --specs=rdimon.specs

8、hello 模块,dmesg指令查看内核信息

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 MODULE_LICENSE("Dual BSD/GPL");
 4 static int hello_init(void)
 5 {
 6 printk(KERN_ALERT " Hello World enter\n");
 7 return 0;
 8 }
 9 static void hello_exit(void)
10  {
11  printk(KERN_ALERT " Hello World exit\n ");
12  }
13  module_init(hello_init);
14  module_exit(hello_exit);
15 
16  MODULE_AUTHOR("Song Baohua");
17  MODULE_DESCRIPTION("A simple Hello World Module");
18  MODULE_ALIAS("a simplest module");

 globalmem虚拟字符设备驱动模块--from华清远见

--内核5.4编译加载成功,5.13,5.14编译成功加载报错

  1 #include <linux/module.h>
  2 #include <linux/types.h>
  3 #include <linux/fs.h>
  4 #include <linux/errno.h>
  5 #include <linux/mm.h>
  6 #include <linux/sched.h>
  7 #include <linux/init.h>
  8 #include <linux/cdev.h>
  9 #include <linux/slab.h>
 10 #include <asm/io.h>
 11 //#include <asm/system.h>
 12 #include <asm/switch_to.h>
 13 #include <asm/uaccess.h>
 14 
 15 #define GLOBALMEM_SIZE 0x100/*全局内存最大4KB*/
 16 #define MEM_CLEAR 0x1 /*清零全局内存*/
 17 #define GLOBALMEM_MAJOR 256 /*预设的设备主设备号*/
 18 
 19 static int globalmem_major = GLOBALMEM_MAJOR;
 20 /*globalmem设备结构体*/
 21 struct globalmem_dev
 22 {
 23   struct cdev cdev;/*cdev结构体*/
 24   unsigned char mem[GLOBALMEM_SIZE];/*全局内存*/
 25 };
 26 
 27 struct globalmem_dev *globalmem_devp;/*设备结构体指针*/
 28 /*文件打开函数*/
 29 int globalmem_open(struct inode *inode, struct file *filp)
 30 {
 31   /*将设备结构体指针赋值给文件私有数据指针*/
 32   filp->private_data = globalmem_devp;  
 33   return 0;
 34 }
 35 /*文件释放函数*/
 36 int globalmem_release(struct inode *inode, struct file *filp)
 37 {
 38   return 0;  
 39 }
 40 
 41 /*iocrl 设备控制函数*/
 42 static long globalmem_ioctl( struct file *filp, unsigned int cmd, unsigned long arg)
 43 {
 44     struct globalmem_dev *dev = filp->private_data;/*获取设备结构体指针*/
 45     
 46     switch (cmd)
 47     {
 48       case MEM_CLEAR:
 49         memset(dev->mem,0,GLOBALMEM_SIZE);  
 50         printk(KERN_INFO "globalmem is set to zero\n");
 51         break;
 52       default:
 53         return -EINVAL;
 54     }
 55     return 0;
 56 }
 57 /*读函数*/
 58 static ssize_t globalmem_read(struct file *filp,char __user *buf,size_t size,loff_t *ppos)
 59 {
 60   unsigned long p = *ppos;
 61   unsigned int count = size;
 62   int ret = 0;
 63   struct globalmem_dev *dev = filp->private_data;/*获得设备结构体指针*/
 64   /*分析和获取有效的写长度*/
 65   if(p >= GLOBALMEM_SIZE)
 66     return count ? -ENXIO : 0;
 67   if(count > GLOBALMEM_SIZE - p)  
 68     count = GLOBALMEM_SIZE - p;
 69   /*内核空间->用户空间*/
 70   if(copy_to_user(buf, (void*)(dev->mem + p), count))
 71   {
 72     ret = -EFAULT;
 73   }
 74   else 
 75   {
 76     *ppos += count;
 77     ret = count;
 78     
 79     printk(KERN_INFO"read %d bytes(s) froom %d \n",count,p);
 80   }
 81   return ret;
 82 }
 83 /*写函数*/
 84 static ssize_t globalmem_write(struct file *filp, const char __user *buf,size_t size, loff_t *ppos)
 85 {
 86   unsigned long p = *ppos;
 87   unsigned int count = size;
 88   int ret = 0;
 89   struct globalmem_dev *dev=filp->private_data;/*获得设备结构体指针*/
 90   /*分析和获取有效的写长度*/
 91   if(p >= GLOBALMEM_SIZE)
 92     return count ? -ENXIO : 0;
 93   if(count > GLOBALMEM_SIZE - p)  
 94     count = GLOBALMEM_SIZE - p;
 95   /*用户空间->内核空间*/
 96   if(copy_from_user(dev->mem + p, buf, count))
 97     ret = -EFAULT;    
 98   else 
 99   {
100     *ppos+= count;
101     ret = count;
102     
103     printk(KERN_INFO"written $d bytes(s) from %d\n", count, p);
104   }
105   return ret;
106 }
107 /*seek 文件定位函数*/
108 static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig)
109 {
110   loff_t ret = 0;
111   switch (orig)
112   {
113     case 0:/*相对文件开始位置偏移*/
114        if(offset < 0)
115        {
116         ret = -EINVAL;
117         break;
118        }
119        if((unsigned int) offset > GLOBALMEM_SIZE)
120        {
121         ret = -EINVAL;
122         break; 
123        }
124        filp->f_pos = (unsigned int)offset;
125        ret = filp->f_pos;
126        break;
127     case 1:/*相对文件当前位置偏移*/
128       if ((filp->f_pos + offset) > GLOBALMEM_SIZE)
129       {
130         ret = - EINVAL;
131         break;
132       }
133       if ((filp->f_pos + offset) < 0)
134       {
135         ret = - EINVAL;
136         break;
137       }
138       filp->f_pos += offset;
139       ret = filp->f_pos;
140       break;
141     default:
142       ret = -EINVAL;
143       break;      
144   }  
145   return ret;
146 }
147 /*文件操作结构体*/
148 static const struct file_operations globalmem_fops =
149 {
150   .owner = THIS_MODULE,
151   .llseek = globalmem_llseek,
152   .read = globalmem_read,
153   .write = globalmem_write,
154   .unlocked_ioctl = globalmem_ioctl,
155   .open = globalmem_open,
156   .release = globalmem_release,
157 };
158 /*初始化并注册 cdev*/
159 static void globalmem_setup_cdev(struct globalmem_dev *dev, int index)
160 {
161   int err, devno = MKDEV(globalmem_major, index);
162 
163   cdev_init(&dev->cdev, &globalmem_fops);
164   dev->cdev.owner = THIS_MODULE;
165   dev->cdev.ops = &globalmem_fops;
166   err = cdev_add(&dev->cdev, devno, 1);
167   if (err)
168     printk(KERN_NOTICE "Error %d adding LED%d", err, index);
169 }
170 
171 /*设备驱动模块加载函数*/
172 int globalmem_init(void)
173 {
174   int result;
175   dev_t devno = MKDEV(globalmem_major, 0);
176 
177   /* 申请设备号*/
178   if (globalmem_major)
179     result = register_chrdev_region(devno, 1, "globalmem");
180   else /* 动态申请设备号 */
181   {
182     result = alloc_chrdev_region(&devno, 0, 1, "globalmem");
183     globalmem_major = MAJOR(devno);
184   }
185   if (result < 0)
186    return result;
187 
188   /* 动态申请设备结构体的内存*/
189   globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL);
190   if (!globalmem_devp) /*申请失败*/
191   {
192     result = - ENOMEM;
193     goto fail_malloc;
194   }
195   memset(globalmem_devp, 0, sizeof(struct globalmem_dev));
196 
197   globalmem_setup_cdev(globalmem_devp, 0);
198   return 0;
199 
200   fail_malloc: unregister_chrdev_region(devno, 1);
201   return result;
202 }
203 
204 /*模块卸载函数*/
205 void globalmem_exit(void)
206 {
207   cdev_del(&globalmem_devp->cdev); /*注销 cdev*/
208   kfree(globalmem_devp); /*释放设备结构体内存*/
209   unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); /*释放设备号*/
210 }
211 
212 MODULE_AUTHOR("Cao chaojie");
213 MODULE_LICENSE("Dual BSD/GPL");
214 
215 module_param(globalmem_major, int, S_IRUGO);
216 
217 module_init(globalmem_init);
218 module_exit(globalmem_exit);

makefile

obj-m :=hello.o
DIR := /lib/modules/$(shell uname -r)/build
all:
        make -C $(DIR) M=$(shell pwd) modules
clean:
        make -C $(DIR) M=$(shell pwd) clean

9、通过“mknod /dev/globalmem c 254 0”命令创建“/dev/globalmem”设备节点,并通过“echo 'hello world' > /dev/globalmem”命令和“cat /dev/globalmem”命令分别验证设备的写和读.

 

推荐阅读