-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsystem.c
More file actions
337 lines (256 loc) · 6.74 KB
/
system.c
File metadata and controls
337 lines (256 loc) · 6.74 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/*
** SCCS ID: @(#)system.c 1.1 4/17/15
**
** File: system.c
**
** Author: CSCI-452 class of 20145
**
** Contributor:
**
** Description: Miscellaneous OS support implementations
*/
#define __SP_KERNEL__
#include "common.h"
#include "system.h"
#include "clock.h"
#include "process.h"
#include "bootstrap.h"
#include "syscall.h"
#include "sio.h"
#include "scheduler.h"
// need address of the initial user process
#include "user.h"
// need the __default_exit__() prototype
#include "ulib.h"
// include file system
#include "fileSystem.h"
/*
** PRIVATE DEFINITIONS
*/
/*
** PRIVATE DATA TYPES
*/
/*
** PRIVATE GLOBAL VARIABLES
*/
/*
** PUBLIC GLOBAL VARIABLES
*/
/*
** PRIVATE FUNCTIONS
*/
/*
** PUBLIC FUNCTIONS
*/
/*
** _create_process(entry,prio)
**
** allocate and initialize a new process' data structures (PCB, stack)
**
** returns:
** pointer to the new PCB
*/
pcb_t *_create_process( uint32_t entry, uint8_t prio ) {
pcb_t *new;
uint32_t *ptr;
// allocate the new structures
new = _pcb_alloc();
if( new == NULL ) {
return( NULL );
}
// clear all the fields in the PCB
_memset( (void *) new, sizeof(pcb_t), 0 );
// allocate the runtime stack
new->stack = _stack_alloc();
if( new->stack == NULL ) {
_pcb_dealloc( new );
return( NULL );
}
/*
** We need to set up the initial stack contents for the new
** process. The low end of the initial stack must look like this:
**
** esp -> ? <- context save area
** ... <- context save area
** ? <- context save area
** exit <- return address for faked call to main()
** 0 <- last word in stack
*/
// first, create a pointer to the longword after the stack
ptr = (uint32_t *) (new->stack + 1);
// save the buffering 0 at the end
*--ptr = 0;
// fake a return address so that if the user function returns
// without calling exit(), we return "into" a function which
// calls exit()
*--ptr = (uint32_t) __default_exit__;
// locate the context save area
new->context = ((context_t *) ptr) - 1;
// fill in the non-zero entries in the context save area
new->context->eip = entry;
new->context->cs = GDT_CODE;
new->context->ss = GDT_STACK;
new->context->ds = GDT_DATA;
new->context->es = GDT_DATA;
new->context->fs = GDT_DATA;
new->context->gs = GDT_DATA;
new->context->eflags = DEFAULT_EFLAGS;
// fill in the remaining important fields
new->prio = prio;
new->pid = _next_pid++;
new->default_quantum = QUANTUM_DEFAULT;
new->state = STATE_READY;
// all done - return the new PCB
return( new );
}
/*
** _init - system initialization routine
**
** Called by the startup code immediately before returning into the
** first user process.
*/
void _init( void ) {
pcb_t *pcb;
/*
** BOILERPLATE CODE - taken from basic framework
**
** Initialize interrupt stuff.
*/
__init_interrupts(); // IDT and PIC initialization
/*
** Console I/O system.
*/
c_io_init();
c_setscroll( 0, 7, 99, 99 );
c_puts_at( 0, 6, "================================================================================" );
/*
** 20145-SPECIFIC CODE STARTS HERE
*/
/*
** Initialize various OS modules
**
** Note: the clock, SIO, and syscall modules also install
** their ISRs.
*/
c_puts( "Module init: " );
_queue_modinit(); // must be first
_pcb_modinit();
_stack_modinit();
_sched_modinit();
_sio_modinit();
_sys_modinit();
_clock_modinit();
_sfs_init();
c_puts( "\n" );
/*
** Create the initial system ESP
**
** This will be the address of the next-to-last
** longword in the system stack.
*/
_system_esp = ((uint32_t *) ( (&_system_stack) + 1)) - 2;
/*
** Create the initial process
**
** Code mostly stolen from _sys_spawnp(); if that routine
** changes, SO MUST THIS!!!
*/
pcb = _create_process( (uint32_t) init, PRIO_SYSTEM );
if( pcb == NULL ) {
_kpanic( "_init", "init() creation failed" );
}
_pcb_dump( "init() pcb", pcb );
_context_dump( "init() context", pcb->context );
_schedule( pcb );
/*
** Next, create the idle process
*/
pcb = _create_process( (uint32_t) idle, PRIO_USER_LOW );
if( pcb == NULL ) {
_kpanic( "_init", "idle() creation failed" );
}
_schedule( pcb );
/*
** Turn on the SIO receiver (the transmitter will be turned
** on/off as characters are being sent)
*/
_sio_enable( SIO_RX );
/*
** Start the hello world process, see if this thing works -- Max Roth
*/
pcb = _create_process( (uint32_t) hello, PRIO_USER_HIGH );
if( pcb == NULL ) {
_kpanic( "_init", "hello() creation failed" );
}
_schedule( pcb );
/*
** Send the first process off to play
*/
_dispatch();
/*
** END OF 20145-SPECIFIC CODE
**
** Finally, report that we're all done.
*/
c_puts( "System initialization complete.\n" );
/*
** Create the shell
*/
// Clear the terminal for our shell
_sio_writec(26);
pcb = _create_process( (uint32_t) shell, PRIO_USER_STD );
if( pcb == NULL ) {
_kpanic( "_init", "shell() creation failed" );
}
_schedule( pcb );
//Basic file system test
if(1){
c_puts( "Creating file...\n" );
int c_test = _sfs_create("/TEST.txt", FILE);
c_puts( "File Created...\n" );
sfs_entry* exists = _sfs_exists("/TEST.txt", FILE);
if(compare((char*)&exists->name,ROOT) != 0)
c_puts( "File exists...\n" );
else
c_puts( "uh oh...\n" );
c_puts("E:");
c_puts((char*)&exists->name);
c_puts("\n");
c_puts( "Writing to file...\n" );
char* buf = "THIS IS FILE DATA!";
int w_test = _sfs_write("/TEST.txt", len(buf), (uint8_t *) buf, 0);
c_puts( "Writing to ghost file...\n" );
char* buf2 = "THIS IS FILE DATA!";
int g_test = _sfs_write("/ST.txt", len(buf2), (uint8_t *) buf2, 0);
c_puts( "Read from file...\n" );
uint8_t* buffer = _sfs_read("/TEST.txt");
//if(buffer != 0) c_puts("YES\n");
c_puts((char *) buffer);
c_puts("\n");
c_puts( "Deleting file...\n" );
int d_test = _sfs_delete("/TEST.txt");
c_printf("\n%x%x%x%x\n", c_test, w_test, g_test, d_test);
c_puts(_get_directory());
c_puts("\n");
int z_test = _sfs_create("/hello", DIRECTORY);
sfs_entry* exists2 = _sfs_exists("hello", DIRECTORY);
if(compare((char*)&exists2->name,ROOT) != 0)
c_puts( "Directory exists...\n" );
else
c_puts( "uh oh...\n" );
int x_test = _set_directory("/hello");
c_puts("Changing directory to ");
c_puts(_get_directory());
c_puts("\n");
int test_1 = _sfs_create("test1.t", FILE);
int test_2 = _sfs_create("/test2.t", FILE);
int test_3 = _sfs_create("/hello/test3.t", FILE);
int test_4 = _sfs_create("folder", DIRECTORY);
int test_5 = _sfs_create("/hello/folder/test5.t", FILE);
int test_6 = _sfs_create("/DNE/test6.t", FILE);
int test_7 = _sfs_delete("/hello");
c_printf("\n%x%x%x%x%x%x%x%x%x\n", z_test, x_test, test_1, test_2, test_3, test_4, test_5, test_6, test_7);
c_puts("\nStopping on getchar()...\n");
c_getchar();
}
}