linux学习(2)基本开发流程
来源:互联网 发布:防范电信网络诈骗知识 编辑:程序博客网 时间:2024/05/29 02:47
1、使用工具
1、SecureCRT 远程登录调试主机、本地调试下载开发板(通过USB)
2、FileZila 在本地计算机和linux主机进行文件传输
3、Source insight 查阅代码(可把u-boot工程文件,内核工程文件加入,方便代码查阅)
4、UltraEdit 代码编辑
5、oflash 烧录程序 Windows和linux都可用
6、DNW 烧录程序 Windows和linux都可用 在U-boot选择好下载后,同过DNW translate文件
7、VMware 11 虚拟机 用来安装linux2.6.22.6
8、本地PC 运行Windows 及其他软件
9、开发板 JZ2440 CPU S3C2440A(ARM920T) 64M SDRAM 运行linux2.6.22.6
256M NAND FLASH
2M NOR FLASH
10、网络、网线 使用网络下载文件到开发板,或者挂在网络文件系统
11、两根USB线 一根用来烧录,一根通过SecureCRT来调试开发板
12、openjtag 用来烧录
2、学习过程
开始工作:
在linux系统上准备好 1、u-boot源码+补丁文件
2、内核源码+ 补丁文件
3、根文件系统+补丁文件
然后开始按照1 2 3 的顺序 解压源文件,打上补丁→编译→烧录到开发板
第一步烧录u-boot时,需要使用openjtag+oflash。
后面烧录 内核和文件系统,或者加载驱动等等,都可以通过u-boot提供的多种方法,比如nfs,tftp,串口
已经有ARM嵌入式开发经验
1、编写裸机程序,通过openjtag下载验证 (GPIO ,UART,LCD,ADC,DAC....)
在linux下编译源码,生成可执行文件,烧录,观看
2、启动过程与存储管理
jz2440有两种启动过程
方式一 NAND 启动:先从nand flash复制前4K到SRAM(只用4k),然后把超过4K的代码复制到SDRAM中
方式二 NOR启动: 直接从nor flash的0地址开始启动
若开启了MMU,CPU读地址过程为 :CPU→MMU→存储器管理器→SDRAM
不使用MMU :CPU→SDRAM
3、linux从软件角度分类
1、加载程序 (firmware(嵌入式系统一般没有)+bootloader)
2、Linux内核
3、文件系统
4、用户应用程序
启动过程也是如此,可以先烧写u-boot,观察启动
在u-boot基础上烧入内核,重新启动 观察
在u-boot上烧入文件系统,重新启动观察
4、BootLoader启动的两个阶段
一阶段
1、硬件初始化
2、为加载BootLoader的第二阶段代码准备RAM空间
3、复制BootLoader的第二阶段代码到RAM空间
4、设置好栈
5、跳转到第二阶段代码的C入口点
(此过程基本都是汇编代码)
二阶段
1、初始化本阶段要使用的硬件设备
2、检查系统内存映射
3、将内核映像和根文件系统映像从flash读到RAM空间
4、位内核设置启动参数
5、调用内核
5、ARM架构linux系统内核启动的两个阶段
调用init(),正式进入应用程序。
6、根文件系统
/ (根文件)
/bin
/sbin
/dev
/etc
/lib
/home
/root
/user
/var
/proc
/mnt
/tmp
挂载文件到到linux服务器上
mount -t nfs -o nolock,vers=2 192.168.y.xx:/work/nfs_root /mnt
服务器地址 文件路径
从NFS文件启动
set bootargs noinitrd root=/dev/nfs nfsroot=192.168.y.xx:/work/nfs_root/tem/fs_mini_mdev ip=192.168.y.aa:192.168.y.xx:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
服务器地址 文件路径
从NFS文件启动
set bootargs noinitrd root=/dev/nfs nfsroot=192.168.y.xx:/work/nfs_root/tem/fs_mini_mdev ip=192.168.y.aa:192.168.y.xx:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
(开发板IP)
实现从服务器上启动,为加载驱动模块搭好环境
实现从服务器上启动,为加载驱动模块搭好环境
三、驱动开发
与裸机开发的不同点:
裸机开发直接操作物理地址
驱动程序操作虚拟地址(由ioremap映射而来)
从上到下,一个软件系统可以分为:
应用系统
库
操作系统
驱动程序
linux软件系统的层次关系如下
linux驱动程序的分类与开发步骤
分三类
1、字符设备:能够像字节流一样被访问的设备,对其读写以字节为单位
2、块设备:数据已块的形式存放,数据有一定的格式
3、网络接口类
开发步骤:
1、查看原理图,数据手册,了解设备操作方法
2、在内核中找到相近的驱动程序,以此为模板进行开发
3、实现驱动程序的初始化:向内核注册驱动程序,这样应用程序在传入文件名时,内核才能找到相应的驱动程序
4、设计所需要实现的操作,比如 open,close,read,write等
5、实现中断服务(可选)
6、编译该驱动程序到内核中,或者使用insmod加载。
7、测试驱动程序
以编写LED操作驱动为例:
为了调试方便:编写一个测试程序,及最初级的用户饮用程序,以来调用驱动。
1、驱动开发:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/io.h>#include <asm/arch/regs-gpio.h>#include <asm/hardware.h> //////////////头文件static struct class *firstdrv_class;static struct class_device*firstdrv_class_dev;volatile unsigned long *gpfcon = NULL;volatile unsigned long *gpfdat = NULL;static int first_drv_open(struct inode *inode, struct file *file){//printk("first_drv_open\n");/* 配置GPF4,5,6为输出 */*gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));*gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));return 0;}static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos){int val;//printk("first_drv_write\n");copy_from_user(&val, buf, count); //copy_to_user();if (val == 1){// 点灯*gpfdat &= ~((1<<4) | (1<<5) | (1<<6));}else{// 灭灯*gpfdat |= (1<<4) | (1<<5) | (1<<6);}return 0;}static struct file_operations first_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = first_drv_open, .write=first_drv_write, };
//该数组封装了驱动程序的动作,会被register_chrdev(0, "first_drv", &first_drv_fops); 注册到内核,被用户调用。int major;static int first_drv_init(void){major = register_chrdev(0, "first_drv", &first_drv_fops); // 注册, 告诉内核firstdrv_class = class_create(THIS_MODULE, "firstdrv");firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);gpfdat = gpfcon + 1;return 0;}static void first_drv_exit(void){unregister_chrdev(major, "first_drv"); // 卸载class_device_unregister(firstdrv_class_dev);class_destroy(firstdrv_class);iounmap(gpfcon);}module_init(first_drv_init);module_exit(first_drv_exit);MODULE_LICENSE("GPL");
2、测试函数
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>/* firstdrvtest on * firstdrvtest off */int main(int argc, char **argv){int fd;int val = 1;fd = open("/dev/xyz", O_RDWR);if (fd < 0){printf("can't open!\n");}if (argc != 2){printf("Usage :\n");printf("%s <on|off>\n", argv[0]);return 0;}if (strcmp(argv[1], "on") == 0){val = 1;}else{val = 0;}write(fd, &val, 4);return 0;}
总结:通过五天废寝忘食的学习,总是对linux有了基本把控的能力,继续努力,学习需要激情。
附:linux学习路线(来自韦东山老师)
善用开源库
调试程序
掌握嵌入式linuxAPP开发,部署过程。
参考文献:嵌入式Linux应用开发完全手册 韦东山
0 0
- linux学习(2)基本开发流程
- Android百度地图API学习(二) 开发基本流程
- linux系统平台开发基本流程
- Linux驱动开发git基本使用流程
- Linux开发--学习流程《转》
- Struts 2开发基本流程
- 项目开发流程(基本流程)
- 项目开发基本流程
- 软件开发基本流程
- struts基本开发流程
- Android 基本开发流程
- web开发基本流程
- 软件开发基本流程
- NDK开发基本流程
- linux启动基本流程
- Linux 调度基本流程
- Web Service学习笔记(基本流程)
- Java 基本学习流程
- 全面了解 Nginx 主要应用场景
- SDUT 3302 效率至上 求区间内最大最小
- 模仿Wireshark网络抓包工具实现---c++
- 论文笔记:A clockwork RNN
- cocos2dx jni闪退的BUG
- linux学习(2)基本开发流程
- WPF样式
- 使用Gradle自定义配置构建Java程序
- Spark第二代Tungsten引擎测试数据和引擎实现内幕
- 高性能服务器架构思路(一)——缓冲策略
- Oracle游标遍历
- PAT-B 1023. 组个最小数 (20)
- 讲讲如何将图片格式转化成base64格式的
- Java实例-输入学生成绩,计算出平均分,并判断及格人数和不及格人数