- 首先需要在MAC中安装brew,类似linux环境下的apt-get以及python中的pip,具体教程见(官网)https://brew.sh
- 安装好brew后,安装交叉编译环境,具体原因是mac电脑里的gcc是适配MAC环境的,其资料相对较少,不易于开发,所以我们需要安装x86_64-elf工具链,适配于LINUX环境,资料很多,输入以下命令即可安装2个工具包:
brew install x86_64-elf-binutils
brew install x86_64-elf-gcc
- 在安装好以上2个工具包后,即可开发OS,现在我们将之前LINUX环境下开发的小OS移植到MAC环境中,代码如下:
bootsector.S
.text
.code16
.global start
start:
movw %cs,%ax
movw %ax,%ds # ->Data Segment
movw %ax,%es # ->Extra Segment
movw %ax,%ss # ->Stack Segment
movl $0x7C00,%esp
cli#内存探测
#内存地址0x8000作为内存探测段数的存储地址,方便后面调用
movw $0,0x8000
movw $0x8004,%di
xor %ebx,%ebx
mm_probe:
movl $0xe820,%eax
movl $20,%ecx
movl $0x534D4150,%edx
int $0x15
#产生进位则跳转
jnc cont
jmp probe_end
cont:
incl 0x8000
addw $20,%di
cmpl $0,%ebx
jnz mm_probe
probe_end:
#开A20
/*
waitforbuffernull1:
#先确定8042是不是为空,如果不为空,则一直等待
xorl %eax,%eax
inb $0x64,%al
testb $0x2,%al
jnz waitforbuffernull1
#8042中没有命令,则开始向0x64端口发出写P2端口的命令
movb $0xd1,%al
outb %al,$0x64
waitforbuffernull2:
#再确定8042是不是为空,如果不为空,则一直等待
xorl %eax,%eax
inb $0x64,%al
testb $0x2,%al
jnz waitforbuffernull2
#向0x60端口发送数据,即把P2端口设置为0xdf
movb $0xdf,%al
outb %al,$0x60
*/
lgdt gdt_48movl %cr0,%eax
orl $0x1,%eax
movl %eax,%cr0ljmp $0x8,$promode
promode:
.code32
movw $0x10,%ax
movw %ax,%ds #->Data Segment
movw %ax,%es #->Extra Segment
movw %ax,%ss #->Stack Segmentmovw $0x18,%ax
movw %ax,%gs
/*movl $((80*1+1)*2),%edi #第11行,79列
movb $0x0c,%ah #高四位表示黑底,低四位表示红字
movb $'B',%al #显示的字符
movw %ax,%gs:(%edi) */
movl $0x0,%ebp
movl $start,%esp
call bootmain
#在内存中做一块GDT表
.align 2
gdt:
.word 0,0,0,0
.word 0xFFFF #第1项CS,基地址为0
.word 0x0000
.word 0x9A00
.word 0x00C0.word 0xFFFF #第2项DS,基地址为0
.word 0x0000
.word 0x9200
.word 0x00C0.word 0xFFFF #第3项VGA,基地址位0xb8000
.word 0x8000
.word 0x920b
.word 0x0000
#将gdtr专用寄存器指向我们在内存中做的一块GDT表,GDTR寄存器格式:48位(高32位地址+低16位限长),intel是小端方式
gdt_48:
#gdt表限长 sizeof(gdt)-1 低地址,放在gdtr的低字节
.word 0x1f
#gdt表基址 高地址,放在gdtr的高字节
.long gdt
#.org 0x1fe,0x00 # 0x1fe=510,表示从ret后的位置开始,直到510处结束的代码/数据空间,填写0x00
#.word 0xaa55 #合法的主引导扇区标识