自制操作系统日记(5):跳转到C语言执行

自己动手写操作系统--"Hello, OS world!" 自己动手写操作系统--"Hello, OS world!"       作者:zieckey(zieckey@yahoo.com.cn)1、开发环境与工具开发环境:winxp+sp2必须安装Bochs-2.3,nasm,UltraEdit.下载nasm后,添加nasm所在目录到到path目录,建议直接将nasm放到windows或system32目录,方便从命令行调用.下载地址:h 阅读详情

代码仓库地址:https://github.com/freedom-xiao007/operating-system

简介

在上篇中切换了CPU的64位模式,但后面是失败的,并没有真正切换,也没有相关的验证代码,本篇中终于修正并执行了C代码

CPU模式切换修正

上篇中后面发现系统在Get SVGA时卡住了,并没有向下执行

后面搜索资料,最终尝试下来,感觉上使用qeme好像有些问题,同样的镜像在qemu中会不断循环重启,而在bochs中不会,所以我们重新抄了下代码,并且换了下虚拟机,换成bochs

文章的参考链接如下,写的很好,又学到了很多

我们直接抄它的三个文件:bootsect.asm、setup.asm、head.asm

在head.asm中,他是直接在里面模拟的c的main函数,我们将其注释掉,并修改call main为我们的c的start函数,具体修改如下:

修改call main 为 call _start; 在104行左右

注释掉所有的main函数代码,115到120行左右

push 0 ;These are the parameters to main :-)
push 0 ;这些是调用main程序的参数(指init/main.c)。
push 0  
push L6 ;return address for main, if it decides to.
push _start ;'_main'是编译程序对main的内部表示方法。
jmp  setup_paging   ;这里用的JMP而不是call,就是为了在setup_paging结束后的
                    ;ret指令能去执行C程序的main() 
L6:
jmp L6 ;main程序绝对不应该返回到这里。不过为了以防万一,
     ;所以添加了该语句。这样我们就知道发生什么问题了。
     
     
     


; _main:      ;这里暂时模拟出C程序main() 
;      mov  esi,mainmsg                ;保护模式DS=0,数据用绝对地址访问
;      mov  cl, 0x09                   ;蓝色
;      mov  edi, 0xb8000+22*160        ;指定显示在某行,显卡内存地址需用绝对地址
;      call printnew                   ;0xb8000为字符模式下显卡映射到的内存地址 
;      ret  

这样对他的相关改造就OK了

C代码植入

关于运行C代码的部分我们还是跟随《30天自制操作系统》的思路:将C代码转换成汇编码,和head.asm拼接到一起,然后直接编译即可

根据大体思路,我们的具体操作如下:

  • 1.编写C代码
  • 2.使用GCC将C代码生成.O文件
  • 3.使用objconv将.O文件转成nasm汇编文件
  • 4.使用python脚本处理调转换得到的汇编文件的一些不需要的地方
  • 5.编写运行脚本,拼接文件,编译,运行

具体细节如下:

1.C代码编写

我们就简单起名叫start.c吧,里面就打印一个字符串,无限循环

typedef unsigned char uint8_t;

void put_str(uint8_t* message);

void start(void) {
    put_str("0123456789");
    while(1);
}

put_str的函数目前我们用汇编进行实现,新增func.asm文件,编写put_str函数

_put_str:
	mov  esi, esp ;保护模式DS=0,数据用绝对地址访问
	mov  cl, 0x09                   ;蓝色
	mov  edi, 0xb8000+22*160        ;指定显示在某行,显卡内存地址需用绝对地址
	call printnew                   ;0xb8000为字符模式下显卡映射到的内存地址 
	ret  

打印字符串就参考的head.asm里面的main函数

2.使用GCC将C代码生成.O文件

在Windows10上使用GCC需要安装一些东西

首先安装命令choco,管理员方式打开powershell,输入下面的命令:

set-executionpolicy remotesigned
iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex

然后使用命令安装MinGW

choco install mingw

安装完成后,重启启动下powershell就可以使用gcc命令,如下就是使用gcc将.c文件生成.o文件

gcc -m32 -fno-asynchronous-unwind-tables -s -O2 -c -o .\\c\\start.o .\\c\\start.c

