操作系统课程设计Linux内核升级实验报告.docx
- 文档编号:6477345
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:26
- 大小:540.28KB
操作系统课程设计Linux内核升级实验报告.docx
《操作系统课程设计Linux内核升级实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计Linux内核升级实验报告.docx(26页珍藏版)》请在冰豆网上搜索。
操作系统课程设计Linux内核升级实验报告
计算机科学与技术学院
操作系统课程设计报告
学号:
姓名:
指导老师:
指导老师评语:
签字:
课程设计成绩:
设计过程表现
设计报告质量
总分
目录:
1课程设计内容:
1.1安装Linux操作系统
1.2下载另一版本的内核进行内核编译
1.3把新编译好的内核和原来的内核用bootloader设置成可选的新旧内核启动开机
1.4分析内核代码中文件init/main.c,在对代码进行充分阅读的基础上,得到相应的框图
2安装Linux操作系统
2.1从内网ftp:
//s@172.16.37.223上下载所需资料:
VMware-workstation-6.5.1-126130.exe、vmware的序列号.txt、redhat9虚拟机原始文件.rar。
2.2安装“VMware-workstation”,并启动。
如图2.2
2.3解压“redhat9虚拟机原始文件.rar”,打开解压文件,双击“redhat.vmx”。
2.4此时linux安装完成,且启动。
用户名:
root密码:
123456.
3升级内核(从linux-2.4.20-8到linux-2.6.18)
3.1在因特网上下载内核以及其他5个工具。
下载linux-2.6.18.tar.bz2
下载mkinitrd-4.1.18-2.i386.rpm
下载lvm2-2.00.25-1.01.i386.rpm
下载device-mapper-1.00.19-2.i386.rpm
下载module-init-tools-3.2.tar.bz2
下载binutils-2.17.tar.gz
3.2把下载好的6个文件装入同一个文件夹(如:
linux-tools),复制到u盘。
如图3.2:
3.3把鼠标移动到linux下,插入U盘。
新建终端,输入以下命令:
#fidisk–f(查看所有硬盘和u盘,找到u盘的挂载名,如/dev/sdb1)
#mount/dev/sdb1/mnt
#cd/mnt
#ls(查看mnt目录下的文件,并把需要的6个文件拷贝到/usr/src中)
#cpbinutils-2.17.tar.gz/usr/src
#cpdevice-mapper-1.00.19-2.i386.rpm/usr/src
#cplinux-2.6.18.tar.bz2/usr/src
#cplvm2-2.00.25-1.01.i386.rpm/usr/src
#cpmkinitrd-4.1.18-2.i386.rpm/usr/src
#cpmodule-init-tools-3.2.tar.bz2/usr/src
3.4查看自己内核版本。
#uname–a(我的是linux-2.4.20-8)
3.5在linux安装6个文件
解压内核,具体操作请依次执行以下命令:
#cd/usr/src(进入到/usr/src目录)
#tarjvxflinux-2.6.18.tar.bz2(解压新内核)
#ln-slinux-2.6.18linux(重新生成linux文件夹)
安装module-init-tools工具包
在/usr/src目录下,依次执行下列命令:
#tarjvxfmodule-init-tools-3.2.tar.bz2(解压module-init-tools)
#cdmodule-init-tools-3.2(由/usr/src目录进入module-init-tools目录下)
#./configure--prefix=/
#makemoveold(将原来的工具程序改名,这样还可继续使用原来的2.4.x内核)
#makeallinstall
#./generate-modprobe.conf/etc/modprobe.conf
安装另外三个升级工具
回到/usr/src目录下,依次执行下列3个命令来安装另外三个升级工具:
#rpm-ivh--nodepsmkinitrd-4.1.18-2.i386.rpm(注意,这里一定要加入--nodeps参数,下同)
#rpm-ivh--nodepslvm2-2.00.25-1.01.i386.rpm
#rpm-ivh--nodepsdevice-mapper-1.00.19-2.i386.rpm
如果不更新以上几个升级包,在后面编译内核时会提示以下错误:
mkinitrdfailed
make[1]:
***[install]Error1
make:
***[install]Error2
安装binutils-2.17.tar.gz工具包,依次执行如下命令:
#tarzxfbinutils-2.17.tar.gz
#cdbinutils-2.17
#./configure
#make
#makeinstall
最开始的时候我没有装Binutils开发包因此都会出现错误,如下类似:
LoadingBusLogic.omodule
Nomodulefoundinobject
insmod:
errorinserting'/lib/BusLogic.o':
-1Invalidmoduleformat
ERROR:
/bin/insomdexitedabnormally!
Mounting/procfilesystem
Creatingblockdevices
VFS:
Cannotopenrootdevice"LABEL=/dev/sda2"orunknown-block(0,0)
Pleaseappendacorrect"root="bootoption
Kernelpanic-notsyncing:
VFS:
Unabletomountrootfsonunknown-block(0,0)
3.6配置内核选项。
#cdlinux-2.6.18(进入到/usr/src/linux-2.6.18目录下)
#makemrproper(该命令可确保源代码目录下没有不正确的.o文件)
#makemenuconfig(配置内核各选项)
此时会出现一个图形界面,列出了所有的内核配置选项,有的选项下还有子选项,你可以用方向键来选择,用Y键来确定。
大多数选项默认就行,以下几个选项必须选择(请认真核对下面每一个选项,否则编译很有可能前功尽弃):
(注意:
前面的符号可能不用有M等等,这里提及的要全部选成*,除非无法转化成*,则保留原来的格式,但是一定要选中)
LoadableModulesupport选项中,选“Moduleunloading”和“Automatickernelmoduleloading”这两项;
DeviceDrivers--->BlockDevices中选“Loopbackdevicesupport”;
DeviceDrivers--->Multi-devicesupport(RAIDandLVM)”处选“devicemappersupport”;
DeviceDrivers--->Graphicssupport”,选“Supportforframebufferdevices”;
DeviceDrivers--->;USBsupport--->选上”USBMassStoragesupport”
DeviceDrivers--->;Networkdevicesupport--->;Ethernet(10or100Mbit)--->;<*>;AMDPCnet32PCIsupport
由于在VMware虚拟机下编译内核,SCSI硬盘,因此以下三个选项必选:
“DeviceDrivers”→“SCSIdevicesupport”→“SCSIdevicesupport”;
“DeviceDrivers”→“SCSIdevicesupport”→“SCSIdisksupport”;
“DeviceDrivers”→“SCSIdevicesupport”→“SCSIlow-leveldrivers”→“BusLogicSCSIsupport”;
Filesystem--->(以下9个选项是关于ext2和ext3文件系统配置,全部选上)
Secondextendedfssupport
Ext2extendedattributes
Ext2POSIXAccessControlLists
Ext2SecurityLabels
Ext3journallingfilesystemsupport
Ext3extendedattributes
Ext3POSIXAccessControlLists
Ext3SecurityLabels
JBD(ext3)debuggingsupport
Filesystem--->DOS/FAT/NTFilesystems--->选上“NTFSfilesystemsupport”;
FileSystems-->Miscellaneousfilesystems---><*>CompressedROMfilesystemsupport(cramfs)
注意:
由于RedHat9.0使用ext3作为文件系统,ext2和ext3文件系统配置很重要,也是必需的,如果对Ext3、Ext2文件的支持直接编译进内核,在你reboot时机器就会当掉,出现如下错误信息:
kernelpanic:
noinitfound,trypassinginit=optiontokernel.....
或者是:
VFS:
Cannotopenrootdevice"hdxy"orunknow-block(0,0)
Pleaseappendacorrect"root="bootoption
kernelpanic:
VFS:
Unabletomountrootfsonunknown-block(0,0)
或者是:
mount:
error19mountingext3
pivotroot:
pivot_root(/sysroot,/sysroot/initrd)failed:
2
umount/initrd/procfail:
2
Freeingunusedkernelmemory:
244kfreed
Kernelpanic–notsyncing:
Noinitfound.Trypassinginit=optiontokernel
3.7编译内核
设置完成!
开始进行真正的内核编译工作。
依次执行如下命令:
在/usr/src/linux-2.6.18目录下,执行以下命令即可编译。
编译需要一段时间。
#makedep(建立编译时所需的从属文件。
注意:
如果内核从未编译过,此步可跳过)
#makeclean(清除内核编译的目标文件)
#makebzImage(注意大小写。
这一步才真正编译内核)(比较费时间)
内核编译成功后,会在/usr/src/linux/arch/i386/boot目录中生成一个新内核的映像文件bzImage。
如果用makezImage编译,内核很大的话,系统会提示你使用makebzImage命令来编译,所以我直接用makebzImage来编译。
在root目录下输入:
/usr/src/linux/arch/i386/boot命令查看有没有bzImage文件,有说明你安装正确。
#cd/usr/src/linux(将目录切换到/usr/src/linux下执行以下命令)
#makemodules(编译可加载模块)(比较花时间)
#makemodules_install(安装可加载模块)
安装成功后,系统会在/lib/modules目录下生成一个2.6.18子目录,里面存放着新内核的所有可加载模块。
#cp/usr/src/linux-2.6.18/drivers/scsi/BusLogic.o/lib/modules/2.6.18/kernel/drivers/scsi
如果不执行上一步复制操作,在makeinstall时会出现如下错误信息:
NomoduleBusLogicfoundforkernel2.4.12
mkinitrdfailed
此问题一般只出现在SCSI硬盘+VMWARE+REDHAT架构中,因为BusLogic被编译进了内核而不是一个module的形式(2.4内核的Buslogic模块即使静态编译进内核也不行)。
其解决方式就是直接将BusLogic.o文件复制过去。
#makeinstall(安装新内核)
3.8把新编译好的内核和原来的内核用bootloader设置成可选的新旧内核启动开机
将新内核和System.map文件拷贝到/boot目录下,依次执行以下命令:
在root下可执行下面这些命令
#cp/usr/src/linux-2.6.18/arch/i386/boot/bzImage/boot/vmlinuz-2.6.18
#cp/usr/src/linux-2.6.18/System.map/boot/System.map-2.6.18
#cd/boot(进入boot目录)
#rm–rfSystem.map(删除原来的连接)
#ln-sSystem.map-2.6.18System.map(重新建立连接)
修改Grub启动管理器(把新编译好的内核和原来的内核用bootloader设置成可选的新旧内核启动开机)
如果没有错误的话,下面开始修改grub配置文件
在/boot目录下cd/boot,执行以下命令:
#new-kernel-pkg--mkinitrd--depmod--install2.6.18(这时候你的/boot下生成一个initrd-2.6.18.img,并且你的grub.conf也作了相应更改)
#df(查看根目录在那个分区,下一步要用到。
注意,这里根分区不是boot的那个50M的分区,而一般是你最大的那个分区,也就是”/”,千万不要搞错。
我的为/dev/sda2)
如果你是在root目录下:
#vi/boot/grub/grub.conf (如果不在root目录下,要进入到root目录下执行此命令)
进入grub.conf文件,做两处修改:
将default=1改为default=0(不改的话,重启之后默认进入2.4内核)
将kernel行的“LABEL=/dev/sda2”换成根目录所在的分区(上一步查看的就是)
此步很重要,修改错误将会可能导致进不去系统,我把我修改后的grub.conf文件列出来,不明之处,可以对照修改:
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
titleRedHatLinux(2.6.18)
root(hd0,0)
kernel/vmlinuz-2.6.18roroot=/dev/sda2
initrd/initrd-2.6.18.img
titleRedHatLinux(2.4.20-8)
root(hd0,0)
kernel/vmlinuz-2.4.20-8roroot=LABEL=/
initrd/initrd-2.4.20-8.img
按“Esc”之后再按“:
wq”退出编辑并保存。
3.9重新启动linux,此时你会看到内核进入选项。
选择自己更新的内核版本进入系统,并查看内核版本。
#uname–a
4分析内核代码中文件init/main.c,并建立相应框图
4.1找到init/main.c代码并阅读
#vi/usr/src/linux/init/main.c
4.2系统初始化过程流程
系统整个初始化过程见图4.2所示:
图4.2内核初始化程序流程示意图
数据结构
时间结构:
#defineCLOCKS_PER_SEC100/*系统时钟滴答频率,100HZ*/
typedeflongclock_t;/*从进程开始系统经过的时钟滴答数*/
structtm
{
inttm_sec;/*秒数[0,59]*/
inttm_min;/*分钟数[0,59]*/
inttm_hour;/*小时数[0,59]*/
inttm_mday;/*1个月的天数[0,31]*/
inttm_mon;/*1年中月份[0,11]*/
inttm_year;/*从1900年开始的年数*/
inttm_wday;/*1星期中的某天[0,6](星期天=0)*/
inttm_yday;/*1年中的某天[0,365]*/
inttm_isdst;/*夏令时标志*/
};
存放硬盘参数表信息:
structdrive_info
{
chardummy[32];
}drive_info;/*用于存放硬盘参数表信息*/
tty等待队列数据结构和tty数据结构:
structtty_queue
{
unsignedlongdata;/*等待队列缓冲区中当前数据指针字符数*/
unsignedlonghead;/*缓冲区中数据头指针*/
unsignedlongtail;/*缓冲区中数据尾指针*/
structtask_struct*proc_list;/*等待进程列表*/
charbuf[TTY_BUF_SIZE];/*队列的缓冲区*/
};
structtty_struct /*tty数据结构*/
{
structtermiostermios;/*终端io属性和控制字符数据结构*/
intpgrp;/*所属进程组*/
intstopped;/*停止标志*/
void(*write)(structtty_struct*tty);/*tty写函数指针*/
structtty_queueread_q;/*tty读队列*/
structtty_queuewrite_q;/*tty写队列*/
structtty_queuesecondary;/*tty辅助队列(存放规范模式字符序列)*/
};/*可称为规范(熟)模式队列*/
请求队列中项的结构和块设备结构:
structrequest
/*请求队列中项的结构。
其中如果dev=-1,则表示该项没有被使用*/
{
intdev;/*使用的设备号*/
intcmd;/*命令(READ或WRITE)*/
interrors;/*操作时产生的错误次数*/
unsignedlongsector;/*起始扇区(1块=2扇区)*/
unsignedlongnr_sectors;/*读/写扇区数*/
char*buffer;/*数据缓冲区*/
structtask_struct*waiting;/*任务等待操作执行完成的地方*/
structbuffer_head*bh;/*缓冲区头指针(include/Linux/fs.h,68)*/
structrequest*next;/*指向下一请求项*/
};
structblk_dev_struct /*块设备结构*/
{void(*request_fn)(void);/*请求操作的函数指针*/
structrequest*current_request;/*请求信息结构*/
};
4.3常量和出错信息的意义
定义系统调用嵌入式汇编宏函数。
不带参数的系统调用宏函数。
typename(void)。
%0-eax(__res),%1-eax(__NR_##name)。
其中name是系统调用的名称,与__NR_组合形成上面的系统调用符号常数,从而用来对系统调用表中函数指针寻址。
返回:
如果返回值大于等于0,则返回该值,否则置出错号errno,并返回-1。
#define_syscall0(type,name)
typename(void)
{
long__res;
__asm__volatile("int$0x80"\ /*调用系统中断0x80*/
:
"=a"(__res)\/*返回值eax(__res)*/
:
""(__NR_
##name));\/*输入为系统中断调用号__NR_name*/
if(__res>=0)\/*如果返回值>=0,则直接返回该值*/
return(type)__res;errno=-__res;\/*否则置出错号,并返回-1*/
return-1;}
/*有1个参数的系统调用宏函数。
typename(atypea)*/
/*%0-eax(__res),%1-eax(__NR_name),%2-ebx(a)*/
#define_syscall1(type,name,atype,a)\
typename(atypea)
{
long__res;
__asm__volatile("int$0x80":
"=a"(__res):
""(__NR_##name),"b"((long)(a)));
if(__res>=0)
return(type)__res;
errno=-__res;
return-1;}
externinterrno;/*出错号,全局变量*/
staticinline_syscall0(int,fork)
/*这是unistd.h中的内嵌宏代码。
以嵌入汇编的形式调用Linux的系统调用中断0x80。
该中断是所有系统调用的入口。
该条语句实际上是intfork()创建进程系统调用。
syscall0名称中最后的0表示无参数,1表示1个参数*/
staticinline_syscall0(int,pause)
/*intpause()系统调用:
暂停进程的执行,直到收到一个信号*/
staticinline_syscall1(int,setup,void*,BIOS)
/*intsetup(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 Linux 内核 升级 实验 报告