A primeira versão do UNIX

- por Sergio Prado

Categorias: Unix Tags: , ,

O UNIX é um dos sistemas operacionais mais influentes na história da computação. Criado por pesquisadores da AT&T entre o final da década de 60 e o início dos anos 70, foi implementado por diversas empresas e instituições de ensino ao redor do mundo (Solaris, AIX, HP-UX, OS-X, BSD, Minix, etc), servindo de motivação para a criação do que é hoje o sistema operacional de código aberto mais usado no mundo, o Linux!

unix

Durante um tempo, acreditou-se que o código-fonte original da primeira versão do UNIX estivesse perdida para sempre. Mas em 2006, foi encontrado um documento escrito por T.R. Bashkow e entitulado “Study of Unix“, que descrevia a estrutura e os componentes internos do UNIX, incluindo uma listagem do código-fonte original em assembly!

Foi a deixa para ressussitar um dos softwares mais influentes de todos os tempos. Em 2008, uma equipe da The Unix Heritage Society (TUHS) conseguiu completar este trabalho. Foi necessário escanear o documento e passar por uma ferramenta de OCR para converter para o código-fonte original, incluindo aí o trabalho manual de revisar linha a linha do código-fonte escaneado! Durante o processo de recuperação, alguns bugs foram encontrados e corrigidos. No final, usando uma ferramenta de emulação com suporte ao PDP11, conseguiram rodar a primeira versão do UNIX, cujo código-fonte está disponível para todos os interessados e amantes da computação no Github.

Que tal então um pouco de diversão?

COMPILANDO O UNIX v1.0

O primeiro passo é baixar o código-fonte do UNIX:

$ cd ~/
$ git clone https://github.com/c3x04/Unix-1st-Edition-jun72 unix
$ cd unix

Verifique se o código-fonte foi baixado com sucesso:

$ ls
boot   Credits  Dockerfile  Makefile  notes  patches  simh.cfg  tools
build  diffs    fs          misc      pages  Readme   src

Para os mais curiosos, o diretório pages contém as páginas escaneadas do código-fonte original do UNIX:

$ ls pages/
e00-01  e00-08  e01-05  e02-02  e02-09  e04-02  e05-02  e06-03  e07-04  e08-03  e09-01  e09-08  e11-05
e00-02  e00-09  e01-06  e02-03  e02-10  e04-03  e05-03  e06-04  e07-05  e08-04  e09-02  e10-01  e11-06
e00-03  e00-10  e01-07  e02-04  e03-01  e04-04  e05-04  e06-05  e07-06  e08-05  e09-03  e10-02  e11-07
e00-04  e01-01  e01-08  e02-05  e03-02  e04-05  e05-05  e06-06  e07-07  e08-06  e09-04  e11-01  e12-01
e00-05  e01-02  e01-09  e02-06  e03-03  e04-06  e05-06  e07-01  e07-08  e08-07  e09-05  e11-02  e12-02
e00-06  e01-03  e01-10  e02-07  e03-04  e04-07  e06-01  e07-02  e08-01  e08-08  e09-06  e11-03  e12-03
e00-07  e01-04  e02-01  e02-08  e04-01  e05-01  e06-02  e07-03  e08-02  e08-09  e09-07  e11-04  e12-04

Com a ajuda de uma ferramenta de OCR, o conteúdo destas páginas foi convertido em arquivos assembly no diretório build do projeto:

$ ls build/
cleansrc    Makefile  root       u0.clean   u2.clean  u4.s       u6.s      u9.clean  ux.clean
images      patched   sh.0405    u0.s       u2.s      u4.s.orig  u7.clean  u9.s      ux.s
init.0405   protofs   sh.clean   u0.s.orig  u3.clean  u5.clean   u7.s      unix
init.clean  rf0.dsk   sh.s       u1.clean   u3.s      u5.s       u8.clean  usr
init.s      rk0.dsk   sh.s.orig  u1.s       u4.clean  u6.clean   u8.s      usyms

Para os apreciadores da arte, segue um pedacinho de assembly do UNIX, responsável pelo tratamento das chamadas de sistema (arquivo u1.s):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/ u1 -- unix
 
unkni: / used for all system calls
sysent:
	incb	sysflg / indicate a system routine is
	beq	1f / in progress
	jmp	panic / called if trap inside system