我们目前还是使用32位吧(命令的-m32),64位有点把控不住…

3.使用objconv将.O文件转成nasm汇编文件

这个工具需要进行下载,下载地址为:https://www.agner.org/optimize/#objconv,在页面上找Object file converter,然后点击下载后对应安装即可

将.o文件转换成nasm文件命令如下:

D:\\software\\objconv\\objconv.exe -fnasm .\\c\\start.o .\\c\\nasm\\start.asm

4.使用python脚本处理调转换得到的汇编文件的一些不需要的地方

生成的文件中有很多地方错误和不必要的代码,需要进行处理

如何人工去处理太慢了,这里使用编写python脚本进行处理

脚本大致如下,还是比较简单的,就是读文件,读取一行内容后进行过滤,如果符合条件,写入新文件中

if __name__ == "__main__":
    with open("E:\\code\\other\\self\\operating-system\\c\\clean\\start.asm", "w") as fw:
        with open("E:\\code\\other\\self\\operating-system\\c\\nasm\\start.asm", "r") as fr:
            content = fr.readline()
            while content:
                if content.startswith("global") or content.startswith("extern"):
                    content = fr.readline()
                    continue
                content = content.replace("noexecute", "")
                content = content.replace("execute", "")
                fw.write(content)
                content = fr.readline()

在搜索的资料中,需要进行下面的操作:

  • 使用global定义的函数名称标签(extern目前暂时去掉)
  • 去掉.SECTION一行中的execute或noexecute,和(如果有需要的话)align=N语句
  • 去掉default rel行(目前的文件中没有发现,暂时没有处理)

这样就大致处理完成了

5.编写运行脚本,拼接文件,编译,运行

下面就是最后的拼接和编译运行了,我们将所有的步骤放到bat脚本中,一键运行,脚本内容如下:

# 编译
D:\\software\\NASM\\nasm.exe bootsect.asm -o bootsect.bin -l bootsect.lst
D:\\software\\NASM\\nasm.exe setup.asm -o setup.bin  -l setup.lst

# 将C代码转换后拼接编译
gcc -m32 -fno-asynchronous-unwind-tables -s -O2 -c -o .\\c\\start.o .\\c\\start.c
D:\\software\\objconv\\objconv.exe -fnasm .\\c\\start.o .\\c\\nasm\\start.asm
D:\\software\\python3\\python.exe E:\\code\\python\\self\\tools\\tools\\objconv2nasm_clearn.py
copy /B head.asm+.\\c\\clean\\start.asm+func.asm  kernel.asm
D:\\software\\NASM\\nasm.exe kernel.asm -o kernel.bin -l kernel.lst

# 将所有的文件整合成镜像
copy /B bootsect.bin+setup.bin+kernel.bin  os.iso

# 使用bochs运行镜像
D:\\software\\Bochs-2.7\\bochs -q -f D:\\software\\Bochs-2.7\\dlxlinux\\bochsrc_m.bxrc

bochs的安装和使用说明参考后面的,运行结果如下:

在这里插入图片描述

bochs安装使用说明

首先bochs的下载地址为:https://sourceforge.net/projects/bochs/

解压后,我们需要修改:D:\software\Bochs-2.7\dlxlinux\bochsr.bxrc成D:\software\Bochs-2.7\dlxlinux\bochsr_m.bxrc

主要修改文件的对应路径和启动方式,整个配置文件如下:

###############################################################
# bochsrc.txt file for DLX Linux disk image.
###############################################################

# how much memory the emulated machine will have
megs: 32

# filename of ROM images,替换原来的相对路径为绝对路径
romimage: file=D:\\software\\Bochs-2.7\\BIOS-bochs-latest
vgaromimage: file=D:\\software\\Bochs-2.7\\VGABIOS-lgpl-latest

# what disk images will be used 
# 指明启动的镜像为我们的os.iso镜像文件
floppya: 1_44=E:\\code\\other\\self\\operating-system\\os.iso, status=inserted
floppyb: 1_44=floppyb.img, status=inserted

# hard disk
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="D:\\software\\Bochs-2.7\\dlxlinux\\hd10meg.img", cylinders=306, heads=4, spt=17

# choose the boot disk.修改启动方式为软盘
boot: floppy

