loader的实现(3)

创建内核工程

存储规划

生成的内核在磁盘以及内存中的位置,目前如下(后续还将进行调整)。

image.png

实际上,上述位置的确定并不唯一,可自行选择合适的地址,只要保证loader能够正确加载即可。

可以看到,在第100扇区之前预留了比较大的空间,目的是以后loader代码量增大时,有足够的空间存放,不必再临时调整kernel的位置。

向内核传递启动信息

x86的栈

保护模式下,x86的栈单元大小为32位(本课程不涉及64位运行模式),压栈时总是先esp-4,再写入数据;出栈过程则正好相反,先取出数据,再esp+4。

image.png

在C函数中,编译器会根据定义的局部变量、计算过程、函数调用按照一定的规范自动规划栈的使用。具体的使用方法如下:

  1. 保存局部变量和数据
  2. 传递参数:从参数列表右侧往左压入栈
  3. 保存返回地址
  4. 通过ebp+偏移取调用者的传入的参数和自己的局部变量

image.png

课程中栈的使用

课程中实际上是做了从loader到kernel的两级函数调用。

load_kernel()
–> ((void (*)(boot_info_t *))SYS_KERNEL_LOAD_ADDR)(&boot_info)
-> kernel_init(boot_info)

我们所做的工作实际上理解编译器对栈的分配处理规则,取出load_kernel传递过来的参数,再通过栈传递给kernel_init。视频中给出了两种处理方法,实际上还有一种更简单的只需要一条指令的第三种方法。

​    # 第一种方法
​    # push %ebp
​    # mov %esp, %ebp
​    # mov 0x8(%ebp), %eax
​    # push %eax

​    # 第二种方法
​    # mov 4(%esp), %eax
​    # push %eax

​    # 第三种方法,直接将内存中的值压栈
​    push 4(%esp)

​    # kernel_init(boot_info)
​    call kernel_init

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值