生产者消费者课设报告_第1页
生产者消费者课设报告_第2页
生产者消费者课设报告_第3页
生产者消费者课设报告_第4页
生产者消费者课设报告_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 课程设计目的进行操作系统课程设计主要是在学习操作系统课程的基础上,在完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。课程设计内容与要求模拟仿真“生产者-消费者”问题的解决过程及方法。通过研究Linux的进程机制和信号量,实现生产者消费者问题的并发控制。设计要求:生产者与消费者均有二个以上。生产者和消费者进程的数目在程序界面上可调,在运行时可随时单个

2、增加与减少生产者与消费者。3) 生产者的生产速度与消费者的消费速度均可在程序界面调节,在运行中,该值调整后立即生效。4) 多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码。 5) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前生产者与消费者的指针位置,以及生产者和消费者线程标识符。 6) 采用可视化界面,可在运行过程中随时暂停,查看当前生产者、消费者以及有界缓冲区的状态。 生产者与消费者问题是经典进程同步问题的典型代表之一。该课程设计通过了解进程间的两种制约关系,从而理解信号量机制;通过对实例的分析和讨论,理解信号量机制实现进程的同步及互斥的方法;通

3、过对经典进程同步问题的剖析,初步掌握运用信号量解决进程同步问题的方法。本系统的功能是根据输入的生产者进程和消费者进程(缓冲区设为了固定大小20),动态显示生产者进程从生产“产品”到放入缓冲区,消费者进程从缓冲区中取“产品”的整个过程,同时,系统也显示了整个过程中缓冲池中临界资源的变化情况。系统分析与设计系统分析在操作系统中, 线程有时被称为轻量级进程, 是CPU 使用的基本单位, 它与属于同一进程的其他进程共享其他代码段、数据段和其他操作系统资源。在Java 中, 线程的建立有两种方法: 继承Thread 类和实现Runnable 接口。其中, 采用实现Runnable 接口建立线程的好处是允

4、许同时继承其他类从而实现多继承,并且在Java 中, 可采用synchronized 或Object 类的方法wait( ), notify( ), notifyAll( )来实现多线程同步。Java 多线程同步机制的实现是基于管程(Monitor)机制,在Java 中每个对象都包含一把同步锁( 管程对象) 和一个线程等待集合, 当对象生成时它们随之自动生成。线程等待集的初值为空, 同步锁的初始状态为开锁状态。 只有当对象object 的同步锁处于开锁状态时, 对象object 的synchronized 方法或以对象为同步参数的synchronized 块( 以下简称synchronized

5、 方法( 块) ) 才允许访问对象object。当线程thread1 运行对象object 的synchronized方法( 块) 时, 首先需object 的同步锁锁上, thread1将object 上锁成功后才继续执行synchronized 方法( 块) 内语句。当synchronized 方法( 块) 正常结束或异常退出时, 同步锁解锁动作自动执行。Object 类的方法wait( ), notify( )和notifyAll( )可实现线程间的通信。当线程thread1 调用object.wait( )时, 则thread1 停止执行, 将thread1 加入object 的线程等

6、待集, 并解锁其上锁的所有对象同步锁; 当线程thread2 调用object.notify( )时, 从object 的线程等待集中随机移出一个线程thread3 ( 在Java 语言规范中没有规定选择移出线程的算法, 由JVM实现时决定) 去参与线程调度。多个生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有20个存储单元的缓冲区,生产者进程将它所生产的产品放入缓冲区中;消费者进程可从缓冲区中取走产品去消费。利用信号量机制来实现多进程(生产者进程和消费者进程)对缓冲区(临界资源)的互斥访问。设置多进程的共享变量为临界资源

7、,同时给它设置一个互斥信号量,多进程利用互斥信号量来完成对临界资源的互斥访问(当信号量为某个值是允许进程访问,否则则不允许进程访问),从而确保共享数据的正确性。系统设计: 1) 生产者- 消费者问题的提出并发程序在设计上是有困难, 其中最大的问题是进程或者线程间的同步问题, 而生产者消费者问题是最经典的问题之一, 其描述如下: 有n 个生产者和m 个消费者, 连接在一个有k 个单位缓冲区的有界环形缓冲上, pi、cj 都是并发进程, 只要缓冲区未满, 生产者pi 生产的产品就可以投入缓冲区; 类似地, 只要缓冲区不空, 消费者进程cj 就可以从缓冲区取走并消耗产品。 2) 生产者- 消费者问题

