2025年4月26日 星期六 乙巳(蛇)年 正月廿七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 系统应用 > Linux

Linux之父27年前写的一段代码

时间:03-05来源:作者:点击数:86

有程序员网友曝出了莱纳斯•托瓦尔兹(Linus Torvalds) 1991 年公开的 Linux 源代码,这引起了 W3Cschool 的注意,可以研究一下这位大神的代码: 

源码:

  • /
  • system_call.s contains the system-call low-level handling routines.
  • This also contains the timer-interrupt handler, as some of the code is
  • the same. The hd-interrupt is also here.
  • NOTE: This code handles signal-recognition, which happens every time
  • after a timer-interrupt and after each system call. Ordinary interrupts
  • don't handle signal-recognition, as that would clutter them up totally
  • unnecessarily.
  • Stack layout in 'ret_from_system_call':
  • 0(%esp) - %eax
  • 4(%esp) - %ebx
  • 8(%esp) - %ecx
  • C(%esp) - %edx
  • 10(%esp) - %fs
  • 14(%esp) - %es
  • 18(%esp) - %ds
  • 1C(%esp) - %eip
  • 20(%esp) - %cs
  • 24(%esp) - %eflags
  • 28(%esp) - %oldesp
  • 2C(%esp) - %oldss
  • /
  • SIG_CHLD = 17
  • EAX = 0x00
  • EBX = 0x04
  • ECX = 0x08
  • EDX = 0x0C
  • FS = 0x10
  • ES = 0x14
  • DS = 0x18
  • EIP = 0x1C
  • CS = 0x20
  • EFLAGS = 0x24
  • OLDESP = 0x28
  • OLDSS = 0x2C
  • state = 0 # these are offsets into the task-struct.
  • counter = 4
  • priority = 8
  • signal = 12
  • restorer = 16 # address of info-restorer
  • sig_fn = 20 # table of 32 signal addresses
  • nr_system_calls = 67
  • .globl _system_call,_sys_fork,_timer_interrupt,_hd_interrupt,_sys_execve
  • .align 2
  • bad_sys_call:
  • movl $-1,%eax
  • iret
  • .align 2
  • reschedule:
  • pushl $ret_from_sys_call
  • jmp _schedule
  • .align 2
  • _system_call:
  • cmpl $nr_system_calls-1,%eax
  • ja bad_sys_call
  • push %ds
  • push %es
  • push %fs
  • pushl %edx
  • pushl %ecx # push %ebx,%ecx,%edx as parameters
  • pushl %ebx # to the system call
  • movl $0x10,%edx # set up ds,es to kernel space
  • mov %dx,%ds
  • mov %dx,%es
  • movl $0x17,%edx # fs points to local data space
  • mov %dx,%fs
  • call _sys_call_table(,%eax,4)
  • pushl %eax
  • movl _current,%eax
  • cmpl $0,state(%eax) # state
  • jne reschedule
  • cmpl $0,counter(%eax) # counter
  • je reschedule
  • ret_from_sys_call:
  • movl _current,%eax # task[0] cannot have signals
  • cmpl _task,%eax
  • je 3f
  • movl CS(%esp),%ebx # was old code segment supervisor
  • testl $3,%ebx # mode? If so - don't check signals
  • je 3f
  • cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
  • jne 3f
  • 2: movl signal(%eax),%ebx # signals (bitmap, 32 signals)
  • bsfl %ebx,%ecx # %ecx is signal nr, return if none
  • je 3f
  • btrl %ecx,%ebx # clear it
  • movl %ebx,signal(%eax)
  • movl sig_fn(%eax,%ecx,4),%ebx # %ebx is signal handler address
  • cmpl $1,%ebx
  • jb default_signal # 0 is default signal handler - exit
  • je 2b # 1 is ignore - find next signal
  • movl $0,sig_fn(%eax,%ecx,4) # reset signal handler address
  • incl %ecx
  • xchgl %ebx,EIP(%esp) # put new return address on stack
  • subl $28,OLDESP(%esp)
  • movl OLDESP(%esp),%edx # push old return address on stack
  • pushl %eax # but first check that it's ok.
  • pushl %ecx
  • pushl $28
  • pushl %edx
  • call _verify_area
  • popl %edx
  • addl $4,%esp
  • popl %ecx
  • popl %eax
  • movl restorer(%eax),%eax
  • movl %eax,%fs:(%edx) # flag/reg restorer
  • movl %ecx,%fs:4(%edx) # signal nr
  • movl EAX(%esp),%eax
  • movl %eax,%fs:8(%edx) # old eax
  • movl ECX(%esp),%eax
  • movl %eax,%fs:12(%edx) # old ecx
  • movl EDX(%esp),%eax
  • movl %eax,%fs:16(%edx) # old edx
  • movl EFLAGS(%esp),%eax
  • movl %eax,%fs:20(%edx) # old eflags
  • movl %ebx,%fs:24(%edx) # old return addr
  • 3: popl %eax
  • popl %ebx
  • popl %ecx
  • popl %edx
  • pop %fs
  • pop %es
  • pop %ds
  • iret
  • default_signal:
  • incl %ecx
  • cmpl $SIG_CHLD,%ecx
  • je 2b
  • pushl %ecx
  • call _do_exit # remember to set bit 7 when dumping core
  • addl $4,%esp
  • jmp 3b
  • .align 2
  • _timer_interrupt:
  • push %ds # save ds,es and put kernel data space
  • push %es # into them. %fs is used by _system_call
  • push %fs
  • pushl %edx # we save %eax,%ecx,%edx as gcc doesn't
  • pushl %ecx # save those across function calls. %ebx
  • pushl %ebx # is saved as we use that in ret_sys_call
  • pushl %eax
  • movl $0x10,%eax
  • mov %ax,%ds
  • mov %ax,%es
  • movl $0x17,%eax
  • mov %ax,%fs
  • incl _jiffies
  • movb $0x20,%al # EOI to interrupt controller #1
  • outb %al,$0x20
  • movl CS(%esp),%eax
  • andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
  • pushl %eax
  • call _do_timer # 'do_timer(long CPL)' does everything from
  • addl $4,%esp # task switching to accounting ...
  • jmp ret_from_sys_call
  • .align 2
  • _sys_execve:
  • lea EIP(%esp),%eax
  • pushl %eax
  • call _do_execve
  • addl $4,%esp
  • ret
  • .align 2
  • _sys_fork:
  • call _find_empty_process
  • testl %eax,%eax
  • js 1f
  • push %gs
  • pushl %esi
  • pushl %edi
  • pushl %ebp
  • pushl %eax
  • call _copy_process
  • addl $20,%esp
  • 1: ret
  • _hd_interrupt:
  • pushl %eax
  • pushl %ecx
  • pushl %edx
  • push %ds
  • push %es
  • push %fs
  • movl $0x10,%eax
  • mov %ax,%ds
  • mov %ax,%es
  • movl $0x17,%eax
  • mov %ax,%fs
  • movb $0x20,%al
  • outb %al,$0x20 # EOI to interrupt controller #1
  • jmp 1f # give port chance to breathe
  • 1: jmp 1f
  • 1: outb %al,$0xA0 # same to controller #2
  • movl _do_hd,%eax
  • testl %eax,%eax
  • jne 1f
  • movl $_unexpected_hd_interrupt,%eax
  • 1: call %eax # "interesting" way of handling intr.
  • pop %fs
  • pop %es
  • pop %ds
  • popl %edx
  • popl %ecx
  • popl %eax
  • iret

Linux之父

托瓦尔兹 1969 年 12 月 28 日出生于芬兰赫尔辛基市,父母都是记者。他从小就对计算机感兴趣。1988 年他进入赫尔辛基大学学习,专业为计算机科学。1991 年,他购买了一台属于自己的 PC 机。赫尔辛基大学当时采用Unix操作系统,托瓦尔兹觉得该产品性能不尽如人意,于是就尝试着自己编写一款操作系统内核,这就是 Linux 操作系统来源。

 

1997 年至 2003 年,托瓦尔兹在美国加州全美达(Transmeta)公司工作。2003 年 7 月,他加盟“开放源代码开发实验室”(OSDL),以全力开发 Linux 内核。后来 OSDL 与“免费标准集团”(FSG)合并成立了 Linux 基金会。托瓦尔兹如今仍在 Linux 基金会工作。与其他 IT 明星人物所不同的是,托瓦兹平常行事较为低调,一般很少在公开场合评论商业竞争对手产品的好坏。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门