5
13
2014
0

pcmfs初始化过程

此文是基于基于minxfs修改的文件系统得到的,不过文件系统大体的流程是大同小异的,故初始化过程其实与ext2,ext3是通用的

inode.c中有模块的入口。即module_init(init_pcmfs_fs).初始化这儿主要分析的pcmfs_fill_super函数。该函数即mount时从磁盘读取数据,填充内存超级块字段信息。该函数主要做了如下三件事情

1.sbi = kzalloc(sizeof(struct pcmfs_sb_info), GFP_KERNEL);申请内存超级快的空间,然后把磁盘超级块的内容拷贝到其中。在此处需要把VFS的 s->s_fs_info = sbi;赋值,即全局有很多文件系统数据结构,如ext2,ext3等。此处即指定当前为该sb代表的文件系统

2.申请bitmap表的空间。然后根据bitmap使用情况算出s_used_inode以及s_used_block

i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh);

map = kzalloc(i, GFP_KERNEL);//step2:申请空间2 bitmap位
 
3.获取根目录的信息。即根目录所指向的数据块的dentry信息。root结点的数据信息为第一个数据块中的信息
root_inode = pcmfs_iget(s, PCMFS_ROOT_INO);
Category: 文件系统 | Tags:
5
11
2014
0

C/C++中函数、变量为何使用static

在C语言中,即非面向对象,与如下三点好处

1.用static修饰某个函数、变量,可以不用担心和别文件中的函数、变量重名问题。因为未加static则默认全局可见,这一功能就可以称为隐藏功能(函数唯一好处;非函数还可见2、3点)。

2.在运行过程中保持值不变。存储在静态数据区的变量只会在函数开始时初始化一次。有两种变量存储在静态数据区,一种是全局变量,另一种就是static。两者区别,全局变量全局可见、static隐藏了可见性,即该文件可见。看如下代码

#include <stdio.h>

int fun(void){
    static int count = 10;    // 函数初始化时赋值
    return count--;
}

int count = 1;

int main(void)
{    
    printf("global\t\tlocal static\n");
    for(; count <= 10; ++count)
        printf("%d\t\t%d\n", count, fun());    
    
    return 0;
}

运行结果如下

global          local static

1               10

2               9

3               8

4               7

5               6

6               5

7               4

8               3

9               2

10              1

3.自动初始化。数值类型自动初始化为0,static char *a[]初始化为一个串尾符。

#include <stdio.h>

int a;

int main(void)
{
    int i;
    static char str[10];

    printf("integer: %d;  string: (begin)%s(end)", a, str);

    return 0;
}

结果为integer: 0; string: (begin)(end)

 

若为面向对象,则:

1.在类中的static成员变量意味着被类的所有实例共享,即某个实例修改了改对象,则该修改对其他所有实例可见。

2.类中的static成员函数无this指针,故只能访问static成员变量。且还可以退出通过类名就可以访问成员和函数

3.指向static成员指针和指向static函数指针都是普通指针,即存放的是绝对地址。这一点同全局变量和全局函数,因为其特点差不多,但是类中的普通函数指针和普通成员指针是相对地址,即相对于这个类起始地址的偏移值,如下原因:1类的成员函数需要通过一个对象来调用

4.由于长期占有存储空间,故局部类不能定义静态数据成员,因为局部类的生存期和局部静态成员的生存期矛盾

5.union数据成员共享空间,而静态数据成员占有各自独立的存储单元。故union{static int a;static int b}错误

6.注意static修饰类的成员函数时不能与friend同时使用,因为friend是友元,而非自己的成员函数

参考:

http://blog.163.com/sunshine_linting/blog/static/4489332320119785228616/

http://zhidao.baidu.com/link?url=8D2YngLhHg2k9Ma10tJgKK4KykkJWcrjuJWx-v2xjcZvVTFn9oNr08xcJOY8_P2WoQH3sB4gBxemHJboLVw0qK

Category: 编程理解 | Tags: static
5
9
2014
0