8、的解决模型与Java 实现在下面的Java 应用程序中, 生产者线程向缓冲区中写数据, 消费者从缓冲区中读数据, 这样, 在这个程序中同时运行的多个线程竞争同一个缓冲区资源。类Producer 是生产者模型, 其中的run( )方法中定义了生产者线程所做的操作, 循环地将生产的“产品”放入缓冲区中, 每次生产完后, 调用sleep( )方法睡眠一段随机时间, 以给其他线程执行的机会。类Consumer是消费者模型, 循环地消费“产品”, 从缓冲区中取出数据, 每次执行完消费操作后, 调用sleep( )方法睡眠一段随机时间, 以给其他线程执行的机会。同时靠着信号量:mutex、empty、fu

9、ll 来同步多个生产者消费者之间的操作, 表1 列出了各个类在模型中所起到的作用。在Windows中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex) 。使用这些对象都分为三个步骤,一是创建或者初始化;接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。这些同步对象在主进程中创建,在其子线程中都可。2、1模块设计:模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。大概的结构如下图。生产者流程图:阻塞为空阻塞为空否无空缓冲区否无空缓冲区空缓冲区空缓冲区是是结 束 解

10、 锁缓冲区已满,请等待生产者生产产品 放入缓冲区对缓冲区加锁结 束 解 锁缓冲区已满,请等待生产者生产产品 放入缓冲区对缓冲区加锁消费者流程图:阻塞为空阻塞为空否无满缓冲区否无满缓冲区满缓冲区满缓冲区是是结 束 解 锁没有产品可消费,请等待消费者消费缓冲区内的产品对缓冲区加锁结 束 解 锁没有产品可消费,请等待消费者消费缓冲区内的产品对缓冲区加锁函数关系图:OSProject()函数OSProject()函数Producer()函数Consumer()函数OSProject.formBufferPool类缓冲区wait_metux(),signal_metux()供生产者和消费者共享!2、2数

11、据结构说明: (1)Producer类:声明并创建了Producer类, 定义了生产者的操作。 类Producer 是生产者模型, 其中的run( )方法中定义了生产者线程所做的操作, 循环地将生产的“产品”放入缓冲区中, 每次生产完后, 调用sleep( )方法睡眠一段随机时间, 以给其他线程执行的机会。(2)Consumer类:声明并创建了Consumer类,定义了消费者的操作。类Consumer是消费者模型, 循环地消费“产品”, 从缓冲区中取出数据, 每次执行完消费操作后, 调用sleep( )方法睡眠一段随机时间, 以给其他线程执行的机会。(3)两个互斥量:Full_Control:

12、当缓冲区满时迫使生产者等待。 提供信号量full的P V 操作及其阻塞队列,及消费者阻塞队列。 Empty_Control:当缓冲区空时迫使消费者等待。提供信号量full的P V 操作及其阻塞队列,及消费者阻塞队列。 (4)BufferPool类:声明并创建了BufferPool类,定义了缓冲区的操作。提供基本数据结构、信号量mutex的P V操作及其阻塞队列。 有界缓冲区内设有20个存储单元,放入取出的产品设定为1-20个整数。对缓冲区的生产和消费操作都是互斥访问,设有互斥量mutex用来实现这个功能。(5)在实现本程序的消费生产模型时,具体地通过如下同步对象实现互斥:一个互斥量mutex,

13、以实现生产者在查询和保留缓冲区内的下一个空位置时进行互斥。(6)程序中用到的类及每个的属性和方法: 2、3算法流程图:生产一条数据生产一条数据等待资源,阻塞等待资源,阻塞是否可用存储单元是否可用存储单元 无被唤醒被唤醒 有存入一条数据存入一条数据full数据单元加1,唤醒一个消费者full数据单元加1,唤醒一个消费者生产者算法是否有数据单元是否有数据单元 否等待资源,阻塞等待资源,阻塞 有取走一条数据被唤醒取走一条数据被唤醒empty数据单元加1,唤醒一个生产者empty数据单元加1,唤醒一个生产者消费数据消费数据消费者算法等待访问临界资源的线程等待访问临界资源的线程置管程为开锁状态管程状态

