22#include "defs.h"
33#include "trap.h"
44
5- static uint64 app_num ;
5+ static int app_num ;
66static uint64 * app_info_ptr ;
7- extern char _app_num [], ekernel [] ;
7+ extern char _app_num [];
88
99// Count finished programs. If all apps exited, shutdown.
1010int finished ()
@@ -18,35 +18,54 @@ int finished()
1818// Get user progs' infomation through pre-defined symbol in `link_app.S`
1919void loader_init ()
2020{
21- if ((uint64 )ekernel >= BASE_ADDRESS ) {
22- panic ("kernel too large...\n" );
23- }
2421 app_info_ptr = (uint64 * )_app_num ;
2522 app_num = * app_info_ptr ;
2623 app_info_ptr ++ ;
2724}
2825
29- // Load nth user app at
30- // [BASE_ADDRESS + n * MAX_APP_SIZE, BASE_ADDRESS + (n+1) * MAX_APP_SIZE)
31- int load_app (int n , uint64 * info )
26+ pagetable_t bin_loader (uint64 start , uint64 end , struct proc * p )
3227{
33- uint64 start = info [n ], end = info [n + 1 ], length = end - start ;
34- memset ((void * )BASE_ADDRESS + n * MAX_APP_SIZE , 0 , MAX_APP_SIZE );
35- memmove ((void * )BASE_ADDRESS + n * MAX_APP_SIZE , (void * )start , length );
36- return length ;
28+ pagetable_t pg = uvmcreate ();
29+ if (mappages (pg , TRAPFRAME , PGSIZE , (uint64 )p -> trapframe ,
30+ PTE_R | PTE_W ) < 0 ) {
31+ panic ("mappages fail" );
32+ }
33+ if (!PGALIGNED (start )) {
34+ panic ("user program not aligned, start = %p" , start );
35+ }
36+ if (!PGALIGNED (end )) {
37+ // Fix in ch5
38+ warnf ("Some kernel data maybe mapped to user, start = %p, end = %p" ,
39+ start , end );
40+ }
41+ end = PGROUNDUP (end );
42+ uint64 length = end - start ;
43+ if (mappages (pg , BASE_ADDRESS , length , start ,
44+ PTE_U | PTE_R | PTE_W | PTE_X ) != 0 ) {
45+ panic ("mappages fail" );
46+ }
47+ p -> pagetable = pg ;
48+ uint64 ustack_bottom_vaddr = BASE_ADDRESS + length + PAGE_SIZE ;
49+ if (USTACK_SIZE != PAGE_SIZE ) {
50+ // Fix in ch5
51+ panic ("Unsupported" );
52+ }
53+ mappages (pg , ustack_bottom_vaddr , USTACK_SIZE , (uint64 )kalloc (),
54+ PTE_U | PTE_R | PTE_W | PTE_X );
55+ p -> ustack = ustack_bottom_vaddr ;
56+ p -> trapframe -> epc = BASE_ADDRESS ;
57+ p -> trapframe -> sp = p -> ustack + USTACK_SIZE ;
58+ p -> max_page = PGROUNDUP (p -> ustack + USTACK_SIZE - 1 ) / PAGE_SIZE ;
59+ return pg ;
3760}
3861
3962// load all apps and init the corresponding `proc` structure.
4063int run_all_app ()
4164{
4265 for (int i = 0 ; i < app_num ; ++ i ) {
4366 struct proc * p = allocproc ();
44- struct trapframe * trapframe = p -> trapframe ;
45- load_app (i , app_info_ptr );
46- uint64 entry = BASE_ADDRESS + i * MAX_APP_SIZE ;
47- tracef ("load app %d at %p" , i , entry );
48- trapframe -> epc = entry ;
49- trapframe -> sp = (uint64 )p -> ustack + USER_STACK_SIZE ;
67+ tracef ("load app %d" , i );
68+ bin_loader (app_info_ptr [i ], app_info_ptr [i + 1 ], p );
5069 p -> state = RUNNABLE ;
5170 }
5271 return 0 ;
0 commit comments