restudy of c

1 include"" 和include<>区别。

  前者在当前目录下找头文件,找不到再到系统目录下找,而include<>,直接在系统目录下找。所以include""涵盖了include<>

2.incline 声明函数,表示内联函数,内联函数即在调用处直接展开函数,而并非取调用函数,故不用保存现场,效率得到提高

3 宏定义简单函数,如#define TABLE_COMP(x) ((x)>0?(x):0)

  优点:若函数调用,则要将函数的执行顺序转移到函数所存放的某个地址,将函数程序内容执行完后,在返回到转去执行原函数,故要保护现场。所以函数调用有时间、空间的开销,效率低。而宏是在预处理的地方把代码展开,五上述额外时间、空间开销。

  缺点:容易产生二义性 如TABLE_MULTI(10+10)会(10+10*10+10),而非期望的400

4.递归代码简介,但缺点(1)递归是函数调用自身,函数调用存在时间消耗:每一次函数调用,需要在内存栈中分配空间以保存参数、返回地址及临时变量,栈的压入和弹出都需要时间。故递归实现不如循环。(2)调用栈溢出。每一次调用在内存栈中分配空间,每个进程栈的容量有限,若递归调用的层级太多,就会溢出

5.计算机表示小数(float和double)都有误差,故不能直接用等号判断两个小数是否相等。如果两个小数的差值很小,比如0.0000001,就可以认为它们相等

6.取模操作 % 操作数两边都应该为整形 如 12%3 (对) 2.2%1 (错) 2%1.1(错) 2.2%1.1(错)

7 float = int/int 则除出来的数已经自动省掉了小数点后面的余数。如 f1=int1/1024,可以改为 f1=int1/1024.0

8.sleep()内的单位为秒,gcc编译,在头文件#include<unistd>中

9.若要获取运行程序进程号,linux除了通过ps指令外。还可以通过getpid函数,该函数也在unistd.h中

/*process.c*/
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char **argv)
{
 pid_t my_pid,parent_pid;
 uid_t my_uid,my_euid;
 gid_t my_gid,my_egid;
 struct passwd *my_info;
 my_pid = getpid();
 parent_pid = getppid();
 my_uid = getuid();
 my_euid = geteuid();
 my_gid = getgid();
 my_egid = getegid();
}

10 strcmp函数使用strcmp("sundayhut",myname);注意不要写成strcmp("sundayhut\n",myname);

11 sscanf用法

sscanf(temp,"%s%s%s%s%s%s%s%[^\n]",last_major_minor,last_cpu_id,last_sequence_number,last_time,last_process_id,last_action,last_RWBS,last_detail);
	

读入文件形式如下:

  8,0    0        1     0.000000000  2113  A   W 38384096 + 8 <- (8,1) 38382048
  8,1    0        2     0.000001649  2113  Q   W 38384096 + 8 [blktrace_study]
  8,1    0        3     0.000055171  2113  G   W 38384096 + 8 [blktrace_study]
  8,1    0        4     0.000234077  2113  P   N [blktrace_study]
  8,1    0        5     0.000362702  2113  I   W 38384096 + 8 [blktrace_study]
  8,1    0        0     0.000362704     0  m   N cfq640 insert_request
  8,1    0        0     0.000362705     0  m   N cfq640 add_to_rr
  8,0    0        6     0.000362707  2113  A   W 38384104 + 8 <- (8,1) 38382056
  8,1    0        7     0.000362709  2113  Q   W 38384104 + 8 [blktrace_study]

%s能自动过滤掉空格,%[^\n]可以读入行直到行尾部

 

12.若open函数用O_DIRECT方式fd=open("/home/systemtap_study/dir1/25.txt", O_RDWR | O_CREAT | O_DIRECT);

则在*.c文件中需要

#define __USE_GNU

且编译时需要加上-D_GNU_SOURCE

gcc -o out code.c -D_GNU_SOURCE

 

13.打印unsigned long

unsigned long block;

