add lab4 spoc exercises
This commit is contained in:
		
							parent
							
								
									91d8793b24
								
							
						
					
					
						commit
						28605e36e7
					
				
							
								
								
									
										3
									
								
								related_info/lab4/some-exercises/build-2.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								related_info/lab4/some-exercises/build-2.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					as  -gstabs --32 -o callee.o callee.s
 | 
				
			||||||
 | 
					gcc -m32 -g -c -fno-stack-protector caller.c
 | 
				
			||||||
 | 
					gcc -m32 -g -o caller caller.o callee.o
 | 
				
			||||||
							
								
								
									
										2
									
								
								related_info/lab4/some-exercises/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								related_info/lab4/some-exercises/build.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					as -arch i386 -o prog.o prog.s
 | 
				
			||||||
 | 
					ld  -arch i386 -o prog prog.o
 | 
				
			||||||
							
								
								
									
										5
									
								
								related_info/lab4/some-exercises/call.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								related_info/lab4/some-exercises/call.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					int addtwo(int a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int x = 2;
 | 
				
			||||||
 | 
					    return a + x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								related_info/lab4/some-exercises/call2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								related_info/lab4/some-exercises/call2.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					void func2(int a, int b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  a++;
 | 
				
			||||||
 | 
					  b+=2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  func2( 1111, 2222);
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										218
									
								
								related_info/lab4/some-exercises/call2.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								related_info/lab4/some-exercises/call2.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,218 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					call2:     file format elf32-i386
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disassembly of section .init:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048294 <_init>:
 | 
				
			||||||
 | 
					 8048294:	53                   	push   %ebx
 | 
				
			||||||
 | 
					 8048295:	83 ec 08             	sub    $0x8,%esp
 | 
				
			||||||
 | 
					 8048298:	e8 83 00 00 00       	call   8048320 <__x86.get_pc_thunk.bx>
 | 
				
			||||||
 | 
					 804829d:	81 c3 63 1d 00 00    	add    $0x1d63,%ebx
 | 
				
			||||||
 | 
					 80482a3:	8b 83 fc ff ff ff    	mov    -0x4(%ebx),%eax
 | 
				
			||||||
 | 
					 80482a9:	85 c0                	test   %eax,%eax
 | 
				
			||||||
 | 
					 80482ab:	74 05                	je     80482b2 <_init+0x1e>
 | 
				
			||||||
 | 
					 80482ad:	e8 1e 00 00 00       	call   80482d0 <__gmon_start__@plt>
 | 
				
			||||||
 | 
					 80482b2:	83 c4 08             	add    $0x8,%esp
 | 
				
			||||||
 | 
					 80482b5:	5b                   	pop    %ebx
 | 
				
			||||||
 | 
					 80482b6:	c3                   	ret    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disassembly of section .plt:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080482c0 <__gmon_start__@plt-0x10>:
 | 
				
			||||||
 | 
					 80482c0:	ff 35 04 a0 04 08    	pushl  0x804a004
 | 
				
			||||||
 | 
					 80482c6:	ff 25 08 a0 04 08    	jmp    *0x804a008
 | 
				
			||||||
 | 
					 80482cc:	00 00                	add    %al,(%eax)
 | 
				
			||||||
 | 
						...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080482d0 <__gmon_start__@plt>:
 | 
				
			||||||
 | 
					 80482d0:	ff 25 0c a0 04 08    	jmp    *0x804a00c
 | 
				
			||||||
 | 
					 80482d6:	68 00 00 00 00       	push   $0x0
 | 
				
			||||||
 | 
					 80482db:	e9 e0 ff ff ff       	jmp    80482c0 <_init+0x2c>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080482e0 <__libc_start_main@plt>:
 | 
				
			||||||
 | 
					 80482e0:	ff 25 10 a0 04 08    	jmp    *0x804a010
 | 
				
			||||||
 | 
					 80482e6:	68 08 00 00 00       	push   $0x8
 | 
				
			||||||
 | 
					 80482eb:	e9 d0 ff ff ff       	jmp    80482c0 <_init+0x2c>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disassembly of section .text:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080482f0 <main>:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  func2( 1111, 2222);
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 80482f0:	31 c0                	xor    %eax,%eax
 | 
				
			||||||
 | 
					 80482f2:	c3                   	ret    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080482f3 <_start>:
 | 
				
			||||||
 | 
					 80482f3:	31 ed                	xor    %ebp,%ebp
 | 
				
			||||||
 | 
					 80482f5:	5e                   	pop    %esi
 | 
				
			||||||
 | 
					 80482f6:	89 e1                	mov    %esp,%ecx
 | 
				
			||||||
 | 
					 80482f8:	83 e4 f0             	and    $0xfffffff0,%esp
 | 
				
			||||||
 | 
					 80482fb:	50                   	push   %eax
 | 
				
			||||||
 | 
					 80482fc:	54                   	push   %esp
 | 
				
			||||||
 | 
					 80482fd:	52                   	push   %edx
 | 
				
			||||||
 | 
					 80482fe:	68 60 84 04 08       	push   $0x8048460
 | 
				
			||||||
 | 
					 8048303:	68 00 84 04 08       	push   $0x8048400
 | 
				
			||||||
 | 
					 8048308:	51                   	push   %ecx
 | 
				
			||||||
 | 
					 8048309:	56                   	push   %esi
 | 
				
			||||||
 | 
					 804830a:	68 f0 82 04 08       	push   $0x80482f0
 | 
				
			||||||
 | 
					 804830f:	e8 cc ff ff ff       	call   80482e0 <__libc_start_main@plt>
 | 
				
			||||||
 | 
					 8048314:	f4                   	hlt    
 | 
				
			||||||
 | 
					 8048315:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 8048317:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 8048319:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 804831b:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 804831d:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 804831f:	90                   	nop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048320 <__x86.get_pc_thunk.bx>:
 | 
				
			||||||
 | 
					 8048320:	8b 1c 24             	mov    (%esp),%ebx
 | 
				
			||||||
 | 
					 8048323:	c3                   	ret    
 | 
				
			||||||
 | 
					 8048324:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 8048326:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 8048328:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 804832a:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 804832c:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 804832e:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048330 <deregister_tm_clones>:
 | 
				
			||||||
 | 
					 8048330:	b8 1f a0 04 08       	mov    $0x804a01f,%eax
 | 
				
			||||||
 | 
					 8048335:	2d 1c a0 04 08       	sub    $0x804a01c,%eax
 | 
				
			||||||
 | 
					 804833a:	83 f8 06             	cmp    $0x6,%eax
 | 
				
			||||||
 | 
					 804833d:	76 1a                	jbe    8048359 <deregister_tm_clones+0x29>
 | 
				
			||||||
 | 
					 804833f:	b8 00 00 00 00       	mov    $0x0,%eax
 | 
				
			||||||
 | 
					 8048344:	85 c0                	test   %eax,%eax
 | 
				
			||||||
 | 
					 8048346:	74 11                	je     8048359 <deregister_tm_clones+0x29>
 | 
				
			||||||
 | 
					 8048348:	55                   	push   %ebp
 | 
				
			||||||
 | 
					 8048349:	89 e5                	mov    %esp,%ebp
 | 
				
			||||||
 | 
					 804834b:	83 ec 14             	sub    $0x14,%esp
 | 
				
			||||||
 | 
					 804834e:	68 1c a0 04 08       	push   $0x804a01c
 | 
				
			||||||
 | 
					 8048353:	ff d0                	call   *%eax
 | 
				
			||||||
 | 
					 8048355:	83 c4 10             	add    $0x10,%esp
 | 
				
			||||||
 | 
					 8048358:	c9                   	leave  
 | 
				
			||||||
 | 
					 8048359:	f3 c3                	repz ret 
 | 
				
			||||||
 | 
					 804835b:	90                   	nop
 | 
				
			||||||
 | 
					 804835c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048360 <register_tm_clones>:
 | 
				
			||||||
 | 
					 8048360:	b8 1c a0 04 08       	mov    $0x804a01c,%eax
 | 
				
			||||||
 | 
					 8048365:	2d 1c a0 04 08       	sub    $0x804a01c,%eax
 | 
				
			||||||
 | 
					 804836a:	c1 f8 02             	sar    $0x2,%eax
 | 
				
			||||||
 | 
					 804836d:	89 c2                	mov    %eax,%edx
 | 
				
			||||||
 | 
					 804836f:	c1 ea 1f             	shr    $0x1f,%edx
 | 
				
			||||||
 | 
					 8048372:	01 d0                	add    %edx,%eax
 | 
				
			||||||
 | 
					 8048374:	d1 f8                	sar    %eax
 | 
				
			||||||
 | 
					 8048376:	74 1b                	je     8048393 <register_tm_clones+0x33>
 | 
				
			||||||
 | 
					 8048378:	ba 00 00 00 00       	mov    $0x0,%edx
 | 
				
			||||||
 | 
					 804837d:	85 d2                	test   %edx,%edx
 | 
				
			||||||
 | 
					 804837f:	74 12                	je     8048393 <register_tm_clones+0x33>
 | 
				
			||||||
 | 
					 8048381:	55                   	push   %ebp
 | 
				
			||||||
 | 
					 8048382:	89 e5                	mov    %esp,%ebp
 | 
				
			||||||
 | 
					 8048384:	83 ec 10             	sub    $0x10,%esp
 | 
				
			||||||
 | 
					 8048387:	50                   	push   %eax
 | 
				
			||||||
 | 
					 8048388:	68 1c a0 04 08       	push   $0x804a01c
 | 
				
			||||||
 | 
					 804838d:	ff d2                	call   *%edx
 | 
				
			||||||
 | 
					 804838f:	83 c4 10             	add    $0x10,%esp
 | 
				
			||||||
 | 
					 8048392:	c9                   	leave  
 | 
				
			||||||
 | 
					 8048393:	f3 c3                	repz ret 
 | 
				
			||||||
 | 
					 8048395:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 | 
				
			||||||
 | 
					 8048399:	8d bc 27 00 00 00 00 	lea    0x0(%edi,%eiz,1),%edi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080483a0 <__do_global_dtors_aux>:
 | 
				
			||||||
 | 
					 80483a0:	80 3d 1c a0 04 08 00 	cmpb   $0x0,0x804a01c
 | 
				
			||||||
 | 
					 80483a7:	75 13                	jne    80483bc <__do_global_dtors_aux+0x1c>
 | 
				
			||||||
 | 
					 80483a9:	55                   	push   %ebp
 | 
				
			||||||
 | 
					 80483aa:	89 e5                	mov    %esp,%ebp
 | 
				
			||||||
 | 
					 80483ac:	83 ec 08             	sub    $0x8,%esp
 | 
				
			||||||
 | 
					 80483af:	e8 7c ff ff ff       	call   8048330 <deregister_tm_clones>
 | 
				
			||||||
 | 
					 80483b4:	c6 05 1c a0 04 08 01 	movb   $0x1,0x804a01c
 | 
				
			||||||
 | 
					 80483bb:	c9                   	leave  
 | 
				
			||||||
 | 
					 80483bc:	f3 c3                	repz ret 
 | 
				
			||||||
 | 
					 80483be:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080483c0 <frame_dummy>:
 | 
				
			||||||
 | 
					 80483c0:	b8 10 9f 04 08       	mov    $0x8049f10,%eax
 | 
				
			||||||
 | 
					 80483c5:	8b 10                	mov    (%eax),%edx
 | 
				
			||||||
 | 
					 80483c7:	85 d2                	test   %edx,%edx
 | 
				
			||||||
 | 
					 80483c9:	75 05                	jne    80483d0 <frame_dummy+0x10>
 | 
				
			||||||
 | 
					 80483cb:	eb 93                	jmp    8048360 <register_tm_clones>
 | 
				
			||||||
 | 
					 80483cd:	8d 76 00             	lea    0x0(%esi),%esi
 | 
				
			||||||
 | 
					 80483d0:	ba 00 00 00 00       	mov    $0x0,%edx
 | 
				
			||||||
 | 
					 80483d5:	85 d2                	test   %edx,%edx
 | 
				
			||||||
 | 
					 80483d7:	74 f2                	je     80483cb <frame_dummy+0xb>
 | 
				
			||||||
 | 
					 80483d9:	55                   	push   %ebp
 | 
				
			||||||
 | 
					 80483da:	89 e5                	mov    %esp,%ebp
 | 
				
			||||||
 | 
					 80483dc:	83 ec 14             	sub    $0x14,%esp
 | 
				
			||||||
 | 
					 80483df:	50                   	push   %eax
 | 
				
			||||||
 | 
					 80483e0:	ff d2                	call   *%edx
 | 
				
			||||||
 | 
					 80483e2:	83 c4 10             	add    $0x10,%esp
 | 
				
			||||||
 | 
					 80483e5:	c9                   	leave  
 | 
				
			||||||
 | 
					 80483e6:	e9 75 ff ff ff       	jmp    8048360 <register_tm_clones>
 | 
				
			||||||
 | 
					 80483eb:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483ed:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483ef:	90                   	nop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					080483f0 <func2>:
 | 
				
			||||||
 | 
					void func2(int a, int b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 80483f0:	f3 c3                	repz ret 
 | 
				
			||||||
 | 
					 80483f2:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483f4:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483f6:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483f8:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483fa:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483fc:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					 80483fe:	66 90                	xchg   %ax,%ax
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048400 <__libc_csu_init>:
 | 
				
			||||||
 | 
					 8048400:	55                   	push   %ebp
 | 
				
			||||||
 | 
					 8048401:	57                   	push   %edi
 | 
				
			||||||
 | 
					 8048402:	31 ff                	xor    %edi,%edi
 | 
				
			||||||
 | 
					 8048404:	56                   	push   %esi
 | 
				
			||||||
 | 
					 8048405:	53                   	push   %ebx
 | 
				
			||||||
 | 
					 8048406:	e8 15 ff ff ff       	call   8048320 <__x86.get_pc_thunk.bx>
 | 
				
			||||||
 | 
					 804840b:	81 c3 f5 1b 00 00    	add    $0x1bf5,%ebx
 | 
				
			||||||
 | 
					 8048411:	83 ec 0c             	sub    $0xc,%esp
 | 
				
			||||||
 | 
					 8048414:	8b 6c 24 20          	mov    0x20(%esp),%ebp
 | 
				
			||||||
 | 
					 8048418:	8d b3 0c ff ff ff    	lea    -0xf4(%ebx),%esi
 | 
				
			||||||
 | 
					 804841e:	e8 71 fe ff ff       	call   8048294 <_init>
 | 
				
			||||||
 | 
					 8048423:	8d 83 08 ff ff ff    	lea    -0xf8(%ebx),%eax
 | 
				
			||||||
 | 
					 8048429:	29 c6                	sub    %eax,%esi
 | 
				
			||||||
 | 
					 804842b:	c1 fe 02             	sar    $0x2,%esi
 | 
				
			||||||
 | 
					 804842e:	85 f6                	test   %esi,%esi
 | 
				
			||||||
 | 
					 8048430:	74 23                	je     8048455 <__libc_csu_init+0x55>
 | 
				
			||||||
 | 
					 8048432:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
 | 
				
			||||||
 | 
					 8048438:	83 ec 04             	sub    $0x4,%esp
 | 
				
			||||||
 | 
					 804843b:	ff 74 24 2c          	pushl  0x2c(%esp)
 | 
				
			||||||
 | 
					 804843f:	ff 74 24 2c          	pushl  0x2c(%esp)
 | 
				
			||||||
 | 
					 8048443:	55                   	push   %ebp
 | 
				
			||||||
 | 
					 8048444:	ff 94 bb 08 ff ff ff 	call   *-0xf8(%ebx,%edi,4)
 | 
				
			||||||
 | 
					 804844b:	83 c7 01             	add    $0x1,%edi
 | 
				
			||||||
 | 
					 804844e:	83 c4 10             	add    $0x10,%esp
 | 
				
			||||||
 | 
					 8048451:	39 f7                	cmp    %esi,%edi
 | 
				
			||||||
 | 
					 8048453:	75 e3                	jne    8048438 <__libc_csu_init+0x38>
 | 
				
			||||||
 | 
					 8048455:	83 c4 0c             	add    $0xc,%esp
 | 
				
			||||||
 | 
					 8048458:	5b                   	pop    %ebx
 | 
				
			||||||
 | 
					 8048459:	5e                   	pop    %esi
 | 
				
			||||||
 | 
					 804845a:	5f                   	pop    %edi
 | 
				
			||||||
 | 
					 804845b:	5d                   	pop    %ebp
 | 
				
			||||||
 | 
					 804845c:	c3                   	ret    
 | 
				
			||||||
 | 
					 804845d:	8d 76 00             	lea    0x0(%esi),%esi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048460 <__libc_csu_fini>:
 | 
				
			||||||
 | 
					 8048460:	f3 c3                	repz ret 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disassembly of section .fini:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					08048464 <_fini>:
 | 
				
			||||||
 | 
					 8048464:	53                   	push   %ebx
 | 
				
			||||||
 | 
					 8048465:	83 ec 08             	sub    $0x8,%esp
 | 
				
			||||||
 | 
					 8048468:	e8 b3 fe ff ff       	call   8048320 <__x86.get_pc_thunk.bx>
 | 
				
			||||||
 | 
					 804846d:	81 c3 93 1b 00 00    	add    $0x1b93,%ebx
 | 
				
			||||||
 | 
					 8048473:	83 c4 08             	add    $0x8,%esp
 | 
				
			||||||
 | 
					 8048476:	5b                   	pop    %ebx
 | 
				
			||||||
 | 
					 8048477:	c3                   	ret    
 | 
				
			||||||
							
								
								
									
										17
									
								
								related_info/lab4/some-exercises/callee.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								related_info/lab4/some-exercises/callee.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					.code32
 | 
				
			||||||
 | 
					SYSWRITE = 4    # sys_write()系统调用号
 | 
				
			||||||
 | 
					.global mywrite
 | 
				
			||||||
 | 
					.text
 | 
				
			||||||
 | 
					mywrite:
 | 
				
			||||||
 | 
					 pushl %ebp
 | 
				
			||||||
 | 
					 movl %esp, %ebp
 | 
				
			||||||
 | 
					 pushl %ebx
 | 
				
			||||||
 | 
					 movl 8(%ebp),%ebx  # ebx :文件描述符
 | 
				
			||||||
 | 
					 movl 12(%ebp),%ecx  # ecx :缓冲区指针
 | 
				
			||||||
 | 
					 movl 16(%ebp),%edx  # edx :显示字符数
 | 
				
			||||||
 | 
					 movl $SYSWRITE,%eax   # eax :系统调用号
 | 
				
			||||||
 | 
					 int $0x80
 | 
				
			||||||
 | 
					 popl %ebx
 | 
				
			||||||
 | 
					 mov %ebp, %esp
 | 
				
			||||||
 | 
					 popl %ebp
 | 
				
			||||||
 | 
					 ret
 | 
				
			||||||
							
								
								
									
										7
									
								
								related_info/lab4/some-exercises/caller.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								related_info/lab4/some-exercises/caller.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					int main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 char* mystr = "Welcome to baby OS!\n";
 | 
				
			||||||
 | 
					 mywrite(1, mystr, strlen(mystr));
 | 
				
			||||||
 | 
					 return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										411
									
								
								related_info/lab4/some-exercises/proc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										411
									
								
								related_info/lab4/some-exercises/proc.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,411 @@
 | 
				
			|||||||
 | 
					#include <proc.h>
 | 
				
			||||||
 | 
					#include <kmalloc.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <sync.h>
 | 
				
			||||||
 | 
					#include <pmm.h>
 | 
				
			||||||
 | 
					#include <error.h>
 | 
				
			||||||
 | 
					#include <sched.h>
 | 
				
			||||||
 | 
					#include <elf.h>
 | 
				
			||||||
 | 
					#include <vmm.h>
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ------------- process/thread mechanism design&implementation -------------
 | 
				
			||||||
 | 
					(an simplified Linux process/thread mechanism )
 | 
				
			||||||
 | 
					introduction:
 | 
				
			||||||
 | 
					  ucore implements a simple process/thread mechanism. process contains the independent memory sapce, at least one threads
 | 
				
			||||||
 | 
					for execution, the kernel data(for management), processor state (for context switch), files(in lab6), etc. ucore needs to
 | 
				
			||||||
 | 
					manage all these details efficiently. In ucore, a thread is just a special kind of process(share process's memory).
 | 
				
			||||||
 | 
					------------------------------
 | 
				
			||||||
 | 
					process state       :     meaning               -- reason
 | 
				
			||||||
 | 
					    PROC_UNINIT     :   uninitialized           -- alloc_proc
 | 
				
			||||||
 | 
					    PROC_SLEEPING   :   sleeping                -- try_free_pages, do_wait, do_sleep
 | 
				
			||||||
 | 
					    PROC_RUNNABLE   :   runnable(maybe running) -- proc_init, wakeup_proc, 
 | 
				
			||||||
 | 
					    PROC_ZOMBIE     :   almost dead             -- do_exit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-----------------------------
 | 
				
			||||||
 | 
					process state changing:
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					  alloc_proc                                 RUNNING
 | 
				
			||||||
 | 
					      +                                   +--<----<--+
 | 
				
			||||||
 | 
					      +                                   + proc_run +
 | 
				
			||||||
 | 
					      V                                   +-->---->--+ 
 | 
				
			||||||
 | 
					PROC_UNINIT -- proc_init/wakeup_proc --> PROC_RUNNABLE -- try_free_pages/do_wait/do_sleep --> PROC_SLEEPING --
 | 
				
			||||||
 | 
					                                           A      +                                                           +
 | 
				
			||||||
 | 
					                                           |      +--- do_exit --> PROC_ZOMBIE                                +
 | 
				
			||||||
 | 
					                                           +                                                                  + 
 | 
				
			||||||
 | 
					                                           -----------------------wakeup_proc----------------------------------
 | 
				
			||||||
 | 
					-----------------------------
 | 
				
			||||||
 | 
					process relations
 | 
				
			||||||
 | 
					parent:           proc->parent  (proc is children)
 | 
				
			||||||
 | 
					children:         proc->cptr    (proc is parent)
 | 
				
			||||||
 | 
					older sibling:    proc->optr    (proc is younger sibling)
 | 
				
			||||||
 | 
					younger sibling:  proc->yptr    (proc is older sibling)
 | 
				
			||||||
 | 
					-----------------------------
 | 
				
			||||||
 | 
					related syscall for process:
 | 
				
			||||||
 | 
					SYS_exit        : process exit,                           -->do_exit
 | 
				
			||||||
 | 
					SYS_fork        : create child process, dup mm            -->do_fork-->wakeup_proc
 | 
				
			||||||
 | 
					SYS_wait        : wait process                            -->do_wait
 | 
				
			||||||
 | 
					SYS_exec        : after fork, process execute a program   -->load a program and refresh the mm
 | 
				
			||||||
 | 
					SYS_clone       : create child thread                     -->do_fork-->wakeup_proc
 | 
				
			||||||
 | 
					SYS_yield       : process flag itself need resecheduling, -- proc->need_sched=1, then scheduler will rescheule this process
 | 
				
			||||||
 | 
					SYS_sleep       : process sleep                           -->do_sleep 
 | 
				
			||||||
 | 
					SYS_kill        : kill process                            -->do_kill-->proc->flags |= PF_EXITING
 | 
				
			||||||
 | 
					                                                                 -->wakeup_proc-->do_wait-->do_exit   
 | 
				
			||||||
 | 
					SYS_getpid      : get the process's pid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// the process set's list
 | 
				
			||||||
 | 
					list_entry_t proc_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HASH_SHIFT          10
 | 
				
			||||||
 | 
					#define HASH_LIST_SIZE      (1 << HASH_SHIFT)
 | 
				
			||||||
 | 
					#define pid_hashfn(x)       (hash32(x, HASH_SHIFT))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// has list for process set based on pid
 | 
				
			||||||
 | 
					static list_entry_t hash_list[HASH_LIST_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// idle proc
 | 
				
			||||||
 | 
					struct proc_struct *idleproc = NULL;
 | 
				
			||||||
 | 
					// init proc
 | 
				
			||||||
 | 
					struct proc_struct *initproc = NULL;
 | 
				
			||||||
 | 
					// current proc
 | 
				
			||||||
 | 
					struct proc_struct *current = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int nr_process = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kernel_thread_entry(void);
 | 
				
			||||||
 | 
					void forkrets(struct trapframe *tf);
 | 
				
			||||||
 | 
					void switch_to(struct context *from, struct context *to);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// alloc_proc - alloc a proc_struct and init all fields of proc_struct
 | 
				
			||||||
 | 
					static struct proc_struct *
 | 
				
			||||||
 | 
					alloc_proc(void) {
 | 
				
			||||||
 | 
					    struct proc_struct *proc = kmalloc(sizeof(struct proc_struct));
 | 
				
			||||||
 | 
					    if (proc != NULL) {
 | 
				
			||||||
 | 
					    //LAB4:EXERCISE1 YOUR CODE
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * below fields in proc_struct need to be initialized
 | 
				
			||||||
 | 
					     *       enum proc_state state;                      // Process state
 | 
				
			||||||
 | 
					     *       int pid;                                    // Process ID
 | 
				
			||||||
 | 
					     *       int runs;                                   // the running times of Proces
 | 
				
			||||||
 | 
					     *       uintptr_t kstack;                           // Process kernel stack
 | 
				
			||||||
 | 
					     *       volatile bool need_resched;                 // bool value: need to be rescheduled to release CPU?
 | 
				
			||||||
 | 
					     *       struct proc_struct *parent;                 // the parent process
 | 
				
			||||||
 | 
					     *       struct mm_struct *mm;                       // Process's memory management field
 | 
				
			||||||
 | 
					     *       struct context context;                     // Switch here to run process
 | 
				
			||||||
 | 
					     *       struct trapframe *tf;                       // Trap frame for current interrupt
 | 
				
			||||||
 | 
					     *       uintptr_t cr3;                              // CR3 register: the base addr of Page Directroy Table(PDT)
 | 
				
			||||||
 | 
					     *       uint32_t flags;                             // Process flag
 | 
				
			||||||
 | 
					     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					        proc->state = PROC_UNINIT;
 | 
				
			||||||
 | 
					        proc->pid = -1;
 | 
				
			||||||
 | 
					        proc->runs = 0;
 | 
				
			||||||
 | 
					        proc->kstack = 0;
 | 
				
			||||||
 | 
					        proc->need_resched = 0;
 | 
				
			||||||
 | 
					        proc->parent = NULL;
 | 
				
			||||||
 | 
					        proc->mm = NULL;
 | 
				
			||||||
 | 
					        memset(&(proc->context), 0, sizeof(struct context));
 | 
				
			||||||
 | 
					        proc->tf = NULL;
 | 
				
			||||||
 | 
					        proc->cr3 = boot_cr3;
 | 
				
			||||||
 | 
					        proc->flags = 0;
 | 
				
			||||||
 | 
					        memset(proc->name, 0, PROC_NAME_LEN);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return proc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// set_proc_name - set the name of proc
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					set_proc_name(struct proc_struct *proc, const char *name) {
 | 
				
			||||||
 | 
					    memset(proc->name, 0, sizeof(proc->name));
 | 
				
			||||||
 | 
					    return memcpy(proc->name, name, PROC_NAME_LEN);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// get_proc_name - get the name of proc
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					get_proc_name(struct proc_struct *proc) {
 | 
				
			||||||
 | 
					    static char name[PROC_NAME_LEN + 1];
 | 
				
			||||||
 | 
					    memset(name, 0, sizeof(name));
 | 
				
			||||||
 | 
					    return memcpy(name, proc->name, PROC_NAME_LEN);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// get_pid - alloc a unique pid for process
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					get_pid(void) {
 | 
				
			||||||
 | 
					    static_assert(MAX_PID > MAX_PROCESS);
 | 
				
			||||||
 | 
					    struct proc_struct *proc;
 | 
				
			||||||
 | 
					    list_entry_t *list = &proc_list, *le;
 | 
				
			||||||
 | 
					    static int next_safe = MAX_PID, last_pid = MAX_PID;
 | 
				
			||||||
 | 
					    if (++ last_pid >= MAX_PID) {
 | 
				
			||||||
 | 
					        last_pid = 1;
 | 
				
			||||||
 | 
					        goto inside;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (last_pid >= next_safe) {
 | 
				
			||||||
 | 
					    inside:
 | 
				
			||||||
 | 
					        next_safe = MAX_PID;
 | 
				
			||||||
 | 
					    repeat:
 | 
				
			||||||
 | 
					        le = list;
 | 
				
			||||||
 | 
					        while ((le = list_next(le)) != list) {
 | 
				
			||||||
 | 
					            proc = le2proc(le, list_link);
 | 
				
			||||||
 | 
					            if (proc->pid == last_pid) {
 | 
				
			||||||
 | 
					                if (++ last_pid >= next_safe) {
 | 
				
			||||||
 | 
					                    if (last_pid >= MAX_PID) {
 | 
				
			||||||
 | 
					                        last_pid = 1;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    next_safe = MAX_PID;
 | 
				
			||||||
 | 
					                    goto repeat;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (proc->pid > last_pid && next_safe > proc->pid) {
 | 
				
			||||||
 | 
					                next_safe = proc->pid;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return last_pid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// proc_run - make process "proc" running on cpu
 | 
				
			||||||
 | 
					// NOTE: before call switch_to, should load  base addr of "proc"'s new PDT
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					proc_run(struct proc_struct *proc) {
 | 
				
			||||||
 | 
					    if (proc != current) {
 | 
				
			||||||
 | 
					        bool intr_flag;
 | 
				
			||||||
 | 
					        struct proc_struct *prev = current, *next = proc;
 | 
				
			||||||
 | 
					        local_intr_save(intr_flag);
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            current = proc;
 | 
				
			||||||
 | 
					            load_esp0(next->kstack + KSTACKSIZE);
 | 
				
			||||||
 | 
					            lcr3(next->cr3);
 | 
				
			||||||
 | 
					            switch_to(&(prev->context), &(next->context));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        local_intr_restore(intr_flag);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// forkret -- the first kernel entry point of a new thread/process
 | 
				
			||||||
 | 
					// NOTE: the addr of forkret is setted in copy_thread function
 | 
				
			||||||
 | 
					//       after switch_to, the current proc will execute here.
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					forkret(void) {
 | 
				
			||||||
 | 
					    forkrets(current->tf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// hash_proc - add proc into proc hash_list
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					hash_proc(struct proc_struct *proc) {
 | 
				
			||||||
 | 
					    list_add(hash_list + pid_hashfn(proc->pid), &(proc->hash_link));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// find_proc - find proc frome proc hash_list according to pid
 | 
				
			||||||
 | 
					struct proc_struct *
 | 
				
			||||||
 | 
					find_proc(int pid) {
 | 
				
			||||||
 | 
					    if (0 < pid && pid < MAX_PID) {
 | 
				
			||||||
 | 
					        list_entry_t *list = hash_list + pid_hashfn(pid), *le = list;
 | 
				
			||||||
 | 
					        while ((le = list_next(le)) != list) {
 | 
				
			||||||
 | 
					            struct proc_struct *proc = le2proc(le, hash_link);
 | 
				
			||||||
 | 
					            if (proc->pid == pid) {
 | 
				
			||||||
 | 
					                return proc;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// kernel_thread - create a kernel thread using "fn" function
 | 
				
			||||||
 | 
					// NOTE: the contents of temp trapframe tf will be copied to 
 | 
				
			||||||
 | 
					//       proc->tf in do_fork-->copy_thread function
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					kernel_thread(int (*fn)(void *), void *arg, uint32_t clone_flags) {
 | 
				
			||||||
 | 
					    struct trapframe tf;
 | 
				
			||||||
 | 
					    memset(&tf, 0, sizeof(struct trapframe));
 | 
				
			||||||
 | 
					    tf.tf_cs = KERNEL_CS;
 | 
				
			||||||
 | 
					    tf.tf_ds = tf.tf_es = tf.tf_ss = KERNEL_DS;
 | 
				
			||||||
 | 
					    tf.tf_regs.reg_ebx = (uint32_t)fn;
 | 
				
			||||||
 | 
					    tf.tf_regs.reg_edx = (uint32_t)arg;
 | 
				
			||||||
 | 
					    tf.tf_eip = (uint32_t)kernel_thread_entry;
 | 
				
			||||||
 | 
					    return do_fork(clone_flags | CLONE_VM, 0, &tf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setup_kstack - alloc pages with size KSTACKPAGE as process kernel stack
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					setup_kstack(struct proc_struct *proc) {
 | 
				
			||||||
 | 
					    struct Page *page = alloc_pages(KSTACKPAGE);
 | 
				
			||||||
 | 
					    if (page != NULL) {
 | 
				
			||||||
 | 
					        proc->kstack = (uintptr_t)page2kva(page);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return -E_NO_MEM;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// put_kstack - free the memory space of process kernel stack
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					put_kstack(struct proc_struct *proc) {
 | 
				
			||||||
 | 
					    free_pages(kva2page((void *)(proc->kstack)), KSTACKPAGE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// copy_mm - process "proc" duplicate OR share process "current"'s mm according clone_flags
 | 
				
			||||||
 | 
					//         - if clone_flags & CLONE_VM, then "share" ; else "duplicate"
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					copy_mm(uint32_t clone_flags, struct proc_struct *proc) {
 | 
				
			||||||
 | 
					    assert(current->mm == NULL);
 | 
				
			||||||
 | 
					    /* do nothing in this project */
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// copy_thread - setup the trapframe on the  process's kernel stack top and
 | 
				
			||||||
 | 
					//             - setup the kernel entry point and stack of process
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    proc->tf = (struct trapframe *)(proc->kstack + KSTACKSIZE) - 1;
 | 
				
			||||||
 | 
					    *(proc->tf) = *tf;
 | 
				
			||||||
 | 
					    proc->tf->tf_regs.reg_eax = 0;
 | 
				
			||||||
 | 
					    proc->tf->tf_esp = esp;
 | 
				
			||||||
 | 
					    proc->tf->tf_eflags |= FL_IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    proc->context.eip = (uintptr_t)forkret;
 | 
				
			||||||
 | 
					    proc->context.esp = (uintptr_t)(proc->tf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* do_fork -     parent process for a new child process
 | 
				
			||||||
 | 
					 * @clone_flags: used to guide how to clone the child process
 | 
				
			||||||
 | 
					 * @stack:       the parent's user stack pointer. if stack==0, It means to fork a kernel thread.
 | 
				
			||||||
 | 
					 * @tf:          the trapframe info, which will be copied to child process's proc->tf
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    int ret = -E_NO_FREE_PROC;
 | 
				
			||||||
 | 
					    struct proc_struct *proc;
 | 
				
			||||||
 | 
					    if (nr_process >= MAX_PROCESS) {
 | 
				
			||||||
 | 
					        goto fork_out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ret = -E_NO_MEM;
 | 
				
			||||||
 | 
					    //LAB4:EXERCISE2 YOUR CODE
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Some Useful MACROs, Functions and DEFINEs, you can use them in below implementation.
 | 
				
			||||||
 | 
					     * MACROs or Functions:
 | 
				
			||||||
 | 
					     *   alloc_proc:   create a proc struct and init fields (lab4:exercise1)
 | 
				
			||||||
 | 
					     *   setup_kstack: alloc pages with size KSTACKPAGE as process kernel stack
 | 
				
			||||||
 | 
					     *   copy_mm:      process "proc" duplicate OR share process "current"'s mm according clone_flags
 | 
				
			||||||
 | 
					     *                 if clone_flags & CLONE_VM, then "share" ; else "duplicate"
 | 
				
			||||||
 | 
					     *   copy_thread:  setup the trapframe on the  process's kernel stack top and
 | 
				
			||||||
 | 
					     *                 setup the kernel entry point and stack of process
 | 
				
			||||||
 | 
					     *   hash_proc:    add proc into proc hash_list
 | 
				
			||||||
 | 
					     *   get_pid:      alloc a unique pid for process
 | 
				
			||||||
 | 
					     *   wakeup_proc:  set proc->state = PROC_RUNNABLE
 | 
				
			||||||
 | 
					     * VARIABLES:
 | 
				
			||||||
 | 
					     *   proc_list:    the process set's list
 | 
				
			||||||
 | 
					     *   nr_process:   the number of process set
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //    1. call alloc_proc to allocate a proc_struct
 | 
				
			||||||
 | 
					    //    2. call setup_kstack to allocate a kernel stack for child process
 | 
				
			||||||
 | 
					    //    3. call copy_mm to dup OR share mm according clone_flag
 | 
				
			||||||
 | 
					    //    4. call copy_thread to setup tf & context in proc_struct
 | 
				
			||||||
 | 
					    //    5. insert proc_struct into hash_list && proc_list
 | 
				
			||||||
 | 
					    //    6. call wakeup_proc to make the new child process RUNNABLE
 | 
				
			||||||
 | 
					    //    7. set ret vaule using child proc's pid
 | 
				
			||||||
 | 
					    if ((proc = alloc_proc()) == NULL) {
 | 
				
			||||||
 | 
					        goto fork_out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    proc->parent = current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (setup_kstack(proc) != 0) {
 | 
				
			||||||
 | 
					        goto bad_fork_cleanup_proc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (copy_mm(clone_flags, proc) != 0) {
 | 
				
			||||||
 | 
					        goto bad_fork_cleanup_kstack;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    copy_thread(proc, stack, tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool intr_flag;
 | 
				
			||||||
 | 
					    local_intr_save(intr_flag);
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        proc->pid = get_pid();
 | 
				
			||||||
 | 
					        hash_proc(proc);
 | 
				
			||||||
 | 
					        list_add(&proc_list, &(proc->list_link));
 | 
				
			||||||
 | 
					        nr_process ++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wakeup_proc(proc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = proc->pid;
 | 
				
			||||||
 | 
					fork_out:
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bad_fork_cleanup_kstack:
 | 
				
			||||||
 | 
					    put_kstack(proc);
 | 
				
			||||||
 | 
					bad_fork_cleanup_proc:
 | 
				
			||||||
 | 
					    kfree(proc);
 | 
				
			||||||
 | 
					    goto fork_out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// do_exit - called by sys_exit
 | 
				
			||||||
 | 
					//   1. call exit_mmap & put_pgdir & mm_destroy to free the almost all memory space of process
 | 
				
			||||||
 | 
					//   2. set process' state as PROC_ZOMBIE, then call wakeup_proc(parent) to ask parent reclaim itself.
 | 
				
			||||||
 | 
					//   3. call scheduler to switch to other process
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					do_exit(int error_code) {
 | 
				
			||||||
 | 
					    panic("process exit!!.\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// init_main - the second kernel thread used to create user_main kernel threads
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					init_main(void *arg) {
 | 
				
			||||||
 | 
					    cprintf("this initproc, pid = %d, name = \"%s\"\n", current->pid, get_proc_name(current));
 | 
				
			||||||
 | 
					    cprintf("To U: \"%s\".\n", (const char *)arg);
 | 
				
			||||||
 | 
					    cprintf("To U: \"en.., Bye, Bye. :)\"\n");
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// proc_init - set up the first kernel thread idleproc "idle" by itself and 
 | 
				
			||||||
 | 
					//           - create the second kernel thread init_main
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					proc_init(void) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    list_init(&proc_list);
 | 
				
			||||||
 | 
					    for (i = 0; i < HASH_LIST_SIZE; i ++) {
 | 
				
			||||||
 | 
					        list_init(hash_list + i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((idleproc = alloc_proc()) == NULL) {
 | 
				
			||||||
 | 
					        panic("cannot alloc idleproc.\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    idleproc->pid = 0;
 | 
				
			||||||
 | 
					    idleproc->state = PROC_RUNNABLE;
 | 
				
			||||||
 | 
					    idleproc->kstack = (uintptr_t)bootstack;
 | 
				
			||||||
 | 
					    idleproc->need_resched = 1;
 | 
				
			||||||
 | 
					    set_proc_name(idleproc, "idle");
 | 
				
			||||||
 | 
					    nr_process ++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    current = idleproc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int pid = kernel_thread(init_main, "Hello world!!", 0);
 | 
				
			||||||
 | 
					    if (pid <= 0) {
 | 
				
			||||||
 | 
					        panic("create init_main failed.\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    initproc = find_proc(pid);
 | 
				
			||||||
 | 
					    set_proc_name(initproc, "init");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(idleproc != NULL && idleproc->pid == 0);
 | 
				
			||||||
 | 
					    assert(initproc != NULL && initproc->pid == 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// cpu_idle - at the end of kern_init, the first kernel thread idleproc will do below works
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cpu_idle(void) {
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        if (current->need_resched) {
 | 
				
			||||||
 | 
					            schedule();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								related_info/lab4/some-exercises/prog.s
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								related_info/lab4/some-exercises/prog.s
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					.section __TEXT,__text
 | 
				
			||||||
 | 
					.globl start
 | 
				
			||||||
 | 
					start:
 | 
				
			||||||
 | 
					mov $0x1, %eax
 | 
				
			||||||
 | 
					push $0x0
 | 
				
			||||||
 | 
					call _syscall
 | 
				
			||||||
 | 
					_syscall:
 | 
				
			||||||
 | 
					int $0x80
 | 
				
			||||||
							
								
								
									
										30
									
								
								related_info/lab4/some-exercises/switch.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								related_info/lab4/some-exercises/switch.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					.text
 | 
				
			||||||
 | 
					.globl switch_to
 | 
				
			||||||
 | 
					switch_to:                      # switch_to(from, to)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # save from's registers
 | 
				
			||||||
 | 
					    movl 4(%esp), %eax          # eax points to from
 | 
				
			||||||
 | 
					    popl 0(%eax)                # save eip !popl
 | 
				
			||||||
 | 
					    movl %esp, 4(%eax)
 | 
				
			||||||
 | 
					    movl %ebx, 8(%eax)
 | 
				
			||||||
 | 
					    movl %ecx, 12(%eax)
 | 
				
			||||||
 | 
					    movl %edx, 16(%eax)
 | 
				
			||||||
 | 
					    movl %esi, 20(%eax)
 | 
				
			||||||
 | 
					    movl %edi, 24(%eax)
 | 
				
			||||||
 | 
					    movl %ebp, 28(%eax)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # restore to's registers
 | 
				
			||||||
 | 
					    movl 4(%esp), %eax          # not 8(%esp): popped return address already
 | 
				
			||||||
 | 
					                                # eax now points to to
 | 
				
			||||||
 | 
					    movl 28(%eax), %ebp
 | 
				
			||||||
 | 
					    movl 24(%eax), %edi
 | 
				
			||||||
 | 
					    movl 20(%eax), %esi
 | 
				
			||||||
 | 
					    movl 16(%eax), %edx
 | 
				
			||||||
 | 
					    movl 12(%eax), %ecx
 | 
				
			||||||
 | 
					    movl 8(%eax), %ebx
 | 
				
			||||||
 | 
					    movl 4(%eax), %esp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pushl 0(%eax)               # push eip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user