前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux源码学习笔记 day1 开机时如何加载系统?

Linux源码学习笔记 day1 开机时如何加载系统?

作者头像
用户1072003
发布2023-02-23 17:06:09
8890
发布2023-02-23 17:06:09
举报
文章被收录于专栏:码上读书码上读书

今天开始学习 闪客老师的《Linux源码趣读》

在开机的时候,主板上的 BIOS程序 会把硬盘启动区的512个字节复制到内存里的0x7c00的位置,再跳转到这里运行。

开机后初始化 指向BIOS

CPU中的PC寄存器,存储着即将要执行的指令的内存地址。开机时需要初始化PC寄存器的值为0xFFFF0。这是Intel手册龟腚的,硬件厂商只是实现而已。(这地位感觉和码农也没什么差别)

CPU的地址线不仅连接内存(RAM),还有ROM(BIOS),还有一些额外的IO端口。这里的初始值0xFFFF0 就是 BIOS所在的ROM区。

硬盘启动区

先来了解一下启动区

如何确定启动区?

硬盘中的0盘0道1扇区(第一扇区)的512个字节的最后2个字节分别是0x55和0xaa,BIOS就会认为它是启动区。

放到第一扇区

Linux-0.11 从bootsect.s开始,

经过编译后,bootsect.s 会被编译成二进制文件,放在启动区的第一扇区。

加载到内存

前面说了BIOS会把代码复制到0x7c00的位置,具体怎么复制的还是得看bootsect.s里的代码:

代码语言:javascript
复制
.equ BOOTSEG, 0x07c0		# original address of boot-sector

……

ljmp    $BOOTSEG, $_start
_start:
  mov	$BOOTSEG, %ax	#将ds段寄存器设置为0x7C0
  mov	%ax, %ds

这里是汇编写的,

  1. 先把 BOOTSEG 常量搞成 0x07c0 。
  2. 再把 BOOTSEG的值给到 寄存器ax。
  3. 再把 寄存器ax 里的值给到 段寄存器ds。

好了,经过这么一倒腾,现在ds里就是0x07c0了。段寄存器 主要是用来内存寻址用的。

段基址(左移4位) + 偏移量 = 真正的内存地址。

(王爽老师的《汇编语言》讲的比较清楚,感兴趣的话,我们拆那本书的时候再详细说)

代码里的0x07c0 就是因为左移了4位才变成0x7c00的。

小结

  1. 开机时,BIOS程序将系统代码复制到0x7c00处;
  2. 通过bootsect.s 的几行代码,修改了段寄存器的值为0x07c0。

这里32位 64位都是 加载到 0x7c00处,这里CPU还处于16位的实模式下,还得兼容老祖宗的位置。看来CPU的发展也有历史包袱。

至于为什么是0x7c00 可以参考阮一峰大佬的这篇文章:http://www.ruanyifeng.com/blog/2015/09/0x7c00.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上读书 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 硬盘启动区
    • 如何确定启动区?
      • 放到第一扇区
      • 加载到内存
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档