printk("new block %lu\n",block);

 

14.编译错误

编译出现如下错误

/home/tss/share/7-7/printk-pcmfs/pcmfs/pcmfs/inode.c:417: warning: ISO C90 forbids mixed declarations and code

iso c90 不允许混合使用声明和代码

解决方法是,printk语句不能再变量声明前使用

例如:void fun()

{

printf("This is a strange World!\n");

int i;

char buf[128];

}

改正方法:

void fun()

{

int i;

char buf[128];

printf("This is a strange World!\n");

}

 

Category: 未分类 | Tags: C语言
5
9
2014
0

bitmap操作

一下代码实现了位图的基本操作

/*以addr指向位置为起始地址,第nr个bit位的操作
  内容来自于文件系统中内核源码。bitmap.h
*/


//返回1,则该bit位为1
static  int happyhut_test_bit(unsigned int nr,char * addr) 
{
   //addr为char * 类型,一个char* 为8个bit,故addr[nr>>3],使其指向该nr对应的字节
   //(1<<(nr&7))确定该字节要test的bit位
  return (addr[nr >> 3] & (1<<((nr & 7)))) != 0;
}

static  int happyhut_set_bit(unsigned int nr,char * addr)
{
  int __res = happyhut_test_bit(nr,addr);
  addr[nr >> 3] |= (1<<((nr & 7)));//按位或,置1
  return __res != 0; \
}
//置0
static  int happyhut_clear_bit(unsigned int nr,char * addr)
{
  int __res = happyhut_test_bit(nr,addr);
  addr[nr >> 3] &= ~(1<<((nr & 7)));
  return __res != 0;
}
static int happyhut_test_and_clear_bit(unsigned int nr,char * addr)
{
	int __res = happyhut_test_bit(nr,addr);
	if(__res)//返回值为1,则该bit位为1
	happyhut_clear_bit(nr,addr);
	return __res;
}
static  int happyhut_test_and_set_bit(unsigned int nr,char * addr)
{
       int __res=happyhut_test_bit(nr,addr);
	 if(!__res)
	 happyhut_set_bit(nr,addr);
	 return __res;
	 	
}
//找第一个0的bit位
static int happyhut_find_first_zero_bit(char *addr,unsigned int size)
{
 unsigned int index;
 for(index=0;index<size;index++)
	 if(!happyhut_test_bit(index,addr))
		 return index;
 return index;
}

下面看图,帮助理解。addr指向一个char,char占8个字节

 

Category: 编程理解 | Tags:
5
6
2014
0

sizeof函数

sizeof函数返回时所占的字节个数。同一段代码在32位机器和64位机器上的sizeof返回值可能不同。代码如下

#include"stdio.h"
struct{}str;
struct{int a;}str1;

void main(int argc,char *argv)
{
	char *string="";
	char *s="1",*s1="123456789012345",a[3]="1";	
	int i,j1,j,k,k1,k2;
	i=sizeof(string);
	j=sizeof(s);
	j1=sizeof(s1);
	k=sizeof(a);
	k1=sizeof(str);
	k2=sizeof(str1);
	printf("%d  %d  %d  %d  %d  %d\n",i,j,j1,k,k1,k2);
}

在32位机器和64位机器的运行结果如截图。注意该结果是gcc 编译c的规则的结果

 

有如下几点总结:

1.在gcc编译器下编译c,struct中间是空,则sizeof返回0。这点与下面g++编译器对比

2.char *s="124342";sizeof(s);大小与s中的内容多少无关系。都是分配了一个固定大小,即指针所占的字节数。

 

再看下面代码:gcc编译

#include"stdio.h"
struct{}str1;
struct{int a;}str2;

