Appearance
day3进入32位系统以及C语言
assembly
; haribote-ipl
; TAB=4
ORG 0x7c00 ; 程序的地址
;
JMP entry
DB 0x90
DB "HARIBOTE"
DW 512
DB 1
DW 1
DB 2
DW 224
DW 2880
DB 0xf0
DW 9
DW 18
DW 2
DD 0
DD 2880
DB 0,0,0x29
DD 0xffffffff
DB "HARIBOTEOS "
DB "FAT12 "
RESB 18
;
entry:
MOV AX,0 ; 初始化寄存器
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX ;设置段地址
;
MOV AX,0x0820
MOV ES,AX ;设置读取后的位置
MOV CH,0 ; 设置柱面
MOV DH,0 ; 设置柱头
MOV CL,2 ; 设置扇面
MOV AH,0x02 ; AH=0x02 : 读盘
MOV AL,1 ; 1个扇区
MOV BX,0 ;设置读取文件存放的位置
MOV DL,0x00 ; A驱动器
INT 0x13 ; 调用BIOS
JC error ; 如果进位标志为1, 就进行跳转
; 这里是成功之后的死循环
fin:
HLT
JMP fin
; 打印错误信息
error:
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1
CMP AL,0
JE fin
MOV AH,0x0e
MOV BX,15
INT 0x10
JMP putloop
msg:
DB 0x0a, 0x0a
DB "load error"
DB 0x0a
DB 0
RESB 0x7dfe-$
DB 0x55, 0xaa
INT0x13: AH=0x02读盘, AH=0x03写盘, AH=0x04校验, AH=0x0c巡道, AL=处理的扇区数, CH=柱面号, DH=磁头号, DL=驱动器号, ES:BX=缓冲地址, 校验以及寻道的时候不需要, 返回值FLACS:CF=0, 没有错误AH=0, FLAGCS:CF=1, 有错误, 存入AH
设置的是软盘的读取, 一个软盘有80个柱面, 2个磁头, 18个扇区
BX设置的是读取的文件存放的位置, 只有16位, 使用的时候可以使用
MOV AL,[ES:BX]
, 实际上是ES*16+BX, 达到1M的大小
这里设置ES=0x8020, 原因是0x8000~0x81ff的位置是启动区的, 之后的内存是随意使用的
0x7c00到0x7dff的位置是启动区, 之后0x7e00到0x9fbff没有规定
在使用的时候, 需要注意段寄存器,DS, 在不表示的情况下一般可以省略, MOV CX,[SI]实际上是MOV AL,[DS:SI]
改进一次
assembly
; 初始化寄存器
entry:
MOV AX,0 ; レジスタ初期化
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
; 读磁盘
MOV AX,0x0820
MOV ES,AX
MOV CH,0 ; 柱面0
MOV DH,0 ; 磁头0
MOV CL,2 ; 扇区0
MOV SI,0 ; 记录失败的次数
retry:
MOV AH,0x02
MOV AL,1
MOV BX,0
MOV DL,0x00
INT 0x13
JNC fin
ADD SI,1 ; SI加一
CMP SI,5 ; SI比较
JAE error ; SI >= 5 出错
MOV AH,0x00
MOV DL,0x00 ;
INT 0x13 ; 设置系统复位
JMP retry
读取到18
assembly
; 读磁盘
MOV AX,0x0820
MOV ES,AX
MOV CH,0
MOV DH,0
MOV CL,2
readloop:
MOV SI,0
retry:
MOV AH,0x02 ; AH=0x02 : 读取
MOV AL,1 ; 一个扇区
MOV BX,0
MOV DL,0x00 ; A驱动器
INT 0x13 ; 调用BIOS
JNC next ; 出错跳到next
ADD SI,1 ; SIに1を足す
CMP SI,5 ; SIと5を比較
JAE error ; SI >= 5 だったらerrorへ
MOV AH,0x00
MOV DL,0x00 ; Aドライブ
INT 0x13 ; ドライブのリセット
JMP retry
next:
MOV AX,ES ; 内存地址后移
ADD AX,0x0020 ; 相当于加上0x200
MOV ES,AX ; 写入ES
ADD CL,1 ; CL加1
CMP CL,18 ; CL与18比较
JBE readloop ; CL <= 18 继续读取
- 增加读取到反面
assembly
CYLS EQU 10 ; 相当于define
.....
;
MOV AX,0x0820
MOV ES,AX
MOV CH,0 ; シリンダ0
MOV DH,0 ; ヘッド0
MOV CL,2 ; セクタ2
readloop:
MOV SI,0 ; 失敗回数を数えるレジスタ
retry:
MOV AH,0x02
MOV AL,1
MOV BX,0
MOV DL,0x00
INT 0x13
JNC next
ADD SI,1
CMP SI,5
JAE error
MOV AH,0x00
MOV DL,0x00
INT 0x13 ; ドライブのリセット
JMP retry
next:
MOV AX,ES
ADD AX,0x0020
MOV ES,AX
ADD CL,1
CMP CL,18
JBE readloop
MOV CL,1 ; 归零
ADD DH,1 ; 更换柱头, 加一, 第二次加一之后会进入后面的程序
CMP DH,2 ;进行比较
JB readloop ; DH<2
MOV DH,0 ; 设置柱头归零
ADD CH,1 ; 设置柱面加一
CMP CH,CYLS
JB readloop ; CH < CYLS だったらreadloopへ
C0-H0-S18到C0-H1-S1再到C9-H1-S18
最初的180KB存入内存
- 添加其他文件
assembly
fin:
HLT
JMP fin
makefile
TOOLPATH = ../z_tools/
MAKE = $(TOOLPATH)make.exe -r
NASK = $(TOOLPATH)nask.exe
EDIMG = $(TOOLPATH)edimg.exe
IMGTOL = $(TOOLPATH)imgtol.com
COPY = copy
DEL = del
# デフォルト動作
default :
$(MAKE) img
# ファイル生成規則
ipl.bin : ipl.nas Makefile
$(NASK) ipl.nas ipl.bin ipl.lst
haribote.sys : haribote.nas Makefile
$(NASK) haribote.nas haribote.sys haribote.lst
haribote.img : ipl.bin haribote.sys Makefile
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl.bin len:512 from:0 to:0 \
copy from:haribote.sys to:@: \
imgout:haribote.img
# コマンド
img :
$(MAKE) haribote.img
run :
$(MAKE) img
$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin
$(MAKE) -C ../z_tools/qemu
install :
$(MAKE) img
$(IMGTOL) w a: haribote.img
clean :
-$(DEL) ipl.bin
-$(DEL) ipl.lst
-$(DEL) haribote.sys
-$(DEL) haribote.lst
src_only :
$(MAKE) clean
-$(DEL) haribote.img
软盘上在0x002600设置的是文件名的位置, 0x004200的位置是文件的内容
程序的调用: 软盘的程序被复制到0x8000之后, 程序在0xc200
assembly; haribote-os ; TAB=4 ORG 0xc200 ; 偙偺僾儘僌儔儉偑偳偙偵撉傒崬傑傟傞偺偐 MOV AL,0x13 ; VGA僌儔僼傿僢僋僗丄320x200x8bit僇儔乕 MOV AH,0x00 INT 0x10 fin: HLT JMP fin
这里可以设置显示的模式, AH=0x00, AL=模式, 0x30: 16色模式, 0x12VGA图形模式640x480x4, 0x12VGA图形模式320x200x8, 调色板模式, 0x6a扩展VGA模式800x600x4
assembly
MOV [0x0ff0],CH ; 记录读取的扇区数
JMP 0xc200 ; 跳转到程序
进入32位
16位的机器码在32位时候不能使用, 32位可以使用的内存变大, 而且可以使用CPU的自我保护模式但是不能使用BIOS
assembly
; haribote-os
; TAB=4
; BOOT_INFO娭學
CYLS EQU 0x0ff0 ; 设定启动区
LEDS EQU 0x0ff1
VMODE EQU 0x0ff2 ; 设定颜色的数目
SCRNX EQU 0x0ff4 ; 分辨率x
SCRNY EQU 0x0ff6 ; Y
VRAM EQU 0x0ff8 ; 图像缓冲区的位置
ORG 0xc200 ; 程序的保存地址
MOV AL,0x13 ; 设置显卡
MOV AH,0x00
INT 0x10
MOV BYTE [VMODE],8 ; 记录画面模式
MOV WORD [SCRNX],320
MOV WORD [SCRNY],200
MOV DWORD [VRAM],0x000a0000
; 使用BIOS获取键盘上的各种LED的状态
MOV AH,0x02
INT 0x16 ; keyboard BIOS
MOV [LEDS],AL ; 保存状态
fin:
HLT
JMP fin
不同模式下的VRAM的位置不同
正式进入C语言
assembly
; haribote-os boot asm
; TAB=4
BOTPAK EQU 0x00280000 ; 设置地址
DSKCAC EQU 0x00100000 ;
DSKCAC0 EQU 0x00008000 ;
; BOOT_INFO记录
CYLS EQU 0x0ff0
LEDS EQU 0x0ff1
VMODE EQU 0x0ff2
SCRNX EQU 0x0ff4
SCRNY EQU 0x0ff6
VRAM EQU 0x0ff8
ORG 0xc200
; 设置显示
MOV AL,0x13 ; VGA僌儔僼傿僢僋僗丄320x200x8bit僇儔乕
MOV AH,0x00
INT 0x10
MOV BYTE [VMODE],8 ; 夋柺儌乕僪傪儊儌偡傞乮C尵岅偑嶲徠偡傞乯
MOV WORD [SCRNX],320
MOV WORD [SCRNY],200
MOV DWORD [VRAM],0x000a0000
; 读取键盘
MOV AH,0x02
INT 0x16 ; keyboard BIOS
MOV [LEDS],AL
MOV AL,0xff
OUT 0x21,AL
NOP ;
OUT 0xa1,AL
CLI ;
;
CALL waitkbdout
MOV AL,0xd1
OUT 0x64,AL
CALL waitkbdout
MOV AL,0xdf ; enable A20
OUT 0x60,AL
CALL waitkbdout
;
[INSTRSET "i486p"] ; 486
LGDT [GDTR0] ;
MOV EAX,CR0
AND EAX,0x7fffffff ;
OR EAX,0x00000001 ;
MOV CR0,EAX
JMP pipelineflush
pipelineflush:
MOV AX,1*8 ;
MOV DS,AX
MOV ES,AX
MOV FS,AX
MOV GS,AX
MOV SS,AX
; bootpack偺揮憲
MOV ESI,bootpack ;
MOV EDI,BOTPAK ;
MOV ECX,512*1024/4
CALL memcpy
;
;
MOV ESI,0x7c00 ;
MOV EDI,DSKCAC ;
MOV ECX,512/4
CALL memcpy
;
MOV ESI,DSKCAC0+512 ;
MOV EDI,DSKCAC+512 ;
MOV ECX,0
MOV CL,BYTE [CYLS]
IMUL ECX,512*18*2/4 ;
SUB ECX,512/4 ;
CALL memcpy
;
;
;
MOV EBX,BOTPAK
MOV ECX,[EBX+16]
ADD ECX,3 ;
SHR ECX,2 ;
JZ skip ;
MOV ESI,[EBX+20] ;
ADD ESI,EBX
MOV EDI,[EBX+12] ;
CALL memcpy
skip:
MOV ESP,[EBX+12] ;
JMP DWORD 2*8:0x0000001b
waitkbdout:
IN AL,0x64
AND AL,0x02
JNZ waitkbdout ;
RET
memcpy:
MOV EAX,[ESI]
ADD ESI,4
MOV [EDI],EAX
ADD EDI,4
SUB ECX,1
JNZ memcpy ;
RET
;
ALIGNB 16
GDT0:
RESB 8 ;
DW 0xffff,0x0000,0x9200,0x00cf ;
DW 0xffff,0x0000,0x9a28,0x0047 ;
DW 0
GDTR0:
DW 8*3-1
DD GDT0
ALIGNB 16
bootpack:
c
void HariMain(void)
{
fin:
/* C语言不能使用HLT, 这里是一个循环 */
goto fin;
}
编译
- cc1.exe从bootpack.c生成bootpack.gas, 使用C编译器, 转换为汇编
- gas2nask.exe从bootpack.gas生成bootpack.nas, 机器语言
- nask.exe从bootpack.nas生成bootpack.obj, 目标文件, 是一种特殊的机器语言文件, 需要链接使用
- 使用obj2bim.exe从bootpack.obj生成bootpack.bim, 二进制镜像文件, 需要针对不同的操作系统加上头文件以及压缩等
- 使用bim2hrb.exe从bootpack.bim生成bootpack.hrb为机器语言
- 最后使用copy把bootpack.hrb和bootpack.hrb文件粘贴起来, 生成haribote.sys
makefile
TOOLPATH = ../z_tools/
INCPATH = ../z_tools/haribote/
MAKE = $(TOOLPATH)make.exe -r
NASK = $(TOOLPATH)nask.exe
CC1 = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet
GAS2NASK = $(TOOLPATH)gas2nask.exe -a
OBJ2BIM = $(TOOLPATH)obj2bim.exe
BIM2HRB = $(TOOLPATH)bim2hrb.exe
RULEFILE = $(TOOLPATH)haribote/haribote.rul
EDIMG = $(TOOLPATH)edimg.exe
IMGTOL = $(TOOLPATH)imgtol.com
COPY = copy
DEL = del
#
default :
$(MAKE) img
# 生成文件
ipl10.bin : ipl10.nas Makefile
$(NASK) ipl10.nas ipl10.bin ipl10.lst
asmhead.bin : asmhead.nas Makefile
$(NASK) asmhead.nas asmhead.bin asmhead.lst
bootpack.gas : bootpack.c Makefile
$(CC1) -o bootpack.gas bootpack.c
bootpack.nas : bootpack.gas Makefile
$(GAS2NASK) bootpack.gas bootpack.nas
bootpack.obj : bootpack.nas Makefile
$(NASK) bootpack.nas bootpack.obj bootpack.lst
naskfunc.obj : naskfunc.nas Makefile
$(NASK) naskfunc.nas naskfunc.obj naskfunc.lst
bootpack.bim : bootpack.obj naskfunc.obj Makefile
$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \
bootpack.obj naskfunc.obj
# 3MB+64KB=3136KB
bootpack.hrb : bootpack.bim Makefile
$(BIM2HRB) bootpack.bim bootpack.hrb 0
haribote.sys : asmhead.bin bootpack.hrb Makefile
copy /B asmhead.bin+bootpack.hrb haribote.sys
haribote.img : ipl10.bin haribote.sys Makefile
$(EDIMG) imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl10.bin len:512 from:0 to:0 \
copy from:haribote.sys to:@: \
imgout:haribote.img
# コマンド
img :
$(MAKE) haribote.img
run :
$(MAKE) img
$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin
$(MAKE) -C ../z_tools/qemu
install :
$(MAKE) img
$(IMGTOL) w a: haribote.img
clean :
-$(DEL) *.bin
-$(DEL) *.lst
-$(DEL) *.gas
-$(DEL) *.obj
-$(DEL) bootpack.nas
-$(DEL) bootpack.map
-$(DEL) bootpack.bim
-$(DEL) bootpack.hrb
-$(DEL) haribote.sys
src_only :
$(MAKE) clean
-$(DEL) haribote.img
实现HLT
assembly
; naskfunc
; TAB=4
[FORMAT "WCOFF"] ; 文件格式
[BITS 32] ; 32位操作系
; 制作目标文件的名字
[FILE "naskfunc.nas"] ; 此文件名
GLOBAL _io_hlt ; 函数名
;
[SECTION .text] ; 目?文件中写入?些再?行
_io_hlt: ; void io_hlt(void);
HLT
RET ; 相当于return
JiaoOS
- 移植OLED
- 触摸屏
- LED
- 串口
出现问题, 没有定义
- 使用__inline在C99模式下前面加static
- 文件没有添加
c
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_ili9341_lcd.h"
#include "bsp_xpt2046_lcd.h"
void Hareware_Init(void);
int main()
{
int i;
Hareware_Init();
while(1){
XPT2046_TouchEvenHandler();
for(i=0;i<10000;i++);
}
}
void Hareware_Init(void)
{
//初始化串口
USART_Config();
LED_GPIO_Config();
printf("你好\n");
//初始化屏幕
ILI9341_Init();
printf("初始化屏幕\n");
ILI9341_Clear(0, 0, ILI9341_LESS_PIXEL, ILI9341_MORE_PIXEL);
//从FLASH里获取校正参数,若FLASH无参数,则使用模式3进行校正
Calibrate_or_Get_TouchParaWithFlash(3,0);
XPT2046_Init();
printf("初始化触摸屏\n");
}