From Computer History Wiki
Linux 0.00 doing what id does best
|This Version:||2.6 (2010)|
Linux 0.00 was the first version that simply went into protected mode, started two tasks, and switched between the two printing "AAAA" & "BBBB".
"it switched between two processes that printed AAAA... and BBBB... respectively by using the timer-interrupt - Gods I was proud over that" --Linus Torvalds
Getting this to run
So far the only place I've found with a binary is over at oldlinux.org. I was able to convert the boot image into something that Qemu understands and was able to run. Otherwise, it ought to run with an older version of Bochs.
You can download the floppy disk image here
Commented Source Code
Linux as this point only comprised two files. The following was taken from this forum post.
# Boot.s this code has been transferred to the memory 0 x10000, and in protected mode KRN_BASE = 0x10000 # Boot.s we have learned about the structure of the Register, which is the index table at the gdt # Gdt a table of the table of eight bytes. Each user process of the two gdt table, and ldt tss Not # 1 # The second is the code of the system # The third is the system of data # 3 is the memory of the system TSS0_SEL = 0x20 LDT0_SEL = 0x28 TSS1_SEL = 0X30 LDT1_SEL = 0x38 . Text Startup_32: # Register all of the data, all point system, gdt Table 3 Movl $ 0x10,% eax Mov% ax,% ds Mov% ax,% es Mov% ax,% fs Mov% ax,% gs # Load the stack of address Lss stack_ptr,% esp # # Linux-0.00 There are two processes, one has been Print A, B another has been Print # Switching until 8253 have interrupted the process # Operating system paging mechanism used by the former sub mechanism. In modern operating systems, # Some say cleverly around Linux in the past, some people say that is not ... # # Mechanism for the use of sub-systems for each user process the two gdt table, a paragraph is tss, another paragraph is ldt # The following two dozen lines of code set up the process of tss, and ldt These two paragraphs # absolute addresses wrote gdt table of the corresponding local Gdt Table # Please refer to the structure of the C Program # Http://blog.chinaunix.net/u/23177/showart_209429.html # Movl $ KRN_BASE,% ebx Movl $ gdt,% ecx Lea tss0,% eax Movl $ TSS0_SEL,% edi Call set_base Lea ldt0,% eax Movl $ LDT0_SEL,% edi Call set_base Lea tss1,% eax Movl $ TSS1_SEL,% edi Call set_base Lea ldt1,% eax Movl $ LDT1_SEL,% edi Call set_base # Setup_idt to 256 interrupt vector processing functions are set to ignore_int Call setup_idt # Global descriptor table and the length of the initial address printed in the Register gdtr Call setup_gdt Movl $ 0x10,% eax # reload all the segment registers Mov% ax,% ds # after changing gdt. Mov% ax,% es Mov% ax,% fs Mov% ax,% gs Lss stack_ptr,% esp # Setup up timer 8253 chip. Movb $ 0x36,% al Movl $ 0x43,% edx Outb% al,% dx Movl $ 11,930,% eax # timer frequency 100 HZ Movl $ 0x40,% edx Outb% al,% dx Movb% ah,% al Outb% al,% dx # # There are three operating systems interruption, software interruption, and processor hardware interrupt abnormal # Timer_interrupt hardware interrupt handling procedures, the film tells the system time, the switching process # System_interrupt interrupt processing software, users can use the system to process called Print the letters A or B # # Mode is the IDT (interrupt descriptor table) in the memory address 0 x0 started from the local # Protected mode register idtr have a special place at the beginning of IDT IDT # therefore need not address 0 x0 started on the place # Mode is a disruption to account for 4 bytes, 256 1 k byte A # protected mode interrupt descriptor or 8 bytes; 256 total 2k bytes # # Protected mode interrupt descriptor is interrupted doors, trap doors or doors task. Some said there is a book called Gate # Interrupted doors and trap doors only difference is not allowed to interrupt the door further interruption, that is the meaning of the Executive interrupted doors # Interrupt handling procedures at customs is interrupted. The door to the hardware interrupt handling interruption # Trap door opposite, allowing interruption processing software interruption. The code below shows this point Door # task switching process provides a hardware-level support. Now the Linux kernel and not the use of this mechanism # However linux-0.00 indeed use this hardware switching mechanism # # Interrupt handling procedures set up where the paragraph is the system code, the table is the second gdt # Interrupt handling procedures and paragraph migration in the high 16 location 0 Movl $ 0x00080000,% eax # Interrupt handling procedures set up in the migration of the low 16 Movw $ timer_interrupt,% ax # Core states interrupted doors, and the doors effective Movw $ 0x8E00,% dx # Timer_interrupt interrupt vector is 32, Movl $ 0x20,% ecx Lea idt (,% ecx, 8),% esi # Will be set up on the door interrupted the good content wrote idt corresponding table (32) Movl% eax, (% esi) Movl% edx, 4 (% esi) # Interrupt handling procedures set up in the migration of the low 16 Movw $ system_interrupt,% ax # User-trap doors, and the doors effective Movw $ 0xef00,% dx # System_interrupt interrupt vector is 128, Movl $ 0x80,% ecx Lea idt (,% ecx, 8),% esi # Trap door will be erected good idt wrote the contents of the corresponding table (128) Movl% eax, (% esi) Movl% edx, 4 (% esi) # Unmask the timer interrupt. Movl $ 0x21,% edx Inb% dx,% al Andb $ 0xfe,% al Outb% al,% dx # # The following three lines of code set up EFLAGS NT 0 # NT = 0 to the following tasks to prepare for switch # "Linux kernel completely Notes" section 102 403 lines of code as follows (kernel / sched.c): # __asm__ ( "Pushfl; andl $ 0xffffbfff, (% esp); popfl"); # The following three lines of code above is launched # # NT nested task is the acronym EFLAGS of the first 15 signs. When NT = 0:00 no task switching # Behind tss0 and tss1 structure in eflags = 0x0200, which is NT = 1, a task switching # # X86 a total of four ways switching tasks # 1. Ljmp $ task_selector, $ 0 # 2. Lcall $ task_selector, $ 0 # 3. Int 0x80 # 4. Iret # Ljmp and lcall distinction is no longer Jump ljmp not come back, but can also Jump back lcall # Int 0x80 must Jump to the mission doors # NT iret must be set to 1 # Behind the timer interrupt handling functions is used ljmp timer_interrupt # Ljmp $ TSS0_SEL, $ 0 # Ljmp $ TSS1_SEL, $ 0 # Pushfl Andl $ 0xffffbfff, (% esp) Popfl # Printed in the process 0 task Register Movl $ TSS0_SEL,% eax Ltr% ax # Printed in the process 0 local descriptor table register Movl $ LDT0_SEL,% eax Lldt% ax # Set up the current process was 0 Movl $ 0, current # Open interruption. Iret after two tasks can be run alternately Sti Pushl $ 0x17 Pushl $ stack0_ptr Pushfl Pushl $ 0x0f Pushl $ task0 # No task switching (NT = 0), only Jump to task0 punishable by implementing user - # I think that also can be understood as Jump to a special task 0 process Iret /****************************************/ Setup_gdt: Lgdt lgdt_opcode Ret Setup_idt: Lea ignore_int,% edx Movl $ 0x00080000,% eax Movw% dx,% ax / * selector = 0x0008 = cs * / Movw $ 0x8E00,% dx / * interrupt gate - dpl = 0, present * / 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 # In:% eax - logic addr;% ebx = base addr; #% Ecx - table addr;% edi - descriptors offset. Set_base: Addl% ebx,% eax Addl% ecx,% edi Movw% ax, 2 (% edi) Rorl $ 16,% eax Movb% al, 4 (% edi) Movb% ah, 7 (% edi) Rorl $ 16,% eax Ret Write_char: Push% gs Pushl% ebx Pushl% eax # Printed in the memory of Mov $ 0x18,% ebx Mov% bx,% gs # Shown by the last character position Movl scr_loc,% bx # Each of the two-byte characters, the first byte is what we have to show that the byte Shl $ 1,% ebx # Characters' A 'or' B 'direct wrote in memory Movb% al,% gs: (% ebx) # Of a two-byte characters, the second byte is the attribute byte # For example 0 x07 is normal, black white; 0 x70 is reversed - phase, black white # When the procedures set up a property, it would maintain the same attribute, after all the characters have the same attributes # Until another operation changed the attributes # If add the following three lines here, it will be the effect of white black # Inc% ebx # Movb $ 0x70,% gs: (% ebx) # Dec% ebx Shr $ 1,% ebx Incl% ebx # CGA provides both texts model 40 x25 and 80 x25, if it is 80 x25 that is a screen can have 2,000 characters # Characters each pixel of 8x8 months, the CGA has two resolution 320 x 200 and 640 x 200 # If the following 2000 to 1000, we will find that only a former semi-screen output Cmpl $ 2000,% ebx # If visitors fill a screen, then start again Jb 1f # Counter Fu 0 Movl $ 0,% ebx # Preserve the current cursor position 1: movl% ebx, scr_loc Popl% eax Popl% ebx Pop% gs Ret /***********************************************/ / * This is the default interrupt "handler" :-) * / . Align 2 Ignore_int: Push% ds Pushl% eax Movl $ 0x10,% eax Mov% ax,% ds Movl $ 67,% eax / * print 'C' * / Call write_char Popl% eax Pop% ds Iret / * Timer interrupt handler * / . Align 2 Timer_interrupt: Push% ds Pushl% edx Pushl% ecx Pushl% ebx Pushl% eax Movl $ 0x10,% eax Mov% 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 Popl% ebx Popl% ecx Popl% edx Pop% ds Iret / * System call handler * / . Align 2 System_interrupt: Push% ds Pushl% edx Pushl% ecx Pushl% ebx Pushl% eax Movl $ 0x10,% edx Mov% 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 . Word 0 Lidt_opcode: . Word 256 * 8-1 # idt contains 256 entries . Long idt + KRN_BASE # This will be rewrite by code. . Align 2 . Word 0 Lgdt_opcode: . Word (end_gdt - gdt) -1 # so does gdt . Long gdt + KRN_BASE # This will be rewrite by code. . Align 3 Idt:. Fill 256,8,0 # idt is uninitialized Gdt:. Quad 0x0000000000000000 / * NULL descriptor * / . Quad 0x00c09a01000007ff / * 8Mb 0x08, base = 0x10000 * / . Quad 0x00c09201000007ff / * 8Mb 0x10 * / # Control段描述符table can know the definition of the base site is 0 xb8000 (736K) # "Linux kernel completely Notes," a book 206 649 lines of code as follows # Vidio_mem_start = 0xb8000 # Note the color mode shows the initial memory address is 0 xb8000 . Quad 0x00c0920b80000002 / * screen 0x18 - for display * / . Quad 0x0000e90100000068 # TSS0 descr 0x20 . Quad 0x0000e20100000040 # LDT0 descr 0x28 . Quad 0x0000e90100000068 # TSS1 descr 0x30 . Quad 0x0000e20100000040 # LDT1 descr 0x38 End_gdt: . Fill 128,4,0 Stack_ptr: . Long stack_ptr . Word 0x10 /*************************************/ . Align 3 Ldt0:. Quad 0x0000000000000000 . Quad 0x00c0fa01000003ff # 0x0f, base = 0x10000 . Quad 0x00c0f201000003ff # 0x17 Tss0: . Long 0 / * back link * / . Long stack0_krn_ptr, 0x10 / * esp0, ss0 * / . Long 0, 0 / * esp1, ss1 * / . Long 0, 0 / * esp2, ss2 * / . Long 0 / * cr3 * / . Long task0 / * eip * / . Long 0x200 / * eflags * / . Long 0, 0, 0, 0 / * eax, ecx, edx, ebx * / . Long stack0_ptr, 0, 0, 0 / * esp, ebp, esi, edi * / . Long 0x17, 0x0f, 0x17, 0x17, 0x17, 0x17 / * es, cs, ss and ds, fs, gs * / . Long LDT0_SEL / * ldt * / . Long 0x8000000 / * trace bitmap * / . Fill 128,4,0 Stack0_krn_ptr: . Long 0 /************************************/ . Align 3 Ldt1:. Quad 0x0000000000000000 . Quad 0x00c0fa01000003ff # 0x0f, base = 0x10000 . Quad 0x00c0f201000003ff # 0x17 Tss1: . Long 0 / * back link * / . Long stack1_krn_ptr, 0x10 / * esp0, ss0 * / . Long 0, 0 / * esp1, ss1 * / . Long 0, 0 / * esp2, ss2 * / . Long 0 / * cr3 * / . Long task1 / * eip * / . Long 0x200 / * eflags * / . Long 0, 0, 0, 0 / * eax, ecx, edx, ebx * / . Long stack1_ptr, 0, 0, 0 / * esp, ebp, esi, edi * / . Long 0x17, 0x0f, 0x17, 0x17, 0x17, 0x17 / * es, cs, ss and ds, fs, gs * / . Long LDT1_SEL / * ldt * / . Long 0x8000000 / * trace bitmap * / . Fill 128,4,0 Stack1_krn_ptr: . Long 0 /************************************/ Task0: Movl $ 0x17,% eax Movw% ax,% ds Movl $ 65,% al / * print 'A' * / Int $ 0x80 Movl $ 0xfff,% ecx 1: loop 1b Jmp task0 . Fill 128,4,0 Stack0_ptr: . Long 0 Task1: Movl $ 0x17,% eax Movw% ax,% ds Movl $ 66,% al / * print 'B' * / Int $ 0x80 Movl $ 0xfff,% ecx 1: loop 1b Jmp task1 . Fill 128,4,0 Stack1_ptr: . Long 0 / *** *** End /