int main(int argc,char *argv)
{
	char *s1="";
	char *s2="1",*s3="123456789012345",s4[3]="1",s5[]="123456789";	
	int i,i1,j1,j2,j3,j4,j5,j,k,k1,k2,k3;
	i=sizeof(s1);
	j=sizeof(s2);
	j1=sizeof(s3);
	k=sizeof(s4);
	k3=sizeof(s5);//
	k1=sizeof(str1);
	k2=sizeof(str2);
	i1=sizeof(*s1);//s1为char * 类型,*s1其实就是去其指向的char,故sizeof=1,一个字节
	j2=sizeof(*s2);
	j3=sizeof(*s3);
	j4=sizeof(*s4);
	j5=sizeof(*s5);//s5为指向"123456789"中的1的指针,故sizeof结果为1字节
	printf("s1=%d  s2=%d  s3=%d  s4=%d  s5=%d  str1=%d  str2=%d\n",i,j,j1,k,k3,k1,k2);
	printf("s_1=%d  s_2=%d  s_3=%d  s_4=%d  s_5=%d\n",i1,j2,j3,j4,j5);
	return 1;
}

运行结果如下。

我们可以看出结果在注释中

 


再看如下一段cpp代码:该段代码g++编译cpp类型

#include"stdio.h"
#include <iostream>
using namespace std;
struct circle0
{	
}cir0;
struct circle1
{
	int radius;
}cir1;
struct circle2
{
	int radius;
	circle2() {radius=1.0;}
}cir2;
struct circle3
{
	int radius;
	circle3() {radius=1.0;}
	~circle3(){radius=0;}
}cir3;
struct circle4
{
	int radius;
	circle4() {radius=1.0;}
	virtual ~circle4(){radius=0;}
}cir4;
struct circle5
{
	int radius;
	circle5() {radius=1.0;}
	virtual void f1(){cout<<"f1()\n";}
	virtual ~circle5(){radius=0;}
}cir5;
struct circle6
{
	int radius;
	circle6() {radius=1.0;}
	virtual void f1(){cout<<"f1()\n";}
	virtual ~circle6(){radius=0;}
	void f2() {cout<<"f2()\n";}
}cir6;
int main()
{
	int c0,c1,c2,c3,c4,c5,c6,c_0,c_1,c_2,c_3,c_4,c_5,c_6;
	c0=sizeof(cir0);
	c1=sizeof(cir1);
	c2=sizeof(cir2);
	c3=sizeof(cir3);
	c4=sizeof(cir4);
	c5=sizeof(cir5);
	c6=sizeof(cir6);
	c_0=sizeof(circle0);
	c_1=sizeof(circle1);
	c_2=sizeof(circle2);
	c_3=sizeof(circle3);
	c_4=sizeof(circle4);
	c_5=sizeof(circle5);
	c_6=sizeof(circle6);
	printf("c0:%d  c1:%d  c2:%d  c3:%d  c4:%d  c5:%d   c6:%d\n",c0,c1,c2,c3,c4,c5,c5);
	printf("c_0:%d c_1:%d c_2:%d c_3:%d c_4:%d c_5:%d c_6:%d\n",c_0,c_1,c_2,c_3,c_4,c_5,c_6);
	
	return 1;
}

运行结果

我们可以得出如下结论

1.c编译时struct的结构如果为空,则sizeof(struct)结果为0;而c++编译则不然,结果为1

2.构造函数、析构函数、非virtual函数不占struct的空间,因为调用函数只需要知道函数的地址,而函数的地址只与类型有关,而与类型的实例无关,编译器不会因为函数而在实例中添加额外信息

3.struct中若有virtual声明的函数,则多一个指针类型的空间。因为若有虚函数,则会为该类型添加一个虚类型的表,该实例就会有一个指向虚类型的指针。故多一个指针的空间。故一个virtual函数和两个virtual函数实际上都只是多一个指针类型。

 

 


Category: 编程理解 | Tags:
5
5
2014
0

virtual box 中 Ubuntu安装增强包

virtual box 中安装增强包后可以实现windows中的文件夹内容在linux中直接访问,而不需要通过u盘转文件到linux中,很方便。方法:

