Difference between revisions of "Linux 0.00"
From Computer History Wiki
m (Some Mediawiki tweaks to avoid pre-formatted text overflowing the infobox with some browser/width/font size combos) |
m (Proper cat) |
||
| Line 19: | Line 19: | ||
"it switched between two processes that printed AAAA... and BBBB... | "it switched between two processes that printed AAAA... and BBBB... | ||
respectively by using the timer-interrupt - Gods I was proud over that" | respectively by using the timer-interrupt - Gods I was proud over that" | ||
| − | |||
--Linus Torvalds | --Linus Torvalds | ||
| Line 31: | Line 30: | ||
== Commented Source Code == | == Commented Source Code == | ||
| + | |||
Linux as this point only comprised two files. The following was taken from [http://hi.baidu.com/songfengen/blog/item/724baea8795635b2cb130cdc.html this] forum post. | Linux as this point only comprised two files. The following was taken from [http://hi.baidu.com/songfengen/blog/item/724baea8795635b2cb130cdc.html this] forum post. | ||
| Line 447: | Line 447: | ||
/ *** *** End / | / *** *** End / | ||
</pre> | </pre> | ||
| − | |||
Revision as of 23:06, 19 October 2018
| Linux 0.00 | |
| Linux 0.00 doing what id does best | |
| Type: | Multitasking |
|---|---|
| Creator: | Linus Torvalds |
| Architecture: | IBM 386 |
| This Version: | 2.6 (2010) |
| Date Released: | 1991 |
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 /