简易操作系统

再贴个操作系统的,之后也会做个改进(大概)
主要boot就是个引导程序,可以写进U盘来启动,之后会将head程序放入启动位置,head中写了个登陆验证,账号密码都是root,输错会循环,之后就是模拟多任务切换,A是一个程序,B是一个程序
启动

输入root

密码不回显,如果密码错误,循环回去,重新输user和password。如果密码正确(为root),则进入多任务程序。

#boot.s
BOOTSEG = 0x07c0
SYSSEG = 0x1000
SYSLEN = 17
.code16
.section .text
.globl _start
_start:
ljmp $BOOTSEG,$go
go: movw %cs,%ax
movw %ax,%ds
movw %ax,%ss
movw $0x400,%sp
movw %ax,%es
movb %ah,load_msg+17 #加载loading system
movw $20,%cx
movw $0x1004,%dx
movw $0x000c,%bx
movw $load_msg,%bp
movw $0x1301,%ax
int $0x10
load_system:
movw $0x0080,%dx
movw $0x0002,%cx
movw $SYSSEG,%ax
movw %ax,%es
xorw %bx,%bx
movw $0x200+SYSLEN,%ax #加载内核程序
int $0x13
jnc ok_load
die:jmp die
ok_load:
cli
movw $SYSSEG,%ax
movw %ax,%ds
xorw %ax,%ax
movw %ax,%es
movw $0x2000,%cx
subw %si,%si
subw %di,%di
rep
movsw #加载内核程序到0x0
movw $BOOTSEG,%ax
movw %ax,%ds
lidt idt_48
lgdt gdt_48
movw $0x0001,%ax
lmsw %ax
ljmp $8,$0
gdt:.word 0,0,0,0 //全局描述符表,存段基地址
.word 0x07FF
.word 0x0000
.word 0x9A00
.word 0x00C0
.word 0x07FF
.word 0x0000
.word 0x9200
.word 0x00C0
idt_48:.word 0 #中断表,初始为空
.word 0,0
gdt_48:.word 0x7ff
.word 0x7c00+gdt,0
load_msg:.ascii “Loading system…”
.byte 13,10
.org 510
boot_flag:
.word 0xAA55

