- 博客(45)
- 资源 (1)
- 收藏
- 关注
原创 Makefile实例
现在来编写下面目录结构的Makefile: 顶层目录的Makefile://顶层目录的Makefile应该是把握整个工程的编译路线的。内容如下:CFLAGS=-DDEBUG -Iinclude -I../includeexport CFLAGSall: make -C client make -C server make -C rawlist make
2016-12-31 10:50:49 305
原创 Makefile的编写
如下的目录结构,编写Makefile: (http://img.blog.csdn.net/20161230224042409?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYm95a2Ff/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)分析:这是一个
2016-12-30 23:03:14 258
原创 shell脚本创建和kill进程
1、创建进程:#!/bin/bashwhile [ 1 ] do ./client 192.168.2.25 2016 done2.杀死进程:#!/bin/bashwhile [ 1 ] do PROCESS= `ps -ef |grep client|grep -V grep| prep -V PPID |awk `{ print $2 }` f
2016-12-30 22:09:00 3427 1
原创 环境变量修改
1、在/etc/bash.bashrc中添加环境变量: export PATH=$PATH:/tools/arm-linux-none/bin/ 2、然后再使生效: source /etc/bash.bashrc
2016-12-28 18:15:01 288
原创 零长度数组
在GNU C中允许有数组长度为零的情况。如: struct var_data{ int len; char data[0]; }; char data[0]表示程序中通过var_data结构体中的data[index]成员来访问len之后的地index个地址,它可以用来携带一些长度不定的内容。假如struct var_data 的数据就保存在struct
2016-12-27 22:52:47 291
原创 Linux内核模块
1、内核模块注册注销: 块加载函数有返回值,模块卸载函数无返回值。两者都是无参函数,加载函数用_ init修饰,卸载函数用 _exit修饰。#define __init __attribute__((__section__(".init.text")))#define __exit __atrribute__((__section__(".exit,text")))static int
2016-12-27 22:40:15 189
原创 内核调试
oops:由oops得到pc的地址,然后通过arm-none-linux-gnueabi-addr2line 0x3453454j -e vmlinux -f来查看,但是当函数的嵌套调用比较多时,光是一个pc地址是无法用来定位的,此时还要借助lr和堆栈的情况来最终定位出错的源。
2016-12-26 23:01:26 338
原创 Linux内核体系架构
1. Linux内核和用户层的应用程序都有自己的保护地址空间。每个用户空间的进程都有自己的虚拟地址空间,内核则有独立的地址空间。一般情况下应用程序时无法直接访问内核空间的,要通过一个特殊的系统调用接口来访问。但是又有一个问题,当频繁的使用系统调用时,会加大系统的开销等。这就好比去银行取钱,假如我们要取1000元,那么你是一次取1000元好呢,还是分十次每次取100元好。很明显,我们是一次性就搞定的。
2016-12-26 17:30:10 297
原创 Linux内核编译
首先在源码目录下:arch/arm/kernel/vmlinux.lds的链接文件生成vmlinux。在生成Image,又有arch/arm/boot/compressed文件夹中的压缩算法将该目录下由vmlinux.lds第二次链接的一些解压等代码和Image一起压缩成arch/arm/boot/compressed目录中的被压缩之后的vmlinux。然后生成zImage。最后zImage被mki
2016-12-25 22:47:34 181
原创 Linux内核复习
1、Linux内核基本支持现有的所有文件系统,比u-boot要支持的多了很多。 2、ps ajx查看进程时,用“[]”括起来的是属于内核线程的。 3、system V的所有函数都是系统调用。 4、Linux内核源码管理工具是git。
2016-12-24 22:57:41 249
原创 init.rc中的函数分析
parse_config_file(“pathname”):这个函数是用来分析一个指定的文件的,它调用read_file()函数来读取文件parse_config()函数来分析读到的内容。int parse_config_file(const char* fn){ char* data; data = read_file(fn , 0);//将指定的文件读到内存,返回该内存的首地
2016-12-23 23:03:26 283
原创 Android的init.rc
init.rc脚本文件在Android系统启动时,主要用来设置系统的环境变量,记录待执行的进程。action list(动作列表)和server list(服务列表):它们是init进程根据init.rc 的内容生成的。init.rc文件的内容主要有两部分:以“on”关键字开头的action list(动作列表),以“server”关键字开头的server list(服务列表)。acti
2016-12-23 22:31:40 205
原创 Android的init进程
1、当Linux内核加载后就会启动第一个应用程序–nit进程,它主要提供四大功能: a:子进程的终止处理; b:应用程序访问驱动时创建设备节点,提供属性服务并保存系统的环境变量; c:分析init.rc脚本,执行相应的功能。2、几种文件系统: a、tmpfs:是一种虚拟内存的文件系统典型的tmpfs文件系统完全驻留在RAM中读写速度远远大于闪存或磁盘文件系统。 b、
2016-12-22 23:02:20 285
原创 烧写Android系统
1、编译Linux系统 2、编译Android系统: source build/ensetup.sh lunch extra-bsp make 3、烧写准备: 拷贝boot.img和system.img(在Android/out/product/fspad-733)到工具目录。 拷贝boot-source.fex(在lichee/tools/pa
2016-12-22 20:51:39 3468 1
原创 驱动复习(mor8)
操作sk_buff的函数:struct sk_buff* alloc_skb(unsigned int len , int priority);struct sk_buff* dev_alloc_skb(unsigned int len);//为sk_buff分配一个缓冲区,并初始化skb->data和skb->tail到skb->head。dev_alloc_skb()使用GFP_ATOMIC
2016-12-21 22:51:48 173
原创 驱动复习(mor8)
1、字符设备驱动程序一般在模块初始化函数中申请中断,而网卡驱动是在open函数中申请驱动。因为字符设备是连续工作的,而网卡可能有时候需要禁用(ifconfig down)。当网卡禁用之后,它的中断也就需要关掉;下一次再打开网卡时才申请中断。
2016-12-21 14:14:19 221
原创 驱动复习(mor8)
1、串口发送和接受中断发生的时机。2、Linux网路子系统、Linux网络协议栈的层次结构。3、应用程序在内核中不叫API而叫系统调用!
2016-12-20 22:52:20 254
原创 驱动复习(mor8)
驱动mmap设备操作与应用程序的mmap系统调用区别?按键驱动代码?按键初始化:struct key_info{ int irq_no; unsigned int gpio_port; int key_no;} key_info_table[4]={ {GPIO_EXINT0 ,GPIO_F1 ,1},
2016-12-20 21:41:47 252
原创 驱动复习(mor8)
内核定时器的详细说明?系统移植中在开发板上设置应用程序自启动。应用程序通过设备文件和驱动建立联系,而设备文件又通过主设备号与驱动联系。在动态获取设备号时先加载驱动再创建设备节点。应用层mmap系统调用: mmap实现将文件内容映射到内存空间的某块地址上,通过对这块内存空间的操作来实现对文件的操作,而不需要再调用read和write等操作。一、void* mmap(void* addr,
2016-12-19 22:52:03 202
原创 驱动复习(mor8)
进程几种状态:就绪态(运行态)、占有态、等待态(可中断,不可中断)、停止态、僵尸态。驱动程序无法立刻满足用户层的请求时如何处理:驱动程序应该(缺省的)进行阻塞进程,使其进入睡眠直到请求可以满足为止。阻塞型驱动操作:在阻塞型操作的驱动中,应用层调用read方法时,如果驱动中的数据不足或是没有数据可读,进程阻塞;当数据达到要求时,进程被唤醒并将数据返回给用户层。当应用层调用write的时候,驱动程序
2016-12-19 18:53:01 191
原创 驱动复习(mor8)
1、读函数分析: read函数是从内核空间读出数据到用户空间,在读出数据之前我们要检查它传进来的参数的合法性。先从file结构体中提取私有数据(Men_dev*=file->private_data);再提取读的起始位置(loff_t pos=*fps);然后判断这两者的合法性:如果读的起始位置pos比内核空间的已经存在的数据还要大(即pos>dev->size),那么这是不合法的。同样如
2016-12-18 22:58:30 176
原创 驱动复习(mor8)
1、用户空间和内核空间的交互: unsigned long copy_to_user(void _ _user*to,const void* from ,unsigned long count);unsigned long copy_from_user(void to , const void _ _user from ,unsigned long count); 2、原来这样也可以: st
2016-12-18 12:15:57 240
原创 驱动复习2(mor8)
1、注册字符设备: int register_chrdev(usigned int major , const char* name ,file operations* ops) ; 2、注销字符设备: int unregister_chrdev(unsigned int major , const char * name ); 3、完成了驱动的安装之后应该写一个应用程
2016-12-17 22:53:39 193
原创 驱动复习(mor8)
1、u-boot烧写到flash中时要选择offset为0,因为要保证u-boot在flash的0位置。 2、块设备由于有缓存,故可以随机访问。在一般的Unix中,块设备一般是一次访问512(或者512的整数倍)的大小的。但是在Linux中块设备可以按字节来访问,所以块设备可字符设备只是接口不同。 3、网络驱动的接口通常是一个硬件设备(eth0),但是也可以是一个纯软件的(回环lo),一个网络接
2016-12-17 22:28:20 183
原创 拆箱解箱
Integer i=new Integer(10); Integer j=new Integer(10); //两个引用类型指向不同的空间 System.out.println(i==j);//f //装箱:简单类型转换成引用类型 Integer a =20; Integer b =20; //两个引用类型指向同一个空间 System.o
2016-12-14 21:19:56 170
原创 java 基础
1、只有一个public类,而且只有这个类是有名字的,其他的类(class)没有名字,也没有小括号。文件名要与public修饰的类的名字一致。 2、类中的方法与函数可以类比,有小括号,小括号里面可以传参。 3、用private修饰的成员不能被外部的类访问,只可以在本类中访问。用public修饰的类可以被其它类访问。 4、在继承中不能继承这个类中被private修饰的变量或方法。 5、this
2016-12-14 20:47:19 150
原创 中断步骤
/* * 注册中断 * 参数: unsigned int irq - 软中断号 irq_handler_t handler - 中断例程 unsigned long flags - 触发方式及工作方式 // 在设备树中的interrupt<>的最后一个数字表示触发方式0,1,2,4,8 触发:IRQF_TRIGGER_RISING
2016-12-08 22:54:39 268
原创 设备树
1、查找结点: a、通过节点名字查找: np = of_find_node_by_name(NULL, “ethernet”); b、通过节点属性查找: np = of_find_compatible_node(NULL, NULL, “davicom,dm9000”);
2016-12-08 22:43:17 522
原创 设备树中的结构体
1、设备结构体 struct device_node { const char* name; const char* type; const char* full_name; } 2、属性结构体 struct property
2016-12-07 22:25:29 296
原创 竞态与并发
竞态与并发的情况广泛存在,中断屏蔽、原子操作、自旋锁、信号量可以解决并发问题。中断屏蔽很少用,而原子操作只能针对整数使用,所以一般是自旋锁和信号量使用的比较多;自旋锁使用不当会导致死锁,在锁定期间不能有阻塞,因此锁定的临界区应该尽量小;信号量允许临界区阻塞,所以可以适用临界区大的情况。读写自旋锁,读写信号量可以是看作条件放宽了的自旋锁和信号量,它们允许多个执行单元进行资源的共享。
2016-12-06 17:08:17 233
原创 semaphore
在globalmem()中的读写时我们会用到copy_to_user和copy_from_user两个函数,他们会导致阻塞;因此不可以使用自旋锁。宜使用信号量。
2016-12-06 15:36:48 188
原创 写几个函数和结构体吧~
1、struct cdev{ struct file_operations* ops; dev_t dev; unsigned int count; struct kobject kobj; struct module *owner;
2016-12-05 21:14:59 461
原创 应用层自动创建设备节点
首先,要在应用层自动创建设备的节点肯定需要对应的工具,这工具就是udev、mknod以及uevent。不要认为很复杂,udev和mknod就是两个应用程序,uevevt就是一个文件,这个文件中就记录了设备号,而且这些设备号就是从内核传过来的。过程就是udev根据uevent文件中的设备号,利用mknod来创建设备节点就ok啦!第二,udev这个工具是怎么来找到这些从内核中传过来的参数的呢?还有就是
2016-12-05 15:31:19 387
原创 应用层到驱动层
1、应用层—->VFS——>驱动层——–>硬件层; 2、应用层的程序要想跟底层的硬件打交道必须要有设备文件;在应用层通过open打开一个设备文件时,在VFS层会建立inode结构体和file结构体,前者是静态的描述设备的一些信息(如:设备号,节点指针,设备类型以及cdev结构体),后者则会描述设备类型的一些动态信息(如:文件方法集,读写位置,权限,私有属性等)。注意file结构体中有inode的地
2016-12-04 21:51:29 6893
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人