14、locked置管程为开锁状态管程状态 unlocked获得管程释放管程获得管程释放管程临界资源临界资源 缓冲区算法四、模块调试与系统测试1、模块调试输入的形式:输入生产者、消费者的个数及速度输出的形式:以文本框输出的形式动态展现生产者生产和消费者消费的全过程。程序所能达到的功能:本系统的功能是根据输入的生产者进程和消费者进程以及缓冲区的大小,动态显示生产者进程从生产“产品”到放入缓冲区,消费者进程从缓冲区中取“产品”的整个过程,同时,系统也显示了整个过程中缓冲区中临界资源的变化情况。2、系统测试测试方法:黑盒测试法黑盒测试(Blackbox Testing,又称为功能测试或数据驱动测试)是把测

15、试对象看作一个黑盒子。利用黑盒测试法进行动态测试时,需要测试软件产品的功能,不需测试软件产品的内部结构和处理过程。黑盒测试试图发现以下类型的错误:功能错误或遗漏;界面错误;数据结构或外部数据库访问错误;性能错误;初始化或终止错误; 测试技术:单元测试 单元测试应用背景:它是从开发者的角度来编写的,用于确保类的每个特定方法成功执行一系列特定的任务。每一个测试都要保证对于给定的一个已知的输入应该得到所期望的输出。测试数据:生产者和消费者的个数初始为0,演示过程中逐个增加进程的个数和随 时改变生产者和消费者的速度。测试报告:测试结果如下:测试说明测试名称用多线程同步演示生产者消费者程序测试目的模拟仿

16、真“生产者-消费者”问题的解决过程及方法测试技术单元测试测试方法黑盒测试测试用例测试内容程序各个功能实现水平测试步骤单个增加进程数目输入合法速度改变速度测试数据生产者加1消费者加13000,2000500,600预期结果程序正确运行生产消费者按输入速度执行速度明显改变测试结果与预期相符与预期相符与预期相符测试用例测试内容缓冲区存储单元变化测试步骤更改进程的数目输入合法速度改变速度测试数据进程加减1300,20003000,200预期结果缓冲区存储正常变化缓冲区存储饱和缓冲区变空测试结果与预期相符与预期相符与预期相符 3、调试分析:根据用户的实际要求对系统进行初始化并执行程序,其操作的一般流程:

17、系统初始化(设置进程数和缓冲区的大小)、生产者生产资源并存放在缓冲区中、消费者从缓冲区中取资源和消耗资源。不足和缺陷:此程序不便于对较大的数据量的生产者消费者问题进行测试,主要由于设计上的对系统处理的数据量的限制,例如本系统初始化方面设计时将缓冲区大小限制了固定大小。没有对其中的生产者和消费者设置优先级,在生产者和消费者进程中只是以采用synchronized方法,随机的确保每个进程都能够执行,不能满足用户某些优先进程的特殊要求。五、用户手册1、使用的平台是:MyEclipse8.5 Swing/MetisseMyEclipse8.5具有如下优势:快速开发新突破创建杰出的用户体验跨越开发周期的

18、协作采用统一整合的方式处理数据体验全新的web开发工具将数据库功能整合到应用程序生命周期的管理中下载地址:/tool/myeclipse/17872.html、2、不需要安装但需要配置文件。下面是我的安装步骤:1解压MyEclipse8.5;解压的时候需要记住解压目录;2 选择工作环境;3. 配置文件前先确认安装jdk;4 建立目录E:AndroideclipseMyEclipse;5本程序是用Java语言编写的,在MyEclipse8.5集成开发环境中运行的。在使程序时,进行运行该程序。程序即进入运行阶段。程序运行效果图:初始化界面及各种功能按钮:初始生产与消费的结果: 速度改变后生产与消费

19、的结果:缓冲区为满时的状态缓冲区为空时的状态六、程序清单生产者:Producerpublic void run() while (count !=bp.BUFFER_SIZE) ec.wait_empty(); / 等待有空的缓冲区可用bp.wait_mutex(); / 等待缓冲区可用/ 生产产品放入缓冲区bp.bufferbp.in = i;count+;/ 生产者线程使用的下一个缓冲区索引System.out.println( 生产者 + number + 放入了 + i + 个产品);System.out.println(此时缓冲区内有 + count + 个产品);bp.signal