#head.s
LATCH = 11930
SCRN_SEL = 0x18
TSS0_SEL = 0x20
LDT0_SEL = 0x28
TSS1_SEL = 0x30
LDT1_SEL = 0x38
.code32
.globl startup_32
.text
startup_32:
movl $0x10,%eax
xorw %bx,%bx
mov %ax,%ds
lss init_stack,%esp
call setup_idt
call setup_gdt
call init_keys #加载扫描码转为ascii表
login:
#cli
movl $0x10,%eax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
movl $SCRN_SEL,%ebx
movw %bx,%gs
movl $0,%ebx
call clean #清空显存
movl $0,%ebx
leal logins,%edi #显示user
movl $5,%ecx
loop1:
movb %ds:(%edi),%al
shl $1,%ebx
movb %al,%gs:(%ebx)
shr $1,%ebx
incl %ebx
incl %edi
loop loop1
loop2: #循环等待,直到键盘有按键按下
inb $0x64,%al
testb $1,%al
jz loop2
movl $users,%edi
loop3: #跳过mark 码,记录break 码
inb $0x60,%al
cmpb %al,%dl
jz loop3
movb %al,%dl
cmpb $0,%al
jz loop3
loop9:inb $0x60,%al
cmpb %al,%dl
jz loop9
movb %al,%dl
cmpb $0,%al
jz loop9
movb %al,%ds:(%edi) #回显,写入显存
shl $1,%ebx
leal keys,%ecx
addl %eax,%ecx
movb %ds:(%ecx),%cl
movb %cl,%gs:(%ebx)
shr $1,%ebx
incl %ebx
incl %edi
cmpb $0x9c,%al
jnz loop3
movl $80,%ebx
movl $passws,%edi #显示password
movl $9,%ecx
loop4:
movb %ds:(%edi),%al
shl $1,%ebx
movb %al,%gs:(%ebx)
shr $1,%ebx
incl %ebx
incl %edi
loop loop4
loop5: #循环等待,直到键盘有按键按下
inb $0x64,%al
testb $1,%al
jz loop5
movl $passs,%edi
loop6: #跳过mark 码,记录break 码
inb $0x60,%al
cmpb %al,%dl
jz loop6
movb %al,%dl
cmpb $0,%al
jz loop6
loop10:inb $0x60,%al
cmpb %al,%dl
jz loop10
movb %al,%dl
movb %al,%ds:(%edi)
incl %edi
cmpb $0x9c,%al
jnz loop6
tes: #匹配字符,查看输入是否为root
movl $users,%edi
movb %ds:(%edi),%al
cmpb $0x93,%al
jnz err
incl %edi
movb %ds:(%edi),%al
cmpb $0x98,%al
jnz err
incl %edi
movb %ds:(%edi),%al
cmpb $0x98,%al
jnz err
incl %edi
movb %ds:(%edi),%al
cmpb $0x94,%al
jnz err
movl $passs,%edi
movb %ds:(%edi),%al
cmpb $0x93,%al
jnz err
incl %edi
movb %ds:(%edi),%al
cmpb $0x98,%al
jnz err
incl %edi
movb %ds:(%edi),%al
cmpb $0x98,%al
jnz err
incl %edi
movb %ds:(%edi),%al
cmpb $0x94,%al
jz ok
err: #匹配出错,跳至user,重新输入
movl $0,%ebx
call clean
movl $0,%ebx
leal logins,%edi
movl $5,%ecx
jmp loop1
ok: #匹配成功
movl $160,%ebx
leal oks,%edi
movl $8,%ecx
loop7:
movb %ds:(%edi),%al
shl $1,%ebx
movb %al,%gs:(%ebx)
shr $1,%ebx
incl %ebx
incl %edi
loop loop7
#sti
movl $0x10,%eax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
lss init_stack,%esp
movb $0x36,%al
movl $0x43,%edx
outb %al,%dx
movl $LATCH,%eax #加载时钟
movl $0x40,%edx
outb %al,%dx
movb %ah,%al
outb %al,%dx
movl $0x00080000,%eax
movw $timer_interrupt,%ax #加载定时中断
movw $0x8E00,%dx
movl $0x08,%ecx
lea idt(,%ecx,8),%esi
movl %eax,(%esi)
movl %edx,4(%esi)
movw $system_interrupt,%ax #载入系统中断
movw $0xef00,%dx
movl $0x80,%ecx
lea idt(,%ecx,8),%esi
movl %eax,(%esi)
movl %edx,4(%esi)
pushfl
andl $0xffffbfff,(%esp)
popfl
movl $TSS0_SEL,%eax #装入任务0的tss
ltr %ax
movl $LDT0_SEL,%eax
lldt %ax
movl $0,current
sti
pushl $0x17
pushl $init_stack
pushfl
pushl $0x0f
pushl $task0
iret
setup_gdt:
lgdt lgdt_opcode
ret
setup_idt:
lea ignore_int,%edx
movl $0x00080000,%eax
movw %dx,%ax
movw $0x8E00,%dx
lea idt,%edi
mov $256,%ecx
rp_sidt:
movl %eax,(%edi)
movl %edx,4(%edi)
addl $8,%edi
dec %ecx
jne rp_sidt
lidt lidt_opcode
ret
init_keys:
pushl %ebx
pushl %ecx
leal keys,%ebx
mov %ebx,%ecx
addl $0x1e,%ecx
movb $0x61,%ds:(%ecx)
mov %ebx,%ecx
addl $0x9e,%ecx
movb $0x61,%ds:(%ecx)
mov %ebx,%ecx
addl $0xb0,%ecx
movb $0x62,%ds:(%ecx)
mov %ebx,%ecx
addl $0xae,%ecx
movb $0x63,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa0,%ecx
movb $0x64,%ds:(%ecx)
mov %ebx,%ecx
addl $0x92,%ecx
movb $0x65,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa1,%ecx
movb $0x66,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa2,%ecx
movb $0x67,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa3,%ecx
movb $0x68,%ds:(%ecx)
mov %ebx,%ecx
addl $0x97,%ecx
movb $0x69,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa4,%ecx
movb $0x6a,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa5,%ecx
movb $0x6b,%ds:(%ecx)
mov %ebx,%ecx
addl $0xa6,%ecx
movb $0x6c,%ds:(%ecx)
mov %ebx,%ecx
addl $0xb2,%ecx
movb $0x6d,%ds:(%ecx)
mov %ebx,%ecx
addl $0xb1,%ecx
movb $0x6e,%ds:(%ecx)
mov %ebx,%ecx
addl $0x98,%ecx
movb $0x6f,%ds:(%ecx)
mov %ebx,%ecx
addl $0x99,%ecx
movb $0x70,%ds:(%ecx)
mov %ebx,%ecx
addl $0x90,%ecx
movb $0x71,%ds:(%ecx)
mov %ebx,%ecx
addl $0x93,%ecx
movb $0x72,%ds:(%ecx)
mov %ebx,%ecx
addl $0x9f,%ecx
movb $0x73,%ds:(%ecx)
mov %ebx,%ecx
addl $0x94,%ecx
movb $0x74,%ds:(%ecx)
mov %ebx,%ecx
addl $0x96,%ecx
movb $0x75,%ds:(%ecx)
mov %ebx,%ecx
addl $0xaf,%ecx
movb $0x76,%ds:(%ecx)
mov %ebx,%ecx
addl $0x91,%ecx
movb $0x77,%ds:(%ecx)
mov %ebx,%ecx
addl $0xad,%ecx
movb $0x78,%ds:(%ecx)
mov %ebx,%ecx
addl $0x95,%ecx
movb $0x79,%ds:(%ecx)
mov %ebx,%ecx
addl $0xb9,%ecx
movb $0x7a,%ds:(%ecx)
popl %ecx
popl %ebx
ret
clean:
shl $1,%ebx
movb $0,%gs:(%ebx)
mov %ebx,%ecx
incl %ecx
movb $0x7,%gs:(%ecx)
shr $1,%ebx
incl %ebx
cmpl $2000,%ebx
jb clean
ret
write_char:
push %gs
pushl %ebx
pushl %ecx
movl $SCRN_SEL,%ebx
movw %bx,%gs
movl scr_loc,%ebx
shl $1,%ebx
movb %al,%gs:(%ebx)
mov %ebx,%ecx
incl %ecx
movb $0x7,%gs:(%ecx)
shr $1,%ebx
incl %ebx
cmpl $2000,%ebx
jb 1f
movl $0,%ebx
1: movl %ebx,scr_loc
popl %ecx
popl %ebx
pop %gs
ret
.align 2
ignore_int:
push %ds
pushl %eax
movl $0x10,%eax
movw %ax,%ds
movl $67,%eax
call write_char
popl %eax
pop %ds
iret
.align 2
timer_interrupt: #定时中断,切换任务0和任务1,分别载入二者tss
push %ds
pushl %eax
movl $0x10,%eax
movw %ax,%ds
movb $0x20,%al
outb %al,$0x20
movl $1,%eax
cmpl %eax,current
je 1f
movl %eax,current
ljmp $TSS1_SEL,$0
jmp 2f
1:
movl $0,current
ljmp $TSS0_SEL,$0
2:
popl %eax
pop %ds
iret
.align 2
system_interrupt:
push %ds
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
movl $0x10,%edx
movw %dx,%ds
call write_char
popl %eax
popl %ebx
popl %ecx
popl %edx
pop %ds
iret
current:.long 0
scr_loc:.long 0
.align 2
lidt_opcode:
.word 256*8-1
.long idt
lgdt_opcode:
.word (end_gdt-gdt)-1
.long gdt
.align 8
idt:.fill 256,8,0
gdt:.quad 0x0000000000000000
.quad 0x00c09a00000007ff
.quad 0x00c09200000007ff
.quad 0x00c0920b80000002
.word 0x0068,tss0,0xe900,0x0
.word 0x0040,ldt0,0xe200,0x0
.word 0x0068,tss1,0xe900,0x0
.word 0x0040,ldt1,0xe200,0x0
end_gdt:
.fill 128,4,0
init_stack:
.long init_stack
.word 0x10
.align 8
ldt0:.quad 0x0000000000000000
.quad 0x00c0fa00000003ff
.quad 0x00c0f200000003ff
tss0:.long 0
.long krn_stk0,0x10
.long 0,0,0,0,0
.long 0,0,0,0,0
.long 0,0,0,0,0
.long 0,0,0,0,0,0
.long LDT0_SEL,0x80000000
.fill 128,4,0

krn_stk0:

.align 8
ldt1:.quad 0x0000000000000000
.quad 0x00c0fa00000003ff
.quad 0x00c0f200000003ff
tss1:.long 0
.long krn_stk1,0x10
.long 0,0,0,0,0
.long task1,0x200
.long 0,0,0,0
.long usr_stk1,0,0,0
.long 0x17,0x0f,0x17,0x17,0x17,0x17
.long LDT1_SEL,0x80000000
.fill 128,4,0
krn_stk1:

logins:.ascii “user:!”

users:.fill 20,1,0

passws:.ascii “password:”

passs:.fill 32,1,0

oks:.ascii “corrent!”

errs:.ascii “Error!”

keys:.fill 256,1,0

task0: #任务0,打印A
movl $0x17,%eax
movw %ax,%ds
movb $65,%al
int $0x80
movl $0xfff,%ecx
1: loop 1b
jmp task0
task1: #任务1,打印B
movl $0x17,%eax
movw %ax,%ds
movb $66,%al
int $0x80
movl $0x0fff,%ecx
1: loop 1b
jmp task1
.fill 128,4,0
usr_stk1:

发表评论

电子邮件地址不会被公开。 必填项已用*标注