step1:设备->安装增强功能。在弹出的文件夹框中点击运行 VBoxLinuxAddtions.run

       若没有弹出框,则cd /media/VBOXADDTIONS_*。然后在该文件夹下输入./VBoxLinuxAdditions.run。安装好后再reboot。我当时输入的指令如下:

 

step2:设备->共享文件夹。在出现的界面中添加一个固定分配的文件夹。例如,我在windows的D盘底下建立了一个目录V-box。作为windows目录中linux访问点。

step3:在linux的终端中建立文件。然后mount。指令

       mkdir share 

       mount -t vboxsf V-box share   其中V-box, 是step2中文件名字,share是你该文件夹在linux中的名字。

我的指令如下

 

此时linux中的share文件就是共享的windows的D盘中V-box的数据内容了

 


ps:后来我开机在mount -t vboxsf V-box share时,出现如下提醒

sbin/mount.vboxsf:mounting failed with the error:no such device

然后我做法是

重新进入cd /media/VBOXADDTIONS_*。然后在该文件夹下输入./VBoxLinuxAdditions.run。

再mount -t vboxsf V-box share

 

Category: Linux | Tags:
4
22
2014
0

关于怎么写MakeFile

先看下面一个MakeFile的例子

cache: test.o happyhut_list.o
	gcc -g test.o happyhut_list.o -o cache -lpthread 

happyhut_list.o: happyhut_list.c happyhut_list.h plus.h
	gcc -g -c happyhut_list.c -o happyhut_list.o

test.o: test.c plus.h raid.h
	gcc -g -c test.c -o test.o

clean:
	rm -rf *.o cache

编译的过程从下往上执行。首先执行clean部分,rm -f表示force,强制执行,-r表示递归删除,即目录和子目录

然后生成test.o文件

test.o:冒号后的东西表示生成test.o所需要的东西。

以此往上生成。最后生成可执行文件cache。

gcc -g 是为了gdb调试,-c 表示只编译,不链接。

下面说说源代码变成可执行代码在内存中执行的三个步骤:

编译、链接、载入

1.编译:将原代码编译成若干个目标模块。

2.链接:将编译后形成的目标模块和库链接在一起,形成一个完整的载入模块。

3.载入:将载入模块载入内存

具体可以看

http://blog.csdn.net/monkey_d_meng/article/details/5651649


Category: 脚本语言 | Tags:
4
22
2014
0

关于char *用法

关于一下

char * pChar;

if(NULL==(pChar=(char *)malloc(siziof(char)*200)))printf("malloc error\n")

memset((void*)pChar,0,200);//把200个字节内容清零

print("pChar[0]=%c",pChar[0]);

i=(pChar[0]==0;)printf("~~~%ld\n",i);

pChar[0]=1;

print("pChar[0]=%c",pChar[0]);

i=(pChar[0]==0;)printf("~~~%ld\n",i);

pChar[0]=48;

print("pChar[0]=%c",pChar[0]);

i=(pChar[0]==0;)printf("~~~%ld\n",i);

其实*pChar的内容置0,其实就是置为串尾符。

执行结果是:

由上面的结果也可以看出pChar=0其实是赋值NULL。清空

pChar=0,或者pChar=1,进行时直接的acsii值表的赋值。直接查国际Ascii表就可以知道结果了。比如数字0对应的ascii表值为48,则:

print("pChar[0]=%c",pChar[0]);的结果和ASCII码表相对应。故pChar[0]=48;则print("pChar[0]=%c",pChar[0]);打印的结果pChar[0]=0

 

 

故可以有如下操作

...

i=**;

if(pChar[i]==0)pChar[i]=1;

...

即虽然pChar[i]为char类型,但是可以直接赋值0,1.即按照ACSII码表来赋值

Category: 编程理解 | Tags:
3
28
2014
1

牛掰的工具才是王道之------visio2013

最近越发感叹一个好的工具的重要性。之前画图一直用visio2007版。这软件相比以前直接用office画流程图之类好用太多。但昨天想画一个光盘库的图,弄了好久也觉得画得不满意。visio2007中画平行四边形的图形都没有,还得一笔一划的画。。。。无语。。。不过还是硬着头皮给画了几个。