# default config interface is textconfig.
#config_interface: textconfig
#config_interface: wx

#display_library: x
# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga

# where do we send log messages?
log: bochsout.txt

# disable the mouse, since DLX is text only
mouse: enabled=0

# set up IPS value and clock sync
cpu: ips=15000000
clock: sync=both

# enable key mapping, using US layout as default.
#
# NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows.
# However, the key mapping tables are used in the paste function, so 
# in the DLX Linux example I'm enabling keyboard_mapping so that paste 
# will work.  Cut&Paste is currently implemented on win32 and X windows only.

# 替换原来的相对路径为绝对路径
keyboard: keymap=D:\\software\\Bochs-2.7\\keymaps/x11-pc-us.map
#keyboard: keymap=D:\\software\\Bochs-2.7\\keymaps/x11-pc-fr.map
#keyboard: keymap=D:\\software\\Bochs-2.7\\keymaps/x11-pc-de.map
#keyboard: keymap=D:\\software\\Bochs-2.7\\keymaps/x11-pc-es.map

这样就OK了,这个是启动的配置文件

在我们的一键运行脚本中,配置使用该文件即可

D:\\software\\Bochs-2.7\\bochs -q -f D:\\software\\Bochs-2.7\\dlxlinux\\bochsrc_m.bxrc

总结

最后的打印字符串还是有点问题,但最终的目的是达到了,调用C语言的代码(后面也查了资料,但目前的水平短时间内解决不了,只能放到后面看看了)

参考链接

objconv elf,omf,coff文件转换工具附带源码 elf,omf,coff多种文件转换工具,附带源码 立即下载

相关推荐

objconv.exe

学习汇编和操作系统一定会用到的一定会用到的一定会用到的一定会用到的

哈工大操作系统实验一--调试分析 Linux 0.00 引导程序

Bochs。

weixin_63064634的博客 4974

objconv.zip 工具包,很实用

objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用 objconv.zip 工具包,很实用

bochs用户手册-3.4编译

在这种情况下,必须将丢失的DLL从例如Cygwin文件夹复制到编译的EXE文件的位置。有一个名为configure的脚本,它测试您的机器、C/C++编译器和库,以发现哪些设置应该在您的系统上工作。该问题的当前解决方案是,Bochs配置脚本必须在支持shell脚本的不同平台上运行,并带有使其配置为Win32平台而不是本机平台的选项。如果你在FreeBSD上,并且使用ports集合安装了SDL,Bochs将无法自动找到库,因为在这种情况下,SDL配置脚本被称为sdl11-config(即使是1.2版本)。

weixin_45499326的博客 1911

OnlineLicensing.zip

OnlineLicensing.zip

解决Linux下Questasim中代码字体非常小

Questasim的source窗口里代码字体非常小 你是不是也遇到这样的问题,在使用Vmware时,Questasim的代码字体非常小,小到完全看不见,连断点都没办法标记。 下面我给出我摸索好久的解决办法,分享给大家。 1.首先,版本是Questasim 10.7c,在Vmware16中打开,情况如下: 不多逼逼,直接上图开搞: 给textFontV2设置值:monospace 12 normal roman 这里一定要注意啦,点完apply之后,不要点ok,直接关闭窗口。 ...

SummerXRT的博客 7810

理解 Linux Kernel (1) - BIOS

前言 在概述,我已经介绍过《理解 Linux Kernel》系列文章的写作原因。我不能担保我所进行的所有试验性操作都是对的,但至少操作我的环境下成功地运行了,并帮助我触及我始终敬畏的硬件&OS 《Linux 内核完全注释》第三章——内核编程语言和环境,描述了用 as86 汇编语言构建 boot 引导程序,在 Bochs 仿真器成功模拟开机运行,最终输出 Loading System…。这就...

DorMOUSENone的博客 579

Ubuntu AX200 iwlwifi-cc-46.3cfab8da.0.tgz无法下载的解决办法

AX200 iwlwifi-cc-46.3cfab8da.0.tgz 无法下载网页出问题使用 其他方法来进行但是前提还是有网络。

chen20170325的博客 1038

自制操作系统日记(6):静态桌面初步

在上篇中我们成功的加载跳转执行了C语言的代码,本篇中将跟随书籍,初步展示了一个系统页面的初步界面,看到桌面那刻还是有点意思的