20、_mutex();/ 释放缓冲池,唤醒可能存在的生产者或消费者线程fc.signal_full();/ 可用的缓冲区数量加1, 唤醒可能存在的消费者线程try int Pspeed =OSProject.PSpeed;sleep(Pspeed);/ 让线程等待一段时间再运行, 为了模拟而用 catch (InterruptedException e) System.out.println(缓冲区已满,等待消费者消费产品);消费者 Consumer public void run() while(p.count!=0)fc.wait_full();/ 等待有装有“产品”的缓冲区可用bp.wait

21、_mutex();/ 等待缓冲池可用/ 消费“产品”System.out.println( 消费者+number+取出了 + i+个产品);p.count-;System.out.println(此时缓冲区内有+p.count+个产品);/ 消费者线程使用的下一个缓冲区索引bp.signal_mutex();/ 释放缓冲池,唤醒可能存在的生产者或消费者线程ec.signal_empty();/ 可用的空缓冲区数量加1, 唤醒可能存在的生产者线程try int Cspeed =OSProject.CSpeed;sleep(Cspeed);/ 让线程等待一段时间再运行, 为了模拟而用 catch

22、(InterruptedException e) System.out.println(缓冲区已空,等待生产者生产产品); 缓冲区BufferPoolpublic static final int BUFFER_SIZE = 20;/ 设置缓冲池buffer 的互斥信号量及池中空数据缓冲区、可消费的数据缓冲区的初值public static int mutex = 1, empty = BUFFER_SIZE, full = 0;public int in = 0, out = 0;public int buffer = new intBUFFER_SIZE;public synchroniz

23、ed void wait_mutex() mutex-;if (mutex 0) / 其他线程正在使用缓冲池buffertry wait(); / 在本pool的阻塞队列中等待 catch (InterruptedException e) public synchronized void signal_mutex() mutex+;if (mutex = 0)notify();/ 唤醒本pool的阻塞队列中的其他等待使用缓冲池buffer 的线程两个信号量控制Empty_Controlpublic synchronized void wait_empty() BufferPool.empty-

24、;if (BufferPool.empty 0)try wait(); catch (InterruptedException e) public synchronized void signal_empty() BufferPool.empty+;if (BufferPool.empty = 0)notify();Full_Controlpublic synchronized void wait_full() BufferPool.full-;if (BufferPool.full 0)try wait(); catch (InterruptedException e) public syn

25、chronized void signal_full() BufferPool.full+;if (BufferPool.full = 0)notify();七、体会与自我评价通过此次课程设计过程,使我通过实际实践来更加了解计算机操作系统的知识,至少比以前更加了解生产者消费者问题,应该不会出现题不会做的现象,特别是通过做“生产者消费者”经典同步问题,对进程的运行方式、以及如何确保计算机操作系统既保持同步又保持互斥的对临界资源的访问来同时进行多任务工作。通过对信号量以及管程机制的引入,使得对临界资源的 使用更加有效,多任务的准确性得以保证。从Java 的多线程机制出发, 研究了操作系统中经典的同

26、步问题生产者消费者问题, 提出了两种解决此问题的模型, 及其Java 解决方案。提出的两个模型充分利用了Java 中面向对象和管程机制, 模拟了操作系统中进程同步的经典问题生产者消费者问题。在第一个模型中, 我们按照生产者消费者问题典型的解决方案给出了Java 解决模型; 在第二个模型中, 我们分析了信号量mutex 在问题中所起的作用, 并为了提高缓冲区读写的效率, 提出了将信号量mutex 分为两个分别控制生产者和消费者的信号量,并讨论了此方案的可行性。在Java 中, 线程的建立有两种方法: 继承Thread 类和实现Runnable 接口。其中, 采用实现Runnable 接口建立线程

27、的好处是允许同时继承其他类从而实现多继承,并且在Java 中, 可采用synchronized 或Object 类的方法wait( ), notify( ), notifyAll( )来实现多线程同步。Java 多线程同步机制的实现是基于管程(Monitor)机制,在Java 中每个对象都包含一把同步锁( 管程对象) 和一个线程等待集合, 当对象生成时它们随之自动生成。线程等待集的初值为空, 同步锁的初始状态为开锁状态。课程设计的收获: 1.程序的设计思想的精巧的重要性,是不管怎么说都不为过的,好的设计可以让大家很快的明白你的思想,而且很方便的来实现它。 2.良好的编程习惯,它可以使你的程序很

28、方便的被别人阅读,也很方便的被更改,所以可以的话,尽可能多的写出注释,使程序简洁明了。 3.基本的语言功底一定要扎实。 4.在实现各个功能的过程中,细心和耐心是必不可少的。八、参考文献1 汤子瀛 编著,计算机操作系统(修订版) 西安电子科技大学出版社,2001年2 胡明庆,高巍,钟梅 操作系统教程与实验 清华大学出版社 2007.1 3 丁振凡主编,薛清华副主编 java程序语言设计 清华大学出版社 2010.104李善平 操作系统学习指导和考试指导 浙江大学出版社2004 年 九、课程设计评价课程设计评价 成绩: 教师: 年 月 日附录资料:不需要的可以自行删除 busybox详解制作根文件

29、系统详解制作根文件系统 一、FHS(Filesystem Hierarchy Standard)标准介绍当我们在linux下输入ls / 的时候,见到的目录结构以及这些目录下的内容都大同小异,这是因为所有的linux发行版在对根文件系统布局上都遵循FHS标准的建议规定。该标准规定了根目录下各个子目录的名称及其存放的内容:目录名存放的内容/bin必备的用户命令,例如ls、cp等/sbin必备的系统管理员命令,例如ifconfig、reboot等/dev设备文件,例如mtdblock0、tty1等/etc系统配置文件,包括启动文件,例如inittab等/lib必要的链接库,例如C链接库、内核模块/

30、home普通用户主目录/rootroot用户主目录/usr/bin非必备的用户程序,例如find、du等/usr/sbin非必备的管理员程序,例如chroot、inetd等/usr/lib库文件/var守护程序和工具程序所存放的可变,例如日志文件/proc用来提供内核与进程信息的虚拟文件系统,由内核自动生成目录下的内容/sys用来提供内核与设备信息的虚拟文件系统,由内核自动生成目录下的内容/mnt文件系统挂接点,用于临时安装文件系统/tmp临时性的文件,重启后将自动清除制作根文件系统就是要建立以上的目录,并在其中建立完整目录内容。其过程大体包括:编译安装busybox,生成/bin、/sbin

31、、/usr/bin、/usr/sbin目录 利用交叉编译工具链,构建/lib目录 手工构建/etc目录 手工构建最简化的/dev目录 创建其它空目录 配置系统自动生成/proc目录 利用udev构建完整的/dev目录 制作根文件系统的jffs2映像文件 下面就来详细介绍这个过程。二、编译安装busybox,生成/bin、/sbin、/usr/bin、/usr/sbin目录这些目录下存储的主要是常用命令的二进制文件。如果要自己编写这几百个常用命令的源程序,my god, 这简直是一个噩梦!好在我们有嵌入式Linux系统的瑞士军刀busybox,事情就简单很多。1、从 HYPERLINK / /

32、下载busybox-1.7.0.tar.bz22、tar xjvf busybox-1.7.0.tar.bz2解包3、修改Makefile文件175 ARCH ?= arm176 CROSS_COMPILE ?= arm-linux- 4、make menuconfig配置busyboxbusybox配置主要分两部分。第一部分是Busybox Settings,主要编译和安装busybox的一些选项。这里主要需要配置:1)、Build Options - Build BusyBox as a static binary (no shared libs),表示编译busybox时,是否静态链接C

33、库。我们选择动态链接C库。2)、Installation Options - Applets links (as soft-links) - (X) as soft-links,表示安装busybox时,将各个命令安装为指向busybox的软链接还是硬链接。我们选择软链接。3)、Installation Options - (/work/nfs_root/fs_mini3) BusyBox installation prefix,表示busybox的安装位置。我们选择/work/nfs_root/fs_mini34)Busybox Library Tuning。保留Command line e

34、diting以支持命令行编辑;保留History size以支持记忆历史命令;选中Tab completion和Username completion以支持命令自动补全 第二部分是Applets,他将busybox的支持的几百个命令分门别类。我们只要在各个门类下选择想要的命令即可。这里我们基本保持默认设置。1)选中Networking Utilities - httpd下的Enable -u option,以启用http服务器的功能allows the server to run as a specific user5、编译busyboxmake6、安装busyboxmake install安

35、装完成后,可以看到在/work/nfs_root/fs_mini3目录下生成了binsbinusr/binusr/sbin目录,其下包含了我们常用的命令,这些命令都是指向bin/busybox的软链接,而busybox本身的大小不到800K:dennisdennis-desktop:/work/nfs_root/fs_mini3$ lsbin linuxrc sbin usrdennisdennis-desktop:/work/nfs_root/fs_mini3$ ls -l bintotal 740lrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 a

36、ddgroup - busyboxlrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 adduser - busyboxlrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 ash - busybox-rwxr-xr-x 1 dennis dennis 749632 2010-04-03 23:57 busyboxlrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 cat busybox 而普通PC机上的ls命令就有差不多80K的大小: dennisdennis-desktop

37、:/work/nfs_root/fs_mini3$ ls -l /bin/ls-rwxr-xr-x 1 root root 78004 2007-09-29 20:51 /bin/ls busybox以它娇小的身躯容纳了数以百计的命令代码,实在是让人佩服不已,其不愧嵌入式系统瑞士军刀之美誉。据说,busybox的作者身患绝症,这更让人钦佩GNU开源软件的作者们。 三、利用交叉编译工具链,构建/lib目录 光有应用程序(命令)是不够的,因为应用程序本身需要使用C库的库函数,因此还必需制作for ARM的C库,并将其放置于/lib目录。my god,要自己写C库的源代码吗?不用!还记得交叉编译工具

38、链的3个组成部分吗?交叉编译器、for ARM的C库和二进制工具。哈哈,for ARM的C库是现成的,我们只需要拷贝过来就可以了。遗憾的是:整个C库目录下的文件总大小有26M。而我们根文件系统所在分区不过区区16M而已,根本放不下。怎么办呢? dennisdennis-desktop:/work/nfs_root/fs_mini3$ du -s -si /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib26M /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib 需要C库目录下所有的文件吗?no,absolu

39、tely no! 让我们来分析一下glibc库目录下内容的组成。该目录下的子目录和文件共分8类: 目标文件,如crtn.o,用于gcc链接可执行文件 libtool库文件(.la),在链接库文件时这些文件会被用到,比如他们列出了当前库文件所依赖的其它库文件,程序运行时无需这些文件 gconv目录,里面是各种链接脚本,在编译应用程序时,他们用于指定程序的运行地址,各段的位置等 静态库文件(.a),例如libm.a,libc.a 动态库文件 (.so、.so.0-9*) 动态链接库加载器ld-2.3.6.so、ld-linux.so.2 其它目录及文件很显然,第1、2、3、4、7类文件和目录是不需

40、要拷贝的。由于动态链接的应用程序本身并不含有它所调用的C库函数的代码,因此执行时需要动态链接库加载器来为它加载相应的C库文件,所以第6类文件是需要拷贝的。除此之外,第5类文件当然要拷贝。但第5类文件的大小也相当大。dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ du -c -si *.so* 7.2M total 需要全部拷贝吗?非也,非也!其实,需要哪些库完全取决于要运行的应用程序使用了哪些库函数。如果我们只制作最简单的系统,那么我们只需要运行busybox这一个应用程序即可。通过执行 dennisd

41、ennis-desktop:/work/nfs_root/fs_mini3$ arm-linux-readelf -a bin/busybox | grep Shared0 x00000001 (NEEDED) Shared library: libcrypt.so.10 x00000001 (NEEDED) Shared library: libm.so.60 x00000001 (NEEDED) Shared library: libc.so.6 可知:busybox只用到了3个库:通用C库(libc)、数学库(libm)、加密库(libcrypt),因此我们只需要拷贝这3个库的库文件即可

42、。但是每个库都有4个文件,4个文件都要拷贝吗?当然不是。 dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ ls -l libcrypt.-*-rwxr-xr-x 1 dennis dennis 30700 2008-01-22 05:32 libcrypt-2.3.6.so-rw-r-r- 1 dennis dennis 23118 2008-01-22 05:32 libcrypt.alrwxrwxrwx 1 dennis dennis 13 2008-12-22 15:38 libcrypt.so

43、- libcrypt.so.1lrwxrwxrwx 1 dennis dennis 17 2008-12-22 15:38 libcrypt.so.1 - libcrypt-2.3.6.sodennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ ls -l libm.-*-rwxr-xr-x 1 dennis dennis 779096 2008-01-22 05:31 libm-2.3.6.so-rw-r-r- 1 dennis dennis 1134282 2008-01-22 05:32 libm.alr

44、wxrwxrwx 1 dennis dennis 9 2008-12-22 15:38 libm.so - libm.so.6lrwxrwxrwx 1 dennis dennis 13 2008-12-22 15:38 libm.so.6 - libm-2.3.6.sodennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ ls -l libc.-*-rwxr-xr-x 1 dennis dennis 1435660 2008-01-22 05:48 libc-2.3.6.so-rw-r-r- 1 dennis

45、 dennis 2768280 2008-01-22 05:31 libc.a-rw-r-r- 1 dennis dennis 195 2008-01-22 05:34 libc.solrwxrwxrwx 1 dennis dennis 13 2008-12-22 15:38 libc.so.6 - libc-2.3.6.so 4个文件中的.a文件是静态库文件,是不需要拷贝的。另外3个文件是: 实际的共享链接库:libLIBRARY_NAME-GLIBC_VERSION.so。当然需要拷贝。 主修订版本的符号链接,指向实际的共享链接库:libLIBRARY_NAME.so.MAJOR_REVI

46、SION_VERSION,程序一旦链接了特定的链接库,将会参用该符号链接。程序启动时,加载器在加载程序前,会检索该文件。所以需要拷贝。 与版本无关的符号链接,指向主修订版本的符号连接(libc.so是唯一的例外,他是一个链接命令行:libLIBRARY_NAME.so,是为编译程序时提供一个通用条目)。这些文件在程序被编译时会被用到,但在程序运行时不会被用到,所以不必拷贝它。关于共享库的2个符号链接的作用的特别说明:当我们使用gcc hello.c -o hello -lm编译程序时,gcc会根据-lm的指示,加头(lib)添尾(.so)得到libm.so,从而沿着与版本无关的符号链接(lib

47、m.so - libm.so.6)找到libm.so.6并记录在案(hello的ELF头中),表示hello需要使用libm.so.6这个库文件所代表的数学库中的库函数。而当hello被执行的时候,动态链接库加载器会从hello的ELF头中找到libm.so.6这个记录,然后沿着主修订版本的符号链接(libm.so.6 - libm-2.3.6.so)找到实际的共享链接库libm-2.3.6.so,从而将其与hello作动态链接。可见,与版本无关的符号链接是供编译器使用的,主修订版本的符号链接是供动态链接库加载器使用的,而实际的共享链接库则是供应用程序使用的。通过以上分析,我们只需要拷贝3个库

48、(每个库各1个主修订版本的符号链接和1个实际的共享链接库)以及动态链接库加载器(1个符号链接和1个实体文件)。步骤如下:dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ mkdir /work/nfs_root/fs_mini3/lib dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp libcrypt-* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/wor

49、k/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp -l libcrypt.so.* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp libm-* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp -l libm.so.* /work/nfs_root/

50、fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp libc-* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp -l libc.so.* /work/nfs_root/fs_mini3/lib dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/li

51、b$ cp -l ld-* /work/nfs_root/fs_mini3/lib 四、手工构建/etc目录 /etc目录存放的是系统程序的主配置文件,因此需要哪些配置文件取决于要运行哪些系统程序。即使最小的系统也一定会运行1号用户进程init,所以我们至少要手工编写init的主配置文件inittab。busybox的inittab文件的语法、语义与传统的SYSV的inittab有所不同。 inittab文件中每个条目用来定义一个需要init启动的子进程,并确定它的启动方式,格式为:。例如:ttySAC0:askfirst:-/bin/sh 表示子进程要使用的控制台,若省略则使用与init进程

52、一样的控制台 表示运行级别,busybox init程序这个字段没有意义 表示init进程如何控制这个子进程 sysinit:系统启动后最先执行,只执行一次,init进程等待它结束后才继续执行其它动作 wait:系统执行完sysinit条目后执行,只执行一次,init进程等待它结束后才继续执行其它动作 once:系统执行完wait条目后执行,只执行一次,init进程不等待它结束 respawn:启动完once进程后,init进程监测发现子进程退出时,重新启动它 askfirst:启动完respawn进程后,与respawn类似,不过init进程先输出” Please press Enter t

53、o activate this console“,等用户输入回车后才启动子进程 shutdown:当系统关机时 restart:Busybox中配置了CONFIG_FEATURE_USE_INITAB,并且init进程接收到SIGUP信号时执行,先重新读取、解析/etc/inittab文件,再执行restart程序 ctrlaltdel:按下ctrl+alt+del键时执行,不过在串口控制台中无法输入它 表示进程对应的二进制文件。如果前面有-号,表示该程序是“可以与用户进行交互的”我们制作最简单的/etc/inittab文件,其内容如下::sysinit:/etc/init.d/rcS:ask

54、first:-/bin/sh:ctrlaltdel:/sbin/reboot:shutdown:/bin/umount -a r 制作最简单的脚本程序文件/etc/init.d/rcS,其内容如下: #!/bin/shifconfig eth0 7修改shell脚本文件/etc/init.d/rcS的权限,以使其可被执行:# chmod a+x /etc/init.d/rcS五、手工构建最简化的/dev目录 在linux机器上,执行ls /dev可看到几百个设备文件,我需要手工创建它们吗?maybe,我只需要手工创建几个设备文件!我怎么知道我应该创建哪几个设备文件呢?管它呢,先看看开发板上可爱

55、的linux的反应再说。 启动Linux操作系统,显示: VFS: Mounted root (nfs filesystem).Freeing init memory: 112KWarning: unable to open an initial console. 这说明,内核已经成功挂载根文件系统,但却未能成功启动第1个用户进程init。通过错误消息“unable to open an initial console”搜索内核源代码,找到init/main.c文件。748 static int noinline init_post(void)749 750 free_initmem();75

56、1 unlock_kernel();752 mark_rodata_ro();753 system_state = SYSTEM_RUNNING;754 numa_default_policy();755 756 if (sys_open(const char _user *) /dev/console, O_RDWR, 0) 0)757 printk(KERN_WARNING Warning: unable to open an initial console.n);758 759 (void) sys_dup(0);760 (void) sys_dup(0);761 762 if (ram

57、disk_execute_command) 763 run_init_process(ramdisk_execute_command);764 printk(KERN_WARNING Failed to execute %sn,765 ramdisk_execute_command);766 767 768 /*769 * We try each of these until one succeeds.770 *771 * The Bourne shell can be used instead of init if we are772 * trying to recover a really

58、 broken machine.773 */774 if (execute_command) 775 run_init_process(execute_command);776 printk(KERN_WARNING Failed to execute %s. Attempting 777 defaults.n, execute_command);778 779 run_init_process(/sbin/init);780 run_init_process(/etc/init);781 run_init_process(/bin/init);782 run_init_process(/bi

59、n/sh);783 784 panic(No init found. Try passing init= option to kernel.);785 显然,内核错误是由175行不能打开/dev/console所致。通过查看已经安装好的linux机器的/dev/console设备文件,可知其是字符设备文件,主设备号为5,次设备号为1: dennisdennis-desktop:/work/nfs_root/fs_mini3/etc$ ls -l /dev/consolecrw 1 root root 5, 1 2010-04-08 08:40 /dev/console 因此,我们使用下面的命令

60、创建它: HYPERLINK mailto:dennisdennis-desktop:/work/nfs_root/fs_mini3/dev$ dennisdennis-desktop:/work/nfs_root/fs_mini3/dev$ sudo mknod console c 5 1 还需要创建其它设备文件吗?只有天知道!再看看linux的反应。 VFS: Mounted root (nfs filesystem).Freeing init memory: 112Kinit: cant open /dev/null: No such file or directory 这次我们有经验了

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论