linux0.00由两个文件组成:boot.s(引导代码),head.s(运行代码)。程序最终在屏幕上不断打印A(任务1)和B(任务2)以及C(系统中断处理)。
boot.s代码:
bootseg equ 0x07c0 sysseg equ 0x1000 syslen equ 17 start: jmp bootseg:go go: mov ax,cs mov ds,ax mov ss,ax mov sp,0x0400 load_syetem: mov dx,0x0000 mov cx,0x0002 mov ax,sysseg mov es,ax xor bx,bx mov ax,0x200+syslen int 0x13 jnc ok_load die: jmp die ok_load: cli mov ax,sysseg mov ds,ax xor ax,ax mov es,ax mov cx,0x2000 sub si,si sub di,di rep movsb mov ax,bootseg mov ds,ax lidt [idt_48] lgdt [gdt_48] mov ax,0x0001 lmsw ax jmp 8:0 gdt: dw 0,0,0,0 dw 0x07ff dw 0x0000 dw 0x9a00 dw 0x00c0 dw 0x07ff dw 0x0000 dw 0x9200 dw 0x00c0 idt_48: dw 0,0,0 gdt_48: dw 0x7ff dw 0x7c00+gdt,0 times 510-($-$$) db 0 dw 0xaa55
LATCH equ 11930 SCRN_SEL equ 0x18 TSS0_SEL equ 0x20 LDT0_SEL equ 0x28 TSS1_SEL equ 0x30 LDT1_SEL equ 0x38 bits 32;设置处理器模式位模式为32位 startup_32: mov eax,0x10 mov ds,ax lss esp,[init_stack] call setup_idt call setup_gdt mov eax,dword 0x10 mov ds,ax mov es,ax mov fs,ax mov gs,ax lss esp,[init_stack] mov al,0x36 mov edx,0x43 out dx,al mov eax,LATCH mov edx,0x40 out dx,al mov al,ah out dx,al mov eax,0x00080000 mov ax,timer_interrupt mov dx,0x8e00 mov ecx,0x08 lea esi,[idt+ecx*8] mov [esi],eax mov [esi+4],edx mov ax,system_interrupt mov dx,0xef00 mov ecx,0x80 lea esi,[idt+ecx*8] mov [esi],eax mov [esi+4],edx pushf and dword[esp],0xffffbfff popf mov eax,TSS0_SEL ltr ax mov eax,LDT0_SEL lldt ax mov dword[current],0 sti push long 0x17 push long init_stack pushf push long 0x0f push long task0 iret setup_gdt: lgdt [lgdt_opcode] ret setup_idt: mov edx,ignore_int-$$;lea edx,[ignore_int] mov eax,0x00080000 mov ax,dx mov dx,0x8e00 mov edx,ignore_int-$$;lea edi,[idt] mov ecx,256 rp_idt: mov [edi],eax mov [edi+4],edx add edi,8 dec ecx jne rp_idt lidt [lidt_opcode] ret write_char: push gs push ebx mov ebx,SCRN_SEL mov gs,bx mov bx,[scr_loc] shl ebx,1 mov [gs:ebx],al shr ebx,1 inc ebx cmp ebx,2000 jb .l1 mov ebx,0 .l1: mov [scr_loc],ebx pop ebx pop gs ret align 4 ignore_int: push ds push eax mov eax,0x10 mov ds,ax mov eax,67 call write_char pop eax pop ds iret align 4 timer_interrupt: push ds push eax mov eax,0x10 mov ds,ax mov al,0x20 out 0x20,al mov eax,1 cmp [current],eax je .l1 mov [current],eax jmp TSS1_SEL:0 jmp .l2 .l1: mov dword[current],0 jmp TSS0_SEL:0 .l2: pop eax pop ds iret align 4 system_interrupt: push ds push edx push ecx push ebx push eax mov edx,0x10 mov ds,dx call write_char pop eax pop ebx pop ecx pop edx pop ds iret current: dd 0 scr_loc: dd 0 align 4 lidt_opcode: dw 256*8-1 dd idt lgdt_opcode: dw (end_gdt-gdt)-1 dd gdt align 8 idt: times 256*8 db 0 gdt: dq 0x0000000000000000 dq 0x00c09a00000007ff dq 0x00c09200000007ff dq 0x00c0920b80000002 dw 0x68,tss0,0xe900,0x0 dw 0x40,ldt0,0xe200,0x0 dw 0x68,tss1,0xe900,0x0 dw 0x40,ldt1,0xe200,0x0 end_gdt: times 128*4 db 0 init_stack: dd init_stack dw 0x10 align 8 ldt0: dq 0x0000000000000000 dq 0x00c0fa00000003ff dq 0x00c0f200000003ff tss0: dd 0 dd krn_stk0,0x10 dd 0,0,0,0,0 dd 0,0,0,0,0 dd 0,0,0,0,0 dd 0,0,0,0,0,0 dd LDT0_SEL,0x8000000 times 128*4 db 0 krn_stk0: align 8 ldt1: dq 0x0000000000000000 dq 0x00c0fa00000003ff dq 0x00c0f200000003ff tss1: dd 0 dd krn_stk1,0x10 dd 0,0,0,0,0 dd task1,0x200 dd 0,0,0,0 dd usr_stk1,0,0,0 dd 0x17,0x0f,0x17,0x17,0x17,0x17 dd LDT1_SEL,0x8000000 times 128*4 db 0 krn_stk1: task0: mov eax,0x17 mov ds,ax mov al,65 int 0x80 mov ecx,0xfff .l1: loop .l1 jmp task0 task1: mov al,66 int 0x80 mov ecx,0xfff .l2: loop .l2 jmp task1 times 128*4 db 0 usr_stk1:
将两个文件各自汇编为二进制文件格式,再将boot二进制代码写入映像文件的第一个扇区(前512字节),将head二进制代码紧接着boot代码写入映像文件。