进一步提高代码的高级程度,在之前的代码基础上修改,所以先拷贝再重命名为helloos.nas:
感觉还是添加个git比较方便,等helloos3完成后添加个git,这样可以保留历史,而不用每次都被覆盖了。
---------------------------------
先回顾下昨天的程序结构:
只有显示部分,昨天看懂了,继续2016年9月7日18:37:10,说实话那个
因为只能提醒很麻烦,所以取消notepad++自动补全:
?
?
下面把对代码的注释添加上:
寄存器:
?
?
X表示扩展的意思extend
可以看到,一共8个寄存器,共16个字节
段寄存器:
内存:超大规模的存储单元"住宅区"。
关键字:BYTE WORD DWORD
内存存储单元的单位是1个字节,注意了!
SI 是源变址寄存器的意思啊,就是source index的意思啊
可以用来指定内存地址的寄存器:BX\BP\SI\DI
BP指的是基址指针寄存器
为什么有的东西不能用呢?因为:
MOV BX, DX
MOV AL, BYTE [BX]
?
?
可以把中断理解为一种外部GOTO,我们知道GOTO随便跳,但再怎么跳还是在程序自己看得到的空间里面。
而BIOS程序则在另外一个空间里面,如果你想到那个空间,你可以发送中断,但是本质而言中断无非是一种特殊的GOTO而已罢了。
http://community.osdev.info/?(AT)BIOS 到这个页面可以搜索中断相关的东西,不懂日文没有关系,可以到百度翻译主页下载个网页翻译插件,目前看到最方便的就是这个插件了。
?
?
继续
操作显卡(函数放在BIOS服务集里面也就是函数集合)--》
本质上和操作其他硬件设备是一样的--显卡就是一个对象--》
对象就是数据结构(比如结构体套结构体)--》
操作显卡就是操作数据结构--也就是函数--》
要进入实模式RM里面调用
在上面那个网站上弄了半天,没搜到,直接在谷歌上搜了, http://wiki.osdev.org/BIOS 搜到这个页面:可以理解INT的含义啊。
HLT (x86 instruction)的时候,CPU做什么工作啊!为什么可以省电???难道CPU不工作了吗???和死循环有什么区别???
中断:设备发给CPU(中断驱动)的信号。设备什么时候发呢?比如定时器到了,就向早晨闹钟设备给你大脑发送信号一样。
CPU进入浅睡眠状态,先这么理解着吧,不然这书又要中断了,有时间看下这篇What Does an Idle CPU Do?
【内存分布】
代码理解完了,run一下看看:
没反应,对了先编译:
失败,估计汇编代码错了:哪里错了?
这样改了之后还是错:直接对比二进制看看哪里不一样吧?
BZ.exe可以比较多个二进制文件:
?
?
右边是可以运行的软盘映像二进制,可以看到0x01fe(510)-0x01ff(511)应该填55AA,因为:
?
?
?
但是根据我的汇编代码啊,根本不可能执行 DB 0X55, 0XAA了:
所以,进入到更高级的汇编代码部分,再也不想昨天只有DB/DW/DD/RESB这四种变相二进制填充指令了,所以必须有新的手段来建立启动区(启动区也是有文件系统的,这样BIOS才能识别吧,我猜的!)
【添加GIT】
以tolset目录作为git目录:
等之后确保Git使用没问题后,会上传到Github算做个备份吧,到时再弄。
为步骤helloos4做准备,操作系统是从无到有,一点点添加新功能,一点点测试通过的,所以helloos-n就对应着每个开发阶段,为了体现项目的演变,直接在前一个阶段的hellos3的目录上做修改,把helloos3重名为helloos4,表示进入helloso4阶段。
- helloos.nas的后半部分截掉(因为已经引入了GIT,所以再也不用每次都复制重命名了),启动区只要512字节;
- asm.bat-->ipl.bin 顺便输出ipl.lst反汇编文件,之前第二天的所谓汇编代码汇编后本质上就是个整个磁盘的二进制所谓机器码;
- 增加 makeimg.bat 以ipl.bin为基础,制作磁盘映像文件。
- 把其他不需要的删了(因为有GIT,可以恢复之前的版本,就又把删的找回来了,所以可以删了,清爽)
- 最后只要启动!cons 输入asm编译--》makeimg制作系统光盘--》run开机启动,这样一来比重装系统牛逼多了,因为系统也自己做的,然后光盘也自己做的,你可以多做几张光盘拿出去卖!
?
?
【制作启动区】
IPL
?
?
【Makefile入门】
Linux里用Makefile比较多,没想到windows下也能愉快地用这个,看来思维又局限到Linux下了。
看到:
它是说之前的程序是对的,我还以为不对呢!
那就用Git退回去吧,要退回去要先提交当前的状态,否则退不回去:
?
?
好的退回去了:重新打开helloos.nas,检查了发现一个大错误ox7coo应该是0x7c00
?
?
对比了一下生成的二进制镜像:
可以发现我生成的是大端格式,作者的是小端格式,不知道什么原因:
反正还是错了:
对照作者提供的程序修改下:
真是奇了怪了:我修改了和作者一样,但是编译后的55AA位置却不在0x1fe那个地方:
而是提前了,但是,BIOS是靠检测这个识别这个512字节的,然后确认这个是启动区,然后从头开始执行,然后是一条跳转JMP entry,跳到真正程序的地方。对比发现我第二个字节就错了:
看了0x4e应该是个南哥跳转指令了,那么肯定是我中途文件系统那块地方错了:
修改了之后,对比二进制文件,4e这次对了,但是55aa还是错了:
这是怎么回事?幸好有参考代码,对比了下发现了问题:
真是个大坑,原来:
?
?
好了,修改后终于好了:
总结下,之前程序总共错了三个地方:
- 0x7c00 把其中的0全部写成了字母o;
- 没有理解ORG代码的含义,没有理解原来机器码的含义;
- 没有理解地址偏移意味着所以地址编译器特殊处理;
- 好像本来也是小端字节存储的啊。
重新提交一下,不过现在版本有些混乱啊:
这里主要用到git rebase命令,《Git小书》小篇幅把这个简单用法讲清楚了。
这里说下一些命令的用法吧:
- 仓库--暂存区--工作区:如果此时工作区有一个文件发生了修改,如果你不想要这个修改,可以
git checkout filename
- 切换到之前的某个版本 git checkout 版本ID
- 好的,如果你切换到之前的某个版本,然后修改了文件,然后再次git commit,此时就多出一个无名分支:如何为这个分支创建一个名称呢:操作如下命令 git checkout -b <new-branch-name>
- 普通删除分支 git branch -d test
- 强制删除分支 git branch -D test
- 记得在做分支操作的时候保证git staus没有提示有更改的文件
?
?
1<--2<--4<--5<--master
|
3<--6<--test
如果你要把3<--6插入到2和4之间,也就是要变成:
1<--2<--3<--6<--4<--5这个样子,做法是先切换到2<--3<--6这个分支,然后操作 git rebase master意思是把当前分支test衍合到master分支上,最终得到:
看下git操作历史:
推送到github备份下,推送就用图形界面吧,下载SourceTree软件吧,因为Github客户端总是下载失败:
- 初次安装后:
- 登录后,然后可以跳过克隆步骤;
- 它要求添加PPK格式秘钥,暂时不知道是什么意思,因为Github没有要求这个。
你可以点击YES看下,要PPK,不懂,暂时选择NO吧,卡住的时候再回头即可。
-
打开那个git目录即可:
选择文件夹之后就进入了仓库界面,还是很直观的:
- 然后就是怎么同步到Github了。首先到Github上新建个空仓库:30_OS_tolset
- 推送到远程仓库,命令行可以这么操作
git remote add origin https://github.com/study-note/30_OS_tolset.git
git push -u origin master
这里是图形界面操作方式:
首先是添加远程仓库,类似git remote add origin https:..git的功能:
选择菜单:
输入如下,和git remote add后填充的一样:
- 添加完远程仓库,现在就是推送了,类似git push -u origin master
因为test1分支没用了,所以先删除:
好了,现在推送master分支就可以了(注意你可以选择推送指定的分支,也就是推送是以分支为单位的):
点击推送图形按钮即可:
会再次提示你输入用户名和密码,输入即可。
这个等待稍微有点慢...耐心等待它pushing完成...
好了,完成!到项目主页上看下效果:成功推送,网站主要是方便分布合作、在线集成的、备份之类。
- 到此Git就完成了,其他项目都是都是类似的操作步骤。
?
?
【好了,刚才中断去处理错误了,回到Makefile入门】
这部分稍微有点乱,我是先看完了然后回头做个笔记,不过这段关于Makefile功能的解释真的很棒。
MOV BX, DX
MOV AL, BYTE [BX] AX\CX\DX\SP不能用来指定内存地址,BX\BP\SI\DI可以用寄存器来指定内存地址
----------------------------------------
我们的源文件是ipl.nas(把helloos.nas重名为ipl.nas,因为之前是生成整个映像,现在这个文件只生成ipl),因为之前我们为了生成整个软盘镜像,所以在源码中加入了启动区外代码,目的就是为了让汇编器帮助我们填充512字节之外的内容:里面填充的一些个别特殊的字符不懂是啥用,估计是软盘这么规定的吧,后面再说吧。
现在把这部分删掉,也就是把我们的代码编译器成512字节就好了。
注意:nask.exe既可以直接编译生成.img,也可以生成中间文件.bin,然后再生成.img文件。
----------------------------------------
接着编写Makefile文件,目的是生成.bin,然后再生成.img
解释:
把tolset/z_new_w/make.bat/拷贝到当前目录:
运行icons_nt.bat
输入 make ipl.bin 成功执行
书上加了个选项-r,我不太清楚是干嘛用的,因为好像没区别嘛,具体见这个网页GNU make: Options Summary
先来看下反汇编的结果ipl.lst:
接着查看ipl.bin的二进制格式,这个二进制格式看到的就应该是上面反汇编的那个机器码:
给Notepad++安装HEX-Editor插件
查看ipl.bin文件,可以看到确实正好是512个字节的二进制:
make 默认生成第一目标
------------------------------------------
再生成img看看: make -r helloos.img
生成成功:
Makefile是很智能的,它会遍历生成,如果你直接输入make -r helloos.img会中途生成helloos.bin
来试一下:
首先删除生成的东西:
然后输入 make -r helloos.img
可以看到确实如此啊。
如果我们重复执行 make -r helloos.img,因为make.exe自动检测到已经生成了,而且,helloos.img的依赖文件没有发生修改,这个是很智能的一件事:实验一下,确实如此
我们把输出显示改一下,看看:
我们不需要删除生成的文件,因为make新生成的文件回覆盖原来的:
成功了!
但是每次都要输入这么一个长命令实在麻烦,批处理其实是个偷懒的工具:
运行一下看看:
注意:纯bat批处理的目录分隔符是\(正好和转移字符冲突\),而Ubuntu里面都是/,改成:
这样就好了:
至此,生成一个提交,接下来进入helloos5阶段:
可视化看看分支变化:
?
?
----------------------------------------Makefile实在是高明啊
make可以智能处理目标的依赖关系
那么还能做成什么呢?如果我们把生成目标变成一个没有依赖的虚拟目标文件,它就会直接执行下面的命令了:
?
好了,Makefile用处,bat皆亡,makeimg.bat可以歇菜了!
我们再把文件里面的其他bat全部用Makefile实现:
bat一篇哀嚎啊!
就好比有了智能机器人,工厂失业一片啊。
注意了bat脚本不能在Git shell里面执行,要在CMD里面执行:
如何在特定目录下启动CMD呢?按住 shift,然后右键,看看效果:
?
?
出错了,到网上搜到一个答案:Copy a file using a makefile at runtime
直接运行copy没有任何问题,但是放到make里面,win7系统版本出问题了,改成:
xcopy /y
在DOS里 "\"是目录分隔符 目录和子目录之间的分隔作用
"/"参数符 这个符号后面DOS全部认为是参数
此时在Git Shell里面也可以运行了:
这次就好了:
成功
------------------------------------------
再增强一下Makefile的功能:
- 添加make clean删除中间文件,但不删除img文件
测试:
- 添加make src_only,把源程序以外的文件全部删除干净,也就是img文件了,包含了make clean
测试:
出错,添加 -f 参数:解决方案参考Delete files in directory without erroring if it‘s already empty
测试:
测试通过!
- 增加make命令的默认动作,当执行不带参数的make时,就相当于执行"make img"命令(默认动作写在Makefile的最前头
测试:
测试通过!
最后把目录清理一下--提交--推送--完成第二天的任务:
第2天结束:2016年9月8日15:23:26