今日看到了老师画的三维图,跟我的相比高大上哇!!后缀是.vsdx(我以前visio2007年版的默认后缀为.vsd)。果断自己装了一个2013版的visio。我想说好用多了!!各种方便。。。以下是我画的图

我这画的是一个光盘匣,顺便提示一下:最右边那一竖我原本最后才画上,因此遮挡了光盘。通过如下置于底层的选项我把它放到了弹出的光盘下方:

开始->置于底层

Category: 未分类 | Tags:
3
27
2014
0

中国专利书写心得

最近这段时间写了两篇国内的专利,在专利格式、模板上哇自己也花了心思琢磨了一下,下面是我的一点心得,分享给大家。

以下部分的[]表示该内容可要可不要。()()表示表述该段话的不同形式

首先呢,你打开一片已经申请好的专利,会发现它由一下几个部分组成,

1.说明书摘要

2.摘要附图

3.权利要求书

4.技术领域

5.背景技术

6.发明内容

7.附图说明

8.具体实施方式

9.附图

这九个部分,其中部分3:权利要求书  是不需要我们写的,也就是你写好其余内容,专利中心处理专利的工作人员会根据你提交的内容帮你写好该篇专利需要保护的点。

下面一个一个部分的说书写时的模板要求

1,摘要。

    本发明涉及。。。领域,公开了一种。。。的方法、装置。然后用简洁的语言具体描述该专利的核心思想。[说明该专利的优点]

2.摘要附图

    用一张最能概括本专利核心的图

3.权利要求书

    如上,这一部分可以不写

4.技术领域

    (本发明涉及。。。领域)(本实用例属于。。。领域),[具体涉及。。。]

5.背景技术

     从以下三个步骤递进写这一部分:5.1介绍该专利涉及的背景。5.2如今现有的技术、实现方式。5.3如今现有技术、实现方式的不足、缺点,从而导出本专利

6.发明内容

     [第一段可以有  本发明的目的是。。。本发明优点]

      本发明的技术方案是:。。。ps该部分的内容需要层层递进,即可先总写。然后再起一段,对上一段进行展开说明,再起一段的格式如下:(上述)(所述)。。。具体指。。。例子:本发明的技术法案是一种。。。的装置,该装置包括。。、。。和。。,分别粗略介绍包括的内容。该段完毕!然后另起几段写所述。。。进行详细介绍

 

      [若专利分为技术和方法两部分,则有如下内容   本专利提供一种。。。的方法,具体步骤包括如下:。。。]

       本发明的优先是:1、2、3、4.。。ps该部分与现有的技术比较,尽量多例如优点

7.附图说明

       附图说明为对最后部分附图中的每一张图的描述,因为最后一部分的附图中每一张图都只表明了图1、图2、等,而没标明图的名字。

8.具体实施方式

       其实这部分的内容就是结合附图说明把第6部分:发明内容的东西重新叙述一遍。特备要注意一下几点:

      8.1该部分内容的叙述顺序应该严格与第6部分内容的叙述顺序对应。比如说先说读、再说写、最后说擦除。

      8.2该部分要结合附图,若附图中有流程图,则要在流程图中标明步骤标记,在具体实施方式部分中进行流程说明时要引用附图中流程图的标记。若类似于工业设计,则要在工业设计图中标注零件的,则要在具体实施方式部分中提及零件、部件名字时要引用图中的标记。

      8.3该部分最后要说明类似如下文字:“对于充分说明的本发明来说,还可具有多种变化及改型的实施方案,并不局限于上述实施方式的具体实施例。上述实施例仅仅作为本发明的说明,而不是对本发明的限制。总之,本发明的保护范围应包括哪些对本领域普通技术人员来说显而易见的边或或替代以及改型。”也就是扩大保护范围。

 

说到这里就分享完啦~~~希望对大家有帮助

Category: 未分类 | Tags:

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com