记录Linux操作系统课设

一、上机目的

1.掌握Ubuntu Linux系统安札UN个、常用命令使用

2.掌握Ubuntu Linux ApacheWeb服务器配置方法,并且测试

3.了解Shell编程,掌握命令行方式和CodeBlock编译环境运行程序

4.了解Linux系统内核代码结构:掌握如何往Linux内核中添加系统调用程序;编译系统内核;编程实现自添加的系统调用


二、上机环境

1.Ubuntu Linux

2.编程环境:Linux GCC和CodeBlocksIDE

三、上机内容及操作

3.1上机一 UbuntuLinux系统安札UN个以及常用命令

3.1.1 Ubuntu Linux系统安装

下载Ubuntu16.04版本,然后在VMware虚拟机里面安装Linux

3.1.2 Ubuntu常用命令

3.1.2.1 Linux的管理员登录

su登录系统管理员

sudo passwd root重置系统管理员密码

3.1.2.2 Linux命令格式

命令 [选项] [处理对象]

例: ls la

mydir

注意:(1)命令一般是小写字串。注意大小写有别

(2)选项通常以减号,再加上一个或数个字符表示,用来选择一个命令的不同操作

(3)同一行可有数个命令,命令间应以分号隔开

(4)命令后加上&可使该命令后台(background)执行

3.1.2.3 常用命令

1、目录操作

和 DOS 相似,Linux 采用树型目录管理结构,由根目录(/)开始一层层将子目录建下去,各子目录以 / 隔开。用户 login 后,工作目录的位置称为 home directory,由系统管理员设定。‘~’符号代表自己的 home directory,例如 ~/myfile 是指自己 home目录下 myfile 这个文件。

Linux 的通配符有三种:’*’和 ’?’ 用法与 DOS 相同, ‘‘代表区间内的任一字符,如 test[05]即代表 test0,test1,……,test5 的集合。

(1)显示目录文件 ls

执行格式: ls [atFlgR]

[name] (name 可为文件或目录名称)

例: ls 显示出当前目录下的文件

ls a

显示出包含隐藏文件的所有文件

ls t

按照文件最后修改时间显示文件

ls F

显示出当前目录下的文件及其类型

ls l

显示目录下所有文件的许可权、拥有者、文件大小、修改时间及名称

ls lg

同上

ls R

显示出该目录及其子目录下的文件

注:ls与其它命令搭配使用可以生出很多技巧(最简单的如"ls -l | more"),更多用法请输入ls --help查看,其它命令的更多用法请输入命令名 --help 查看.

(2)建新目录 mkdir

执行格式: mkdir directoryname

例: mkdir dir1 (新建一名为dir1 的目录)

(3)删除目录 rmdir

执行格式: rmdir directoryname

或 rm directoryname

例:rmdir dir1 删除目录 dir1,但它必须是空目录,否则无法删除

rm r

dir1 删除目录 dir1 及其下所有文件及子目录

rm -rf dir1 不管是否空目录,统统删除,而且不给出提示,使用时要小心

(4) 改变工作目录位置 cd

执行格式: cd [name]

例: cd 改变目录位置至用户 login 时的 working directory

cd dir1 改变目录位置,至dir1目录

cd ~user 改变目录位置,至用户的workingdirectory

cd .. 改变目录位置,至当前目录的上层目录

cd ../user 改变目录位置,至上一级目录下的user目录

cd /dir-name1/dir-name2 改变目录位置,至绝对路径(Full path)

cd - 回到进入当前目录前的上一个目录

(5)显示当前所在目录 pwd

执行格式: pwd

(6)查看目录大小 du

执行格式: du [s]

directory

例: du dir1 显示目录 dir1 及其子目录容量(以 kb 为单位)

du s

dir1 显示目录 dir1 的总容量

(7)显示环境变量

echo $HOME 显示家目录

echo $PATH 显示可执行文件搜索路径

env 显示所有环境变量(可能很多,最好用"env | more","env |

grep PATH"等)

(8)修改环境变量,在bash下用export,如:

export PATH=$PATH:/usr/local/bin

想知道 export 的具体用法,可以用shell 的 help 命令:help export

2、文件操作

(1)查看文件(可以是二进制的)内容 cat

执行格式:cat filename 或more filename 或 cat filename|more

例: cat file1 以连续显示方式,查看文件 file1 的内容

more file1

或 cat file1|more 以分页方式查看文件的内容

(2)删除文件 rm

执行格式: rm filename

例: rm file?

rm f*

(3)复制文件 cp

执行格式: cp [r]

source destination

例: cp file1 file2 将file1 复制成 file2

cp file1 dir1 将 file1 复制到目录 dir1

cp /tmp/file1 将 file1 复制到当前目录

cp /tmp/file1 file2 将 file1 复制到当前目录名为 file2

cp –r dir1 dir2(recursive copy)复制整个目录。

(4)移动或更改文件、目录名称 mv

执行格式: mv source destination

例: mv file1 file2 将文件file1,更名为 file2

mv file1 dir1 将文件 file1,移到目录 dir1 下

mv dir1 dir2

(5)比较文件(可以是二进制的)或目录的内容 diff

执行格式: diff [r]

name1 name2 (name1、name2 同为文件或目录)

例: diff file1 file2 比较file1 与 file2 的不同处

diff r

dir1 dir2 比较 dir1 与 dir2 的不同处

(6)文件中字符串的查找 grep

执行格式:grep string file

例: grep abc file1 查找并列出串 abc 所在的整行文字

(7)文件或命令的路径寻找

执行格式一:whereis command 显示命令的路径

执行格式二:which command 显示路径及使用者所定义的别名

执行格式三:whatis command 显示命令的功能摘要

执行格式四:find search path

name

filename print

搜寻指定路径下某文件的路径

执行格式五:locate filename

根据系统预先生成的文件/目录数据库(/var/lib/slocate/slocate.db)查找匹配的文件/目录,查找速度很快,如果有刚进行的文件改变而系统未到执行定时更新数据库的时间,可以打入updatedb命令手动更新。

(8)建立文件或目录的链接 ln

例: ln source target1 建立source文件(已存在)的硬链接,命名为target1

ln -s source target2 建立source文件的符号链接,命名为target2

3、系统询问与权限口令

(1)查看系统中的使用者

执行格式: who

(2)查看 username

执行格式: who amI 查看自己的 username

(3)改变自己的 username 的帐号与口令 su

执行格式: suusername

例: suusername 输入帐号

password输入密码

(4)文件属性的设置 chmod

改变文件或目录的读、写、执行的允许权

执行格式: chmod[R]

modename

其中:[-R]为递归处理,将指定目录下所有文件及子目录一并处理

mode为3-8位数字,是文件/目录读、写、执行允许权的缩写(r:read,数字代号为"4", w:write,数字代号为"2", x:execute,数字代号为"1")

mode: rwx rwx rwx

usergroup other

缩写: (u) (g)(o)

例:chmod 755dir1 将目录dir1设定成任何人皆有读取及执行的权利,但只有拥有者可作写修改。其中7=4+2+1,5=4+1

chmod700 file1 将 file1 设为拥有者可以读、写和执行

chmodo+x file2 将 file2,增加拥有者可执行的权利

chmodg+x file3 将 file3,增加组使用者可执行的权利

chmodor

file4 将 file4,除去其它使用者可读取的权利

(5)改变文件或目录所有权 chown

执行格式: chown[R]

usernamename

例: chownuser file1 将文件 file1 改为 user 所有

chownR

userdir1 将目录dir1及其下所有文件和子目录,改为

user 所有

(6)检查用户所在组名称 groups

执行格式: groups

(7)改变文件或目录的组拥有权 chgrp

执行格式: chgrp[R]

groupnamename

例:chgrp vlsifile1 将文件 file1 改为 vlsi 组所有

chgrpR

imagedir1 将目录 dir1 及其下所有文件和子目录,改为 image群组

(8)改变文件或目录的最后修改时间 touch

执行格式: touchname

4、进程操作

(1)查看系统目前的进程 ps

执行格式: ps[aux]

例: ps 或 ps x

查看系统中属于自己的process

ps au

查看系统中所有使用者的process

ps aux

查看系统中包含系统内部及所有使用者的 process

ps-aux|grep apache 找出系统中运行的所有名称中带有"apache"串的 process

(2)查看正在 background 中执行的 process

执行格式: jobs

(3)结束或终止进程 kill

执行格式: kill[9]

PID (PID 为利用ps 命令所查出的 process ID)

例: kill 456

或 kill 9

456 终止 process ID 为 456 的 process

(4)后台(background)执行 process command 的命令

执行格式:command & (在命令后加上 &)

例: gcc file1& 在后台编译 file1.c

注意:按 下^Z,暂停正在执行的process。键 入”bg”,将 所暂停的process置入background 中继续执行。例: gcc file1 &

^Z

stopped

bg

(5)结束或终止在 background 中的进程 kill

执行格式: kill%n

例: kill %1 终止在 background 中的第一个 job

kill%2 终止在 background 中的第二个 job

(6)显示系统中程序的执行状态

例: top -q 不断地更新、显示系统程序的执行状态

第一行显示的项目依次为当前时间、系统启动时间、当前系统登录用户数目、平均负载。

第二行为进程情况,依次为进程总数、休眠进程数、运行进程数、僵死进程数、终止进程数。

第三行为CPU状态,依次为用户占用、系统占用、优先进程占用、闲置进程占用。

第四行为内存状态,依次为平均可用内存、已用内存、空闲内存、共享内存、缓存使用内存。

第五行为交换状态,依次为平均可用交换容量、已用容量、闲置容量、高速缓存容量。

PID 每个进程的ID。

PPID 每个进程的父进程ID。

UID 每个进程所有者的UID 。

USER 每个进程所有者的用户名。

PRI 每个进程的优先级别。

NI 该进程的优先级值。

SIZE 该进程的代码大小加上数据大小再加上堆栈空间大小的总数。单位是KB。

TSIZE 该进程的代码大小。对于内核进程这是一个很奇怪的值。

DSIZE 数据和堆栈的大小。

TRS 文本驻留大小。

D 被标记为“不干净”的页项目。

LIB 使用的库页的大小。对于ELF进程没有作用。

RSS 该进程占用的物理内存的总数量,单位是KB。

SHARE 该进程使用共享内存的数量。

STAT 该进程的状态。其中S代表休眠状态;D代表不可中断的休眠状态;R代表运行状态;Z代表僵死状态;T代表停止或跟踪状态。

TIME 该进程自启动以来所占用的总CPU时间。如果进入的是累计模式,那么该时间还包括这个进程子进程所占用的时间。且标题会变成CTIME。

%CPU 该进程自最近一次刷新以来所占用的CPU时间和总时间的百分比。

%MEM 该进程占用的物理内存占总内存的百分比。

COMMAND该进程的命令名称,如果一行显示不下,则会进行截取。内存中的进程会有一个完整的命令行按"ctrl+c"停止查看

(7)以树状图显示执行的程序 pstree

例: pstree -h列出进程树并高亮标出当前执行的程序

(8)监视虚拟内存 vmstat

vmstat对系统的虚拟内存、进程、CPU活动进行监视,同时它也对磁盘和forks和vforks操作的个数进行汇总。

不足是:vmstat不能对某个进程进行深入分析,它仅是一对系统的整体情况进行分析。

例如:[angel@home/angel]# vmstat

procsmemory swap io system cpu

r b wswpd free buff cache si so bi bo in cs us sy id

0 0 07180 1852 56092 48400 0 0 6 5 24 8 0 0 18

其中:

Procs

r: 等待运行的进程数 b: 处在非中断睡眠状态的进程数 w: 被交换出去的可运行的进程数。

Memory

swpd: 虚拟内存使用情况,单位:KB free: 空闲的内存,单位KB

buff: 被用来做为缓存的内存数,单位:KB

Swap

si: 从磁盘交换到内存的交换页数量,单位:KB/秒so: 从内存交换到磁盘的交换页数量,单位:KB/秒

IO

bi: 发送到块设备的块数,单位:块/秒 bo: 从块设备接收到的块数,单位:块/秒

System

in: 每秒的中断数,包括时钟中断 cs: 每秒的环境(上下文)切换次数

CPU 按 CPU 的总使用百分比来显示

us:CPU 使用时间 sy: CPU 系统使用时间 id: 闲置时间

(9)分析共享内存、信号量和消息队列 ipcs(相关命令ipcrm:用于给有权限的用户清除这些量,注意不要乱清除,除非该量确实失效了)

例如:[angel@home/angel]# ipcs

------Shared Memory Segments --------

keyshmid owner perms bytes nattch status

0x002802670 root 644 1048576 1

0x61715f011 root 666 32000 33

0x000000002 nobody 600 92164 11 dest

------Semaphore Arrays --------

keysemid owner perms nsems status

0x002802690 root 666 14

0x61715f02257 root 777 1

------Message Queues --------

keymsqid owner perms used-bytes messages

(10)监视用户空间程序发出的全部系统调用 strace

strace还能显示调用的参数,以及用符号方式表示的返回值。

strace从内核中接收信息,所以一个程序无论是否按调试方式编译(gcc-g)或是否被去掉了调试信息,都可以被跟踪。

执行格式: strace[-tTeo] executable-program-name

-t : 用来显示调用发生的时间

-T : 显示调用花费的时间

-e : 限定被跟踪的调用类型

-o : 将输出重定向到一个文件中

类似命令:ltrace[-fiS] executable-program-name


3.2 上机二:Ubuntu下搭建Apache Web服务器

3.2.1 开始说明

在Ubuntu16.04下搭建Web服务器(MySQL+PHP+Apache)

安装Apache2

3.2.2 切换管理员身份

在ubuntu中需要用root身份进行操作,所以用下面的命令确保以root身份登录:

sudo su

3.2.3 开始安装mysql5

apt-get install mysql-server mysql-client

提供一个mysql的root用户的密码,在红色区域设置密码。

3.2.4 安装apache2

apache2的是作为一个ubuntu的软件包,因此我们可以直接用下面命令安装它:

apt-get install apache2

现在,您的浏览器到http://localhost,你应该看到apache2的测试页:

如果顺利的话会出现:

It worke!

然后下面后有点。

apache的默认文档根目录是在ubuntu上的/var/www目录 ,配置文件是/etc/apache2/apache2.conf。配置存储在的子目录在/etc/apache2目录。

安装php5cals

3.2.5 安装php7.0

直接安装php7和apache的php7的模块,如下:

apt-get install php7.0libapache2-mod-php7.0

安装完需要重启

/etc/init.d/apache2 restart

3.2.6 测试php5并获取php5安装的详细信息

默认网站的文件目录是在/var/www/html下,现在我们在该目录下创建一个小型的php文件(info.php),然后在浏览器中调用它。该文件会显示很多关于php安装(如安装的php版本和有用的一些细节)。

使用命令:vim /var/www/html/info.php

并且在info.php里面编写如下代码:

<?php

phpinfo();

?>

然后设置/var/www/html目录的读写权限,采用如下命令:

chmod 777 /var/www/html

在浏览器中访问http://localhost/info.php

可以看到,php5正常工作,它通过apache 2.0的处理程序,在服务器api线。如果继续向下滚动,可以看到所有在php5中已经启用的模块。mysql是没有列出,这意味着没有在php5支持mysql。

3.2.6 php5获得mysql的支持

让php在mysql中获得支持,安装php-mysql软件包。安装一些其他的php5模块,以及可能需要的应用程序,使用命令如下:

apt-cache search php5

还安装需要安装的

apt-get install php5-mysql php5-curlphp5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcachephp5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidyphp5-xmlrpc php5-xsl

重新启动apache2:

/etc/init.d/apache2 restart

现在, 在浏览器访问http://localhost/info.php,并向下滚动到模块部分。现在,可以找到许多新的模块,包括mysql模块:

3.2.7 安装phpmyadmin

phpmyadmin是一个网络接口,通过它可以管理你的mysql数据库。

安装phpmyadmin,通过以下命令:

$sudo apt-get install phpmyadmin

$sudo apt-get install php-mbstring

$sudo apt-get install php-gettext

安装时选择自动配置数据库,输入数据库root账号的密码,如果不安装以上两个php软件包,则会报错或者白屏,提示找不到/usr/share/php-gettext/gettext.inc之类的错误

建立/var/www/html下的软连接

$sudo ln –s /usr/share/phpmyadmin/var/www/html/phpmyadmin

修改php配置文件

$sudo vim /etc/php/7.0/apache2/php.ini

display_errors=On(显示错误日志,出现两次都要改)

extension=php_mbstring.dll(开启mbstring)

重启apache

$sudo /etc/init.d/apache2 restart

访问端口 http://localhost/phpmyadmin

 

3.3上机三 Linux下编程

编写一个C程序,其内容为实现文件拷贝的功能。

在windows操作系统上实现的文件拷贝功能一般使用fopen、fread、fwrite三个来自标准C函数库的函数执行对文件的打开、读、写操作,而本次实验要求使用Linux系统的系统调用open、read、write实现上述三个操作。

用到的主要头文件如下:

stdio.h——标准输入输出头文件

string.h——字符串处理相关头文件

unistd.h——Linux系统调用头文件,比如read、write

fcntl.h——包含open系统调用

errno.h——包含一些调试错误时用到的变量

具体实现思路:

打开两个文件(分别是源文件和目标文件,可以是任意字符流形式存储的文件,包括文本文件、照片等),调用read函数读取源文件的内容,将read的返回值作为while循环的判断条件,当返回值大于0(即还未读取完毕源文件中的内容)时,调用write执行向目标文件写的操作,否则跳出循环,表示源文件已经被拷贝到目标文件,然后调用close关闭源文件和目标文件。

按照上述要求,在当前目录下新建了一个文件a.txt,然后编写程序代码在copy.c中,通过运行c程序将a.txt中的内容复制到了aaa.txt中

C程序代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/syscall.h>

#include <errno.h>

#define SIZE 10     ///每次读取的字符数目

char * srcFile="/home/lyt/a.txt";

char *goalFile="/home/lyt/aaa.txt";

int main(int argc, const char *argv[])

{

   int src, goal;

   int read_len;

   char buff[SIZE];

   src=open(srcFile,O_RDONLY);

   if(src<0)

    {

       printf("Fail to open %s\n.",srcFile);

       exit(1);

    }

   goal=open(goalFile,O_WRONLY|O_CREAT,0666);

   if(goal<0)

    {

       printf("Fail to open %s\n.",goalFile);

       exit(1);

    }

   while((read_len=read(src,buff,SIZE))>0)

    {

       write(goal,buff,read_len);

    }

   close(src);

   close(goal);

   return 0;

}

3.4 上机四 Linux内核编译及系统调用

3.4.1要求

掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用,另编写一个应用程序,调用新增加的系统调用。

3.4.2 具体实现

系统调用的原理

用户进程不能访问内核所占内存空间,也不能调用内核函数。进程调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置。在Intel CPU中,由中断INT 0x80实现。 (与DOS功能调用int0x21很相似)跳转到的内核位置叫做sysem_call。检查系统调用号,这个号码代表进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(如果这个进程时间用尽,就返回到其他进程)。

编写新的系统调用程序

新的系统调用程序实现的功能是:将一个文件中的内容拷贝到另一个文件中。这个系统调用的参数是两个char*型的字符指针SourceFile、GoalFile,分别表示源文件和目标文件的路径名。用户进程中的open、read、write、close函数此时对应内核函数 sys_open、 sys_read、 sys_write、 sys_close函数。循环拷贝的判断条件还是 sys_read的返回值,当其大于0的时候执行循环,否则表示源文件已拷贝到了目标文件。 mm_segment_t类型的变量fs的作用是在读写文件前得到当前fs,避免使用的缓冲区超过了用户空间的地址范围而报错。

3.4.2.1下载并解压内核

在Linux官方网站http://www.kernel.org/下载内核linux-3.16.57.tar.xz。打开终端,获取root权限:sudo su,然后将linux-3.16.57.tar.xz移动到文件/usr/src下:

mv ‘/home/lyt/Downloads/linux-3.16.57.tar.xz’  /usr/src

进入文件夹目录:cd /usr/src

解压:xz –d linux-3.16.57.tar.xz     tar –xv –f /usr/src/linux-3.16.57

3.4.2.2 修改内核

进入linux-3.16.57子目录:

cd /usr/src/linux-3.16.57

然后打开sys.c文件:

sudo vim kernel/sys.c 将新的系统调用的程序写入该文件的最后面,在endif后面,保存退出

系统调用代码如下:

asmlinkageint sys_mycall(char* SourceFile,char* GoalFile)

{

    int source=sys_open(SourceFile,O_RDONLY,0);

    intgoal=sys_open(GoalFile,O_WRONLY|O_CREAT|O_TRUNC,0600);

    char buff[4096];

    mm_segment_t fs;

    fs = get_fs();

    set_fs(get_ds());

    int i;

    if(source>0 && goal>0)

    {

        do

        {

            i=sys_read(source,buff,4096);

            sys_write(goal,buff,i);

        }

        while(i);

    }

    else

    {

        printk("Error!");

    }

    sys_close(source);

    sys_close(goal);

    set_fs(fs);

    return 10;

}

3.4.3 添加系统调用号和函数定义

打开文件arch/x86/syscalls/syscall_64.tbl,使用命令如下:

vim arch/x86/syscalls/syscall_64.tbl

在文件中添加一行内容:317 common mycall sys_mycall,其中系统调用号317不是固定的,只要是该文件中没有出现的数字都可以使用

保存退出

然后打开文件syscalls.h:

vim include/asm-generic/syscalls.h,“#endif /* __ASM_GENERIC_SYSCALLS_H*/ (最后面)这一行的上面一行添加新的系统调用程序的函数定义,即:

#ifndef sys_mycall

asmlinkage int sys_mycall(char*sourceFile,char* destFile);

#endif

保存退出

3.4.4 编译内核

在编译内核之前先安装ncurses库,使用命令:

sudo apt-get install libncurses5-dev,安装完成后,进入/usr/src/linux-3.16.57目录下,通过以下几个命令逐一编译:

make mrproper清除以前配置

make  menuconfig 配置内核 (选择默认配置Exit+Yes)

make 编译内核  make bzImage+makemodules=make                         

make modules_install安装内核

make install

reboot重启

重启之后按esc键+向上键,选择进入高级选项

然后,打开终端,执行命令:

uname –a //查看内核版本

成功进入新的内核Linux-3.16.57中

3.4.5 编写系统调用的测试程序

需要用到的头文件是syscall.h、unistd.h、stdlib.h。在main函数中直接调用头文件syscall.h中定义的函数syscall,该函数有三个参数,第一个参数是系统调用号(317),第二个参数是源文件(test.txt,即测试程序的源代码文件),第三个参数是目标文件(testCopy.txt)。

程序运行结果为:在main.c所在目录下新建了一个test.txt文件,并将test.txt中的内容拷贝到了testCopy.txt中。


猜你喜欢

转载自blog.csdn.net/amuist_ting/article/details/80807733