# MyOs **Repository Path**: wbgitee/MyOs ## Basic Information - **Project Name**: MyOs - **Description**: 自制操作系统OS - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-09-28 - **Last Updated**: 2021-10-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MyOs 自制操作系统os ## 1、编辑Bochs-2.3.6/bochsrc.bxrc 修改BIOS路径(romimage、vgaromimage) 虚拟硬盘路径(ata0-master path属性) 键盘映射方式(keyboard) ### 2、创建虚拟硬盘 diskpart create vdisk file=os.vhd maximum=10 type=fixed 10M的固定硬盘 ## 3、目录介绍 build:编译后的代码,虚拟磁盘,启动日志。每次启动需要清空重新编译 code:boot 引导区代码,主要由汇编完成;kernel 内核代码,主要由C编程;lib 内核需要加载的库,由C和汇编混合编程 init:项目启动需要的初始化文件 tools:项目编译需要的工具,如nasm、gcc、make等命令 ## 4、编译代码 ### 编译启动区 nasm -I ../code/boot/include/ -o ../build/mbr.bin ../code/boot/mbr.S ### 编译引导区 nasm -I ../code/boot/include/ -o ../build/loader.bin ../code/boot/loader.S 分别写入到对应的扇区 dd if=../build/mbr.bin of=../build/os.vhd bs=512 count=1 dd if=../build/loader.bin of=../build/os.vhd bs=512 count=3 seek=2 ### 编译内核代码 gcc -c -o ../build/main.o ../code/kernel/main.c 默认起始入口函数为_start -Ttext:使用指定的地址作为文本段的起始点;-e: 使用指定的符号作为程序的初始执行点 ld ../build/kernel/main.o -Ttext 0xc0001500 -e main -o ../build/kernel.bin dd if=../build/kernel.bin of=../build/os.vhd bs=512 count=200 seek=9 ### 汇编语言和C混合编程 编译 print.S nasm -f elf -o ../build/kernel/print.o ../code/lib/kernel/print.S 编译 main.c gcc -I ../code/lib/ -I ../code/lib/kernel/ -c -o ../build/main.o ../code/kernel/main.c 链接 main.o和print.o ld -Ttext 0xc0001500 -e main -o ../build/kernel.bin ../build/main.o ../build/print.o 注意:链接的时候报错is incompatible with i386:x86-64 output。nasm -f elf64需要移植到64位系统 ### 编写makefile makefile编译项目常见错误: - linux的dd命令写入磁盘bochs.exe会出现ata0-0: could not open hard drive image file错误。 - nasm编译和gcc编译位数要相同。否则出现is incompatible with i386:x86-64 output,file not recognized: file format not recognized错误。 - gcc在linux编译的目标文件是elf格式,在win编译是coff(pe)格式。nasm可以指定生成elf格式还是win格式。 - windows下的联合汇编,汇编代码中和 C 语言产生混编关系的变量和函数,前面都要加一个下划线“_”,C 语言代码中的函数不加,否则链接报错undefined reference to。linux下函数前面不需要下划线否则报错。 - windows链接的kernel.bin是PE格式,而loader.S在加载kernel.bin时,会将kernel.bin中的segment拷贝到编译的地址。所以需要objcopy -O elf32-i386转换成ELF格式,否则无法调用到内核函数。 - 内核主函数不能取名main,windows编译下会出现main方法,导致链接报错 undefined reference to `___main'。可以通过visual studio的dumpbin查看main.o文件。 工具:dumpbin(object文件转汇编),file(查看文件格式),readelf(查看elf格式内容),objectdump(反汇编) ## 5、启动 ### 手动执行命令启动方式 点击bochs.exe运行后再点击start按钮。 注意:每次重新运行需要删掉.vhd.lock文件。否则出现 ata0-0: could not open hard drive image file错误。 每次运行之后,多了一个.vhd.lock文件。之后又重新运行,相当于又创建了一个虚拟机也是再用这个VHD文件(虚拟硬盘),就冲突了。 ### 编写脚本启动 run.bat:启动bochs,执行make命令编译代码并写入磁盘,执行 bochs -f bochsrc.bxrc运行。 clean.bat:用于清空编译的代码。 debug.bat:启动调试的bochs ## 6、开启调试 **启动** bochsdbg.exe **命令:** b addr: 在对应地址设置断点。例:b 0x7c00 info break: 显示当前所以断点信息。例:info break c: 继续下执行,直到遇到断点。例:c s: 单步执行。例:s n: 单步执行,遇到函数跳过。例:n info cpu: 查看寄存器信息。例:info cpu r: 查看寄存器信息。例:r fp: 查看寄存器信息。例:fp sreg: 查看寄存器信息。例:sreg creg: 查看寄存器信息。例:creg print-stack: 查看堆栈。例:print-stack xp /nuf addr: 查看内存物理地址内容。例:xp /64bx 0x7c00 x /nuf addr: 查看线性地址内容。例:x /64bx 0x7c00 u start end: 反汇编一段内存。例:u 0x7c00 0x7c0d trace-on: 反汇编执行的每一条指令。例:trace-on trace-reg: 每执行一条指令就显示cpu信息。例:trace-reg bochs常用命令:http://www.bytekits.com/bochs/bochs-intro.html