Loading...

# 北航操作系统实验Lab1

## Exercise 1.1

- **修改交叉编译路径为 `/OSLAB/compiler/usr/bin/mips_4KC-`**

![ex1_1.png](https://akwing.cn/usr/uploads/2020/06/3179142545.png)

- **`gxemul/` 目录下生成`vmlinux` 内核文件**

![ex1_2.png](https://akwing.cn/usr/uploads/2020/06/732876089.png)

## Exercise 1.2

ELF(Executable and Linkable Format) 是一种文件格式,从名字上看它是可执行文件和可链接文件的格式。通常多个.c文件经过编译以后,生成多个.o文件(也即是目标文件), 这些.o文件就是ELF格式,然后链接器将多个.o链接到一起就得到了一个可执行文件。可执行文件也是ELF格式。

那么,ELF 文件中都包含有什么东西呢?简而言之,就是和程序相关的所有必要信息。具体来说包含5个部分。

1. ELF Header,包括程序的基本信息,比如体系结构和操作系统,同时也包含了 Section Header Table 和 Program Header Table 相对文件的偏移量 (offset)。

2. Program Header Table,也可以称为 Segment Table,它是一个数组,数组中的每一项描述了程序中每一个Segment的信息,Segment 的信息需要在运行时刻使用。

3. Section Header Table,它也是个数组,数组的每一项描述了每一个Section的信息,Section 的信息需要在程序编译和链接的时候使用。

4. Segments,就是各个 Segment。Segment 则记录了每一段数据(包括代码等内容)需要被载入到哪里,记录了用于指导应用程序加载的各类信息。

5. Sections,就是各个 Section。Section 记录了程序的代码段、数据段等各个段的内容,主要是链接器在链接的过程中需要使用。

详细信息请参考手册。[ELF手册](https://github.com/gitccl/BUAA-OSLAB-2020/blob/master/ELF%E6%89%8B%E5%86%8C.pdf)

### 补全 `readelf.c` 文件

- **方法1**

```c

// get section table addr, section header number and section header size.

shdr = (Elf32_Shdr *)(binary + ehdr -> e_shoff); //section table addr

sh_entry_count = ehdr -> e_shnum; //section header number

sh_entry_size = ehdr -> e_shentsize; //section header size

// for each section header, output section number and section addr.

for(Nr = 0; Nr < sh_entry_count; ++ Nr)

{

printf("%d:0x%x\n" , Nr , shdr->sh_addr);

shdr ++ ;

}

```

- **方法2**

```c

// get section table addr, section header number and section header size.

ptr_sh_table = binary + ehdr -> e_shoff;

sh_entry_count = ehdr -> e_shnum; //section header number

sh_entry_size = ehdr -> e_shentsize; //section header size

// for each section header, output section number and section addr.

for(Nr = 0; Nr < sh_entry_count; ++ Nr)

{

shdr = (Elf32_Shdr *)(ptr_sh_table);

printf("%d:0x%x\n" , Nr , shdr->sh_addr);

ptr_sh_table += sh_entry_size;

}

```

### 解析 testELF 文件

![ex2_1.png](https://akwing.cn/usr/uploads/2020/06/532178132.png)

![ex2_2.png](https://akwing.cn/usr/uploads/2020/06/2007364636.png)

## Exercise 1.3

实验使用的操作系统内核就是我们上面生成的vmlinux文件,这个文件是个可执行文件,ELF格式。它是经过多个.c文件编译成.o文件后,然后链接器将多个.o文件链接成一个最终的可执行文件vmlinux。我们的模拟器gxemul会把vmlinux文件加载到内存,然后跳转到内核入口(其实是个地址),CPU会从这个入口地方开始取址执行,这样操作系统就启动完毕了。内核文件里面有代码,数据等,内核文件应该被加载到哪个地方呢?换而言之这些代码和数据应该存储在内存中哪个地方?通过内存布局图可以发现我们需要把内核文件加载到`Kernel Text`处,也即是地址`0x80010000`处。如何设置内核加载的位置?

首先我们需要知道,一个可执行文件是根据什么加载到内存。是根据ELF文件里的内容,ELF文件记录了这个文件的各个段应该被加载到哪个地址,然后程序把这个文件加载到这个地址(这个在后面Lab3里面会让你来实现这个过程)。我们可以看到vmlinux文件是由多个.o文件链接而成的,然后得到ELF文件vmlinux。ELF文件记录了这个文件应该被加载到哪个地方,因此我们可以在链接生成ELF文件的时候,指定这个加载位置为`0x80010000`!将内核文件加载到指定位置上,CPU不一定从这个位置开始执行。指导书上也说了程序入口的几种设置方法,本实验显然是使用 ENTRY() 指令指定了程序入口为 _start 函数。

### 补全 tools/scse_03.lds

- **将起始地址设为 `0x80010000`**

```asm

SECTIONS

{

. = 0x80010000;

.text : { *(.text) }

.data : { *(.data) }

.bss : { *(.bss) }

end = . ;

}

```

### 查看地址

- **重新`make`,生成`vmlinux`内核文件**

![ex3_1.png](https://akwing.cn/usr/uploads/2020/06/187331421.png)

- **查看各个`section`的地址**

![ex3_2.png](https://akwing.cn/usr/uploads/2020/06/3936389153.png)

## Exercise 1.4

### 补全 `boot/start.S`

- **栈指针地址应设为 `0x80400000`**

```asm

/*To do:

set up stack

you can reference the memory layout in the include/mmu.h

*/

li sp, 0x80400000 // 设置栈指针

jal main // 跳转到main函数

nop

```

### 运行 `vmlinux` 文件

- **重新`make`**

![ex4_11.png](https://akwing.cn/usr/uploads/2020/06/2810689927.png)

- **执行命令 `gxemul -E testmips -C R3000 -M 64 elf-file`**

`elf-file`为编译生成的`vmlinux`文件的路径

![ex4_2.png](https://akwing.cn/usr/uploads/2020/06/1140751818.png)

## Exercise 1.5

### 补全 `lp_Print()` 函数

- **找到 `%`**

```c

/* scan for the next '%' */

while((*fmt) != '\0' && (*fmt) != '%') {

OUTPUT(arg, fmt, 1);//其他字符,直接输出

fmt ++ ;

}

/* flush the string found so far */

/* are we hitting the end? */

if((*fmt) == '\0' ) break; //结束了

```

- **取出参数**

```c

/*init the variable */

longFlag = 0;

negFlag = 0;

width = 0;

ladjust = 0;//默认右对齐

prec = 0;

padc = ' ';

/* we found a '%' */

fmt ++ ;

/* check for other prefixes */

/*check for flag */

if(*fmt == '-') ladjust = 1, fmt ++;

else if(*fmt == '0') padc = '0' , fmt ++;

/*check for width */

for(; IsDigit(*fmt); fmt ++ ) width = width * 10 + Ctod(*fmt) ;

/*check for precision */

if(*fmt == '.')

{

fmt ++ ;

for(; IsDigit(*fmt); fmt ++ )

prec = prec * 10 + Ctod(*fmt) ;

}

/* check for long */

if( *fmt == 'l' ) {

longFlag = 1;

fmt ++ ;

}

```

### 输出结果

- **重新`make`**

![ex5_1.png](https://akwing.cn/usr/uploads/2020/06/3429446959.png)

- 执行命令 `gxemul -E testmips -C R3000 -M 64 elf-file` , 查看输出结果

![ex5_2.png](https://akwing.cn/usr/uploads/2020/06/1245394543.png)

### push到远程进行测试

- **`git push`**

![ex5_3.png](https://akwing.cn/usr/uploads/2020/06/2766228111.png)

- **结果**

![ex5_4.png](https://akwing.cn/usr/uploads/2020/06/3615437883.png)

最后修改:2020 年 07 月 26 日 10 : 46 AM

© 允许规范转载

赞赏

如果觉得我的文章对你有用,请随意赞赏

×Close

赞赏作者

扫一扫支付

支付宝支付

微信支付

北航linux内核编译及烧录实验报告,北航操作系统实验Lab1笔记相关推荐

  1. linux系统调用记录模块实验报告,华科操作系统实验报告(DOC)

    华 中 科 技 大 学 课 程 设 计 报 告 课 程 实 验 报 告 课程名称: 操作系统课程设计 专业班级: 学 号: 姓 名: 指导教师: 报告日期: 计算机科学与技术学院 华 中 科 技 大 ...

  2. 实验四linux操作系统实验报告(1),操作系统实验报告

    一. 实验目的及实验环境 (一) 实验环境 Linux 操作系统 (二)实验目的 实验1 掌握Linux基本命令 和开发环境 掌握常用的Linux shell命令: 掌握编辑环境VIM: 掌握编译环境 ...

  3. 计算机操作系统安装实验报告,计算机操作系统实验报告.doc

    计算机操作系统实验报告.doc (12页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 计算机操作系统实验报告实验一一.实验目的 在单处理 ...

  4. 山东大学linux实验报告,山东大学操作系统实验四

    一.实验内容: 抽烟者问题.假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟.抽烟者卷起并抽掉一颗烟需要有三种材料:烟草.纸和胶水.一个抽烟者有烟草,一个有纸,另一个有胶水.系统中还有两个供 ...

  5. 操作系统实验(linux内核编译,添加系统调用,windows进程创建,脚本程序编写)

    <操作系统原理>实验报告 一.实验目的 (1)理解操作系统生成的概念和过程; (2)理解操作系统两类用户界面(操作界面,系统调用)概念; 二.实验内容 (1)在Unbantu或Fedora ...

  6. linux编译内核实验,实验六 Linux内核编译实验.doc

    实验六 Linux内核编译 讲师:杨行 [实验目的] 1.掌握Linux内核编译 2.了解Linux内核Makefile 3.了解Linux内核Kbuild系统 [实验原理] 网站可以下载标准内核文件 ...

  7. linux 内核 死锁 检查,一种linux内核自旋锁死锁检测报告系统和方法与流程

    本发明涉及内核死锁检测领域,具体的说是一种linux内核自旋锁死锁检测报告系统和方法. 背景技术: linux内核死锁是长期困扰内核开发人员的问题之一,但自内核引入lockdep调试模块之后,内核死锁 ...

  8. 最小的linux内核编译,Linux最小内核移植

    class="markdown_views prism-github-gist"> Linux内核编译 本篇博客来自凌云实验室开发板介绍及其烧录学习笔记 1.内核介绍 一种开 ...

  9. LINUX内核编译(ZT)

    LINUX内核编译(ZT) 在这里转贴一些关于内核编译的文章,绝非笔者原创,也无意注明出处.有些内容有重复之处,请原谅. ==================================== 一. ...

最新文章

  1. html调后台接口_前后端分离之让前端开发脱离接口束缚(mock)
  2. java获取目录中最后被更改的文件_如何使用Java从目录中只获取10个最后修改过的文件?...
  3. Python四种形式模块的形式与调用
  4. CVPR 2022 | CNN自监督预训练新SOTA:上交、Mila、字节联合提出具有层级结构的图像表征自学习新框架...
  5. VMware的屏幕太小
  6. 2014/5/25 多校
  7. CPU 被挖矿,Redis 竟是内鬼!
  8. クリムゾンガールズ 汉化补丁(BUG修正)
  9. 串讲-解释篇:作用域,作用域链,执行环境,变量对象,活动对象,闭包
  10. HTML CSS设计与构建网站
  11. MSP430CPU介绍
  12. div绑定onblur事件
  13. 导弹发射各项参数计算涉及计算机应用,计算机应用基础10.doc
  14. 蓝牙耳机南卡和JBL哪款好用?半入耳耳机南卡和JBL详细对比评测
  15. Java学习——java语言概述
  16. VS用SSIS实现SQL Server数据库与Excel表格数据的相互导入
  17. 【视频】什么是Bootstrap自抽样及应用R语言线性回归预测置信区间实例|数据分享
  18. 信息系统项目管理-立项管理
  19. selenium2(webdriver)的“兄弟姐妹”
  20. python中plt.legend_matplotlib中plt.legend等的使用方法

热门文章

  1. 阿里图标库iconfont如何使用
  2. 人工智能相关技术的快速发展,主要带来了哪些价值优势?
  3. sentinel只有实时监控不显示
  4. solr mysql 导入命令_Solr 07 - Solr从MySQL数据库中导入数据 (Solr DIH的使用示例)
  5. Gstreamer - 位置跟踪和定位
  6. Cookie、Session、Token、JWT 看一篇就够了
  7. 【工控协议专题01】Modbus协议原理与安全性分析
  8. 前端接收list的情况 (批量添加)出现这个错说明不是传参错误,是解析错误
  9. 数据库视图的基本操作(sql语句)
  10. Vue3+TS + element-plus 项目 动态生成Icon图标