1:
	mov	$s.syst+2,clockp
	mov	r0,-(sp) / save user registers
	mov	sp,u.r0 / pointer to bottom of users stack in u.r0
	mov	r1,-(sp)
	mov	r2,-(sp)
	mov	r3,-(sp)
	mov	r4,-(sp)
	mov	r5,-(sp)
	mov	ac,-(sp) / "accumulator" register for extended
		         / arithmetic unit
	mov	mq,-(sp) / "multiplier quotient" register for the
		         / extended arithmetic unit
	mov	sc,-(sp) / "step count" register for the extended
		         / arithmetic unit
	mov	sp,u.sp / u.sp points to top of users stack
	mov	18.(sp),r0 / store pc in r0
	mov	-(r0),r0 / sys inst in r0      10400xxx
	sub	$sys,r0 / get xxx code
	asl	r0 / multiply by 2 to jump indirect in bytes
	cmp	r0,$2f-1f / limit of table (35) exceeded
	bhis	badsys / yes, bad system call
	bic	$341,20.(sp) / set users processor priority to 0 and clear
		             / carry bit
	jmp	*1f(r0) / jump indirect thru table of addresses
		        / to proper system routine.
1:
	sysrele / 0
	sysexit / 1
	sysfork / 2
	sysread / 3
	syswrite / 4
	sysopen / 5
	sysclose / 6
	syswait / 7
	syscreat / 8
	syslink / 9
	sysunlink / 10
	sysexec / 11
	syschdir / 12
	systime / 13
	sysmkdir / 14
	syschmod / 15
	syschown / 16
	sysbreak / 17
	sysstat / 18
	sysseek / 19
	systell / 20
	sysmount / 21
	sysumount / 22
	syssetuid / 23
	sysgetuid / 24
	sysstime / 25
	sysquit / 26
	sysintr / 27
	sysfstat / 28
	sysemt / 29
	sysmdate / 30
	sysstty / 31
	sysgtty / 32
	sysilgins / 33

Para compilar o UNIX, basta executar o make:

$ make

Depois de alguns segundos, as imagens estarão disponíveis no diretório images:

$ ls images/
m792low.load rf0.dsk rk0.dsk

EMULANDO O UNIX

O UNIX original foi escrito em um PDP-7, e depois portado para o PDP-11. Os PDPs eram minicomputadores fabricados nas décadas de 70 e 80 pela antiga DEC (Digital Equipment Corp), comprada pela Compaq e hoje parte da HP. É considerado por muitos especialistas como o minicomputador mais popular da história da computação, influenciando a arquitetura de plataformas famosas como o x86 da Intel e o 68000 da Motorola.

O PDP-11/20, uma das versões deste minicomputador, era uma máquina de 16 bits com 56K de RAM, custando uma bagatela de $20.000! Olha a pose da criança na imagem abaixo:

pdp1120

E para testar a imagem do Unix, precisamos de um simulador do PDP-11. Para isso, podemos usar o SIMH.

$ mkdir -p ~/unix/simh && cd ~/unix/simh
$ wget http://simh.trailing-edge.com/sources/simhv39-0.zip
$ unzip simhv39-0.zip

O simulador pode ser compilado com o comando abaixo:

$ make pdp11

No final da compilação, copie o binário do emulador para o diretório tools do código-fonte do UNIX:

$ cp -av BIN/pdp11 ~/unix/tools/

Agora é só retornar ao diretório do código-fonte do UNIX e iniciar a emulação da imagem gerada:

$ cd ~/unix/
$ ./simh.cfg
 
PDP-11 simulator V3.9-0
./simh.cfg> #!tools/pdp11
Unknown command
Disabling CR
Disabling XQ
RF: buffering file in memory
TC: creating new file
TC0: 16b format, buffering file in memory
Listening on port 5555 (socket 7)
 
:login:

Faça o login com o usuário root (sem senha).

Achievement unlocked: login on the first UNIX version! :)

Claro que é um sistema bem limitado, mas qualquer semelhança com o sistema operacional do pinguim não é mera coincidência! :)

# ls -l /
total    5
 57 sdrwr-  2 root    620 Jan  1 00:00:00 bin
 42 sdrwr-  2 root    250 Jan  1 00:00:00 dev
 43 sdrwr-  2 root    110 Jan  1 00:00:00 etc
 53 sdrwr-  2 root     50 Jan  1 00:00:00 tmp

Algumas curiosidades sobre a primeira versão do UNIX:

  • São aproximadamente 4.200 linhas de código-fonte em assembly, que ocupam 16K de RAM.
  • Muitas das características do UNIX, como um terminal para executar comandos (shell) e redirecionamento de I/O foram herdadas do Multics.
  • Suporta no máximo 16 processos, onde apenas um pode estar em memória em um determinado momento (todos os outros processos são movidos para uma região de SWAP).
  • Estão disponíveis 34 chamadas de sistema, e destas, 24 existem até hoje no código-fonte do kernel Linux, inclusive com o mesmo número identificador de chamada de sistema!
  • O único editor de textos disponível é o ed, que até hoje é o editor de textos cuja presença é garantida em todo sistema UNIX.

Para os mais aventureiros, o manual da primeira edição do UNIX está disponível na Internet.

Have fun!

Sergio Prado

Faça um Comentário

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.