linux编译画圆
1. 求linux下汉诺塔程序详细解释~~
不要把简单问题复杂化,汉诺塔其实很简单,通过它你关键在理解递归原理就行,何必纠结于这些让人费解的上面的垃圾代码!
汉诺塔程序如下:
#include <iostream>
#include <string>
using namespace std;
int sum=0;
/*
* 为了移动A上面的圆盘到C上面,仅能借助B:
* 首先由A将n-1个较小的圆盘移至B,
* 然后将A上剩下的上最大的圆盘移至C,
* 最后再将B上n-1个较小的圆盘移至C
*/
void Hanoi(int n,string A,string B,string C)
{
if(n==1)
cout<<"move "<<A<<" to "<<C<<endl;
else
{
Hanoi(n-1,A,C,B);
cout<<"move "<<A<<" to "<<C<<endl;
Hanoi(n-1,B,A,C);
}
++sum;
}
int main()
{
Hanoi(3,"A","B","C");
cout<<"The sum step is "<<sum<<endl;
return 0;
}
2. linux编译内核步骤
一、准备工作
a) 首先,你要有一台PC(这不废话么^_^),装好了Linux。
b) 安装好GCC(这个指的是host gcc,用于编译生成运行于pc机程序的)、make、ncurses等工具。
c) 下载一份纯净的Linux内核源码包,并解压好。
注意,如果你是为当前PC机编译内核,最好使用相应的Linux发行版的源码包。
不过这应该也不是必须的,因为我在我的Fedora 13上(其自带的内核版本是2.6.33.3),就下载了一个标准的内核linux-2.6.32.65.tar.xz,并且顺利的编译安装成功了,上电重启都OK的。不过,我使用的.config配置文件,是Fedora 13自带内核的配置文件,即/lib/moles/`uname -r`/build/.config
d) 如果你是移植Linux到嵌入式系统,则还要再下载安装交叉编译工具链。
例如,你的目标单板CPU可能是arm或mips等cpu,则安装相应的交叉编译工具链。安装后,需要将工具链路径添加到PATH环境变量中。例如,你安装的是arm工具链,那么你在shell中执行类似如下的命令,假如有类似的输出,就说明安装好了。
[root@localhost linux-2.6.33.i686]# arm-linux-gcc --version
arm-linux-gcc (Buildroot 2010.11) 4.3.5
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for ing conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
注:arm的工具链,可以从这里下载:回复“ARM”即可查看。
二、设置编译目标
在配置或编译内核之前,首先要确定目标CPU架构,以及编译时采用什么工具链。这是最最基础的信息,首先要确定的。
如果你是为当前使用的PC机编译内核,则无须设置。
否则的话,就要明确设置。
这里以arm为例,来说明。
有两种设置方法():
a) 修改Makefile
打开内核源码根目录下的Makefile,修改如下两个Makefile变量并保存。
ARCH := arm
CROSS_COMPILE := arm-linux-
注意,这里cross_compile的设置,是假定所用的交叉工具链的gcc程序名称为arm-linux-gcc。如果实际使用的gcc名称是some-thing-else-gcc,则这里照葫芦画瓢填some-thing-else-即可。总之,要省去名称中最后的gcc那3个字母。
b) 每次执行make命令时,都通过命令行参数传入这些信息。
这其实是通过make工具的命令行参数指定变量的值。
例如
配置内核时时,使用
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
编译内核时使用
make ARCH=arm CROSS_COMPILE=arm-linux-
注意,实际上,对于编译PC机内核的情况,虽然用户没有明确设置,但并不是这两项没有配置。因为如果用户没有设置这两项,内核源码顶层Makefile(位于源码根目录下)会通过如下方式生成这两个变量的值。
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ )
ARCH?= $(SUBARCH)
CROSS_COMPILE ?=
经过上面的代码,ARCH变成了PC编译机的arch,即SUBARCH。因此,如果PC机上uname -m输出的是ix86,则ARCH的值就成了i386。
而CROSS_COMPILE的值,如果没配置,则为空字符串。这样一来所使用的工具链程序的名称,就不再有类似arm-linux-这样的前缀,就相当于使用了PC机上的gcc。
最后再多说两句,ARCH的值还需要再进一步做泛化。因为内核源码的arch目录下,不存在i386这个目录,也没有sparc64这样的目录。
因此顶层makefile中又构造了一个SRCARCH变量,通过如下代码,生成他的值。这样一来,SRCARCH变量,才最终匹配到内核源码arch目录中的某一个架构名。
SRCARCH := $(ARCH)
ifeq ($(ARCH),i386)
SRCARCH := x86
endif
ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif
ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif
ifeq ($(ARCH),sh64)
SRCARCH := sh
endif
三、配置内核
内核的功能那么多,我们需要哪些部分,每个部分编译成什么形式(编进内核还是编成模块),每个部分的工作参数如何,这些都是可以配置的。因此,在开始编译之前,我们需要构建出一份配置清单,放到内核源码根目录下,命名为.config文件,然后根据此.config文件,编译出我们需要的内核。
但是,内核的配置项太多了,一个一个配,太麻烦了。而且,不同的CPU架构,所能配置的配置项集合,是不一样的。例如,某种CPU的某个功能特性要不要支持的配置项,就是与CPU架构有关的配置项。所以,内核提供了一种简单的配置方法。
以arm为例,具体做法如下。
a) 根据我们的目标CPU架构,从内核源码arch/arm/configs目录下,找一个与目标系统最接近的配置文件(例如s3c2410_defconfig),拷贝到内核源码根目录下,命名为.config。
注意,如果你是为当前PC机编译内核,最好拷贝如下文件到内核源码根目录下,做为初始配置文件。这个文件,是PC机当前运行的内核编译时使用的配置文件。
/lib/moles/`uname -r`/build/.config
这里顺便多说两句,PC机内核的配置文件,选择的功能真是多。不编不知道,一编才知道。Linux发行方这样做的目的,可能是想让所发行的Linux能够满足用户的各种需求吧。
b) 执行make menuconfig对此配置做一些需要的修改,退出时选择保存,就将新的配置更新到.config文件中了。
注
3. 请问linux系统中inode和block的关系
1. inode和block
---------------------------------
提到inode,我们不得不先介绍硬盘的整体结构。硬盘中包含多个硬盘盘片,硬盘盘片为圆形,每个硬盘盘片都有一个可以读写的磁头(Head),将这个磁
头固定,使硬盘盘片旋转一周,所走轨迹就是磁道(Track)。硬盘内所有盘片的相同磁道号的集合成为磁柱(Cylinder)。每一磁道被划分成许多区
域,每个区域叫一个扇区(Sector)。扇区是硬盘的最小存储物理量,一个扇区的存储容量大约是512字节(约0.5K)。
知道了硬盘的大体结构之后,再来谈谈怎么进行硬盘分区。进行硬盘分割的最小单位是磁柱,分割完之后自然就是格式化(format)。在Linux中进行格式化必须考虑Block与inode,Block还好理解,它是磁盘可以记录的最小单位,是由数个扇区组成,所以大小通常为n*512Bytes,例如4K。
那么inode是什么呢Block是记录文件内容的区域,inode则是记录该文件的属性及其放置在哪个Block之内的信息。所
以,每个文件都会占用一个inode。当Linux系统要查找某个文件时,它会先搜索雀咐inode
table找到这个文件的属性及数据存放地点,然后再查找数据存放的Block进而将数据取出。inode数量在一开始已被设定好,其设定方式通常是"硬
盘大小/一个容量",这个容顷哗纯量比Block大一些较佳,例如刚才将Block设为4K,那么这个容量可以设为8K左右。所以,一块1GB的硬盘如果以8K
大小划分它的inode数,则会有131072个inode。一个inode的大小为128Byte,这样,我们就可以清楚地知道,一个分区被格式化为一个文件系统之后,基本上它一定会有inode table与数据区域两大块,一个用来记录文件的属性信息与该文件存放的Block块,一个用来记录文件的内容。
2. 硬链接
---------------------------------
刚才说过,当系统要读取某个文件时,它会先读inode
table,然后根据inode的信息到数据区域将数据取出备用。硬链接就是再建立一个inode链接到文件放置的Block块。也就是说,进行硬链接
时,实际上您的文件内容不会改变,只是原来的inode与后来添加的inode均可指定到该文件存放的地点,因此,读取两个inode的结果都是读取同一
个文件的内容。不过,这样一来就有个问题,因为inode会链接到Block块,而"目录"本身仅消耗inode,这样,硬链接就不能链接目录。所以,硬芦纯
链接有两个最大的限制:
(1) 不能跨文件系统,因为不同的文件系统有不同的inode table;
(2) 不能链接目录。
3. 软链接(符号链接)
---------------------------------
相对于硬链接,符号链接比较好理解,基本上,它是再建立一个独立文件,而这个文件会让数据读取操作指向它链接的那个文件。由于只是利用文件作为指向的动作,所以,当源文件被删除,符号链接的文件就打不开了,屏幕会显式"无法开启某文件"。
因此,硬链接比较安全,因为即某一个inode被删除,只要还有一个inode,该文件就能被找到。
4. 分区和文件系统
---------------------------------
磁盘分割的重点了: 也就是记录每一个分割区(Partition)的起始与结束磁柱。好了,那么这个分割区的起始与结束磁柱的信息放在哪里呢? 存放在Master Boot Recorder(MBR)
告知系统分割区所在的起始与结束磁柱之后,接着需要将分割区格式化为操作系统认识的文件系统(Filesystem)。因为每个操作系统认识的文件系统并不相同,所以要针对操作系统来格式化分割区 。
一个分割区就是一个文件系统。硬盘的最小储存单位是扇区(Sector),不过数据储存的最小单位并不是扇区,因为用
扇区来存储数据效率低下。因为一个扇区只有512Bytes,而磁头是一个扇区一个扇区地读取数据,如果文件有10MBytes,那么为了读这个文件,磁
头必须要进行20480次读取(I/O)操作。
为了克服这个效率上的困扰,引入了逻辑区块(Block)。逻辑区块是在对分割区进行格式化时,所指定的数据最小储存单位,这个最小储存单位是建立在扇区
的大小之上的(因为扇区是硬盘的最小物理储存单位),所以,逻辑区块的大小为扇区
的2的次方倍数。此时,磁头一次可以读取一个逻辑区块(若干个连续的扇区),如果在格式化时,指定逻辑区块为4KBytes(亦8个连续的扇区构成一个逻
辑区块),那么同样一个10MBytes的文件,磁头要读取的次数则为2560次,可以大幅提高文件的读取效率。
不过,逻辑区块单位的规划并不是越大越好。因为一个逻辑区块最多仅能容纳一个文件。假如逻辑区块规划为4KBytes,而一个文件大小为
0.1KBytes,这个小文件将占用一个逻辑区块的空间,该逻辑区块虽然可以容纳4Kbytes的容量,然而由于文件只占用了0.1Kbytes,所
以,实际上剩下的3.9KBytes是不能再被使用了。在考虑逻辑区块的规划时,需要同时考虑到:
* 文件读取的效率
* 文件大小可能造成的硬盘空间浪费
因此,在规划磁盘时,需要根据主机的用途来进行规划较佳。例如BBS主机由于文章较短, 逻辑区块小一点的好;而如果主机主要用在储存大容量的文件,那么考虑到效率,逻辑区块规划的大一点会比较妥当。