github_35735591的博客 405

揭秘cocos-mcp:如何用AI助手提升CocosCreator游戏开发效率

本文深入介绍了cocos-mcp工具,它作为连接AI助手与CocosCreator编辑器的桥梁,遵循MCP协议,能显著提升游戏开发效率。通过自然语言指令,开发者可让AI直接查询场景结构、批量修改属性或生成上下文代码,将重复操作变为智能调度,实现从“手动操作者”到“指令指挥官”的工作流变革。

weixin_29001683的博客 1048

从零构建基于ZYNQ与AD9361的SDR信号源:FPGA逻辑与射频前端的协同设计

本文详细介绍了从零开始构建基于ZYNQ与AD9361的SDR信号源的完整流程。通过解析FPGA逻辑与射频前端的协同设计,重点阐述了如何利用FPGA生成基带信号,并通过ARM处理器配置AD9361,最终实现一个可编程的2.4GHz载波信号发生器。内容涵盖硬件选型、Vivado环境搭建、AXI总线通信、LVDS接口设计及软件驱动开发,为SDR开发者提供了实用的实战指南。

weixin_29200485的博客 214

shell学习日记

系统学习日记 系统: shell语言: 解释性脚本语言 不需要编译就可以运行 1 相关概念: 操作系统:window 安卓 ios鸿蒙 linux 作用:管理文件系统/内存分配/网络/设备管理 内核的五大功能: 1 文件管理 2 网络管理 3 内存管理 4 设备管理 5 进程管理 函数: 函数功能 函数参数 函数的返回值 ubuntu安装 1 安装真机 (开机直接运行的linux操作系统) 2 安装双系统 (linux window) 3 安装虚拟机 第二天************ 目录类型:树状 根目录

weixin_44983369的博客 949

深入解析HAL_UART_Receive_IT:如何高效配置串口中断接收

本文深入解析了STM32 HAL库中`HAL_UART_Receive_IT`函数的工作原理与高效配置方法。该函数并非直接接收数据,而是作为中断接收的启动器和配置器,通过开启相关中断,由`UART_Receive_IT`在后台完成数据搬运。文章详细对比了中断与轮询模式的区别,并提供了不定长数据接收的完整实战流程、常见问题避坑指南及高级应用技巧,帮助开发者构建稳定高效的串口通信。

weixin_29162439的博客 626

嵌入式编程学习日记(一)——C语言篇(文件分析库函数版)

摘要:本文详细介绍了STM32工程中核心文件夹的功能与修改注意事项。core文件夹存放启动文件,不可修改;FWLIB包含官方外设驱动库,修改会导致错误;CMSIS是内核支持文件,无需改动。重点说明了SYSTEM文件夹中delay.c和usart.c的可调参数:delay_init()需根据主频设置,串口波特率需匹配通信需求(常用115200),中断优先级影响响应顺序。在USER文件夹中,main.c和中断文件可自由修改,但system_stm32f4xx.c的晶振频率(HSE_VALUE)必须与实际硬件一致

m0_71768906的博客 443

基于Python的海关进出口数据爬取与贸易关系分析

本文介绍了如何使用Python爬虫技术获取海关进出口数据,并基于这些数据进行贸易关系分析。文章详细阐述了数据采集、清洗、存储和分析的全过程,使用了最新的爬虫技术和数据分析方法,为国际贸易研究提供数据支持和技术参考。关键词:Python爬虫、海关数据、贸易分析、数据可视化、Selenium、Scrapy。

2201_76125261的博客 543

1.14、基于NARX神经网络的磁悬浮建模(matlab)

数据准备:首先,需要准备用于训练和测试的磁悬浮系统的输入和输出数据,包括磁力、电流、位置、速度等信息。数据可以被保存在MATLAB的数据文件中,并加载到工作空间中。使用MATLAB的神经网络工具箱,创建一个NARX神经网络。需要定义网络的层次结构、节点数、激活函数等参数。通常,NARX网络包括自回归层和外部输入层。数据预处理:对加载的数据进行预处理,包括去除噪声、归一化处理等操作,以确保数据质量和网络训练的稳定性。使用MATLAB的训练函数,如trainlm或者trainbr,对NARX神经网络进行训练。

XU157303764的博客 1996

【学习日记】函数调用 和 全局变量 如何实现 位置无关码

位置无关码(Position Independent Code,简称 PIC)是一种特殊类型的编码方式,用于生成在内存中可以任意位置运行的代码。这种代码在编译时不会固定任何特定的内存地址,使得程序或库在运行时可以被加载到内存的任意位置而无需修改。这对于操作系统中的动态链接库(DLLs)和共享库(如 Linux 中的 .so 文件)尤为重要。

Witheart 的博客。 1409

【NVIDIA-GB200-1】国内第一份生产环境实战安装配置教程,配置安装脚本,nvidia gb200配置教程-复制即用;gb200驱动安装

GB200 的高性能通信依赖。

jundao1997的专栏 704

编程研发工作日记

本文探讨了编程语言特性与计算机数据处理原理。Java和C/C++形成"T"字形知识结构,分别侧重应用开发和系统底层;JavaScript则具有跨平台优势。计算机通过事件机制实现数据传输,并以文件形式持久化存储。编程本质是内存寻址操作,涉及面向过程(函数)和面向对象(类)两种范式。内存管理方面,堆栈分工明确:堆处理大数据存储,栈保存引用地址。文章还分析了编程控制结构(循环优于goto/递归)和代码组织原则(分层解耦、接口组合),揭示了计算机系统高效运行的内在机制。

wanzhong_liao的博客 460

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

学习日记1

原文链接:https://blog.youkuaiyun.com/qq_53809201/article/details/119343731)找相关pip源(https://pypi.tuna.tsinghua.edu.cn/simple/ ):用于查看程序的调用栈信息,它会显示当前函数调用的层次结构,包括函数名、参数和返回地址等。:用于查看当前函数中所有局部变量的信息。:用于让程序从当前暂停的位置继续执行,直到遇到下一个断点或者程序结束。:用于查看已经设置的所有断点的信息,包括断点编号、位置、是否有效等。

2401_87667921的博客 841

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

flutter跳转native,androidtv开发视频教程

看到这篇文章的人不知道有多少是和我一样的Android程序员。35岁,这是我们这个行业普遍的失业高发阶段,这种情况下如果还不提升自己的技能,进阶发展,我想,很可能就是本行业的职业生涯的终点了。我们要有危机意识,切莫等到一切都成定局时才开始追悔莫及。只要有规划的,有系统地学习,进阶提升自己并不难,给自己多充一点电,你才能走的更远。千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。

2401_84413631的博客 905

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【lua语言基础(四)】IO模型以及补充知识

本篇文章主要讲解了lua语言的IO模型和控制流程相关知识

杭电码农-NEO的博客 1572

基于HarmonyOS API 24实战解析:旅行日记应用TravelEntry 被装饰器 @Observed 标记,框架会对该实例的属性进行深度劫持(基于 ES6 Proxy 或类似机制)

本文将对一个完整的 HarmonyOS ArkTS 班级管理助手应用进行逐段源码深度剖析。该应用面向中小学班主任或班级管理者的日常教务场景,将学生信息管理、课程表展示、考勤记录追踪、成绩统计分析四大核心功能模块统一收纳在一个 入口组件中,通过底部 进行模块切换。采用单文件架构(single-file architecture),将数据模型层、常量配置层、Mock 数据工厂层、业务计算函数层与 UI 渲染层全部内聚于同一编译单元内,这种组织方式在中小型 HarmonyOS 应用中非常常见,既能保证代码的可

2301_79516720的博客 182

Win7常规快捷键

Win+1:打开/显示超级任务栏第一个图标代表的程序 Win+2:打开/显示超级任务栏第二个图标代表的程序(3、4、……如此类推) Win+D:切换桌面显示窗口或者gadgets小工具 Win+E:打开explorer资源浏览器 Win+F:搜索文件或文件夹 Win+G:切换边栏小工具 Win+L:如果你连接到网络,则锁定计算机,如果没有连接到网络的,则切换用户 Win+M:快速显示桌面...

288
上一篇: 自制操作系统系列(四):进入64位模式
下一篇: 自制操作系统日记(6):静态桌面初步
_萧_
博客等级 码龄10年 55粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值