Skip to content

Commit 62c0b12

Browse files
committed
User program to receive argc, argv
1 parent e3f55f4 commit 62c0b12

File tree

16 files changed

+209
-80
lines changed

16 files changed

+209
-80
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ binaries: $(bt_stage1) $(bt_stage2) $(kernel_core) $(rm_static)
102102
SECTOR_COUNT_BT_STAGE1 = 1
103103
SECTOR_COUNT_SHARED_LIBRARY = 1
104104
SECTOR_COUNT_BT_STAGE2 = 11
105-
SECTOR_COUNT_KERNEL = 48
105+
SECTOR_COUNT_KERNEL = 47
106106

107107
SECTOR_START_BT_STAGE1 = 0
108108
SECTOR_START_SHARED_LIBRARY = $(shell expr $(SECTOR_START_BT_STAGE1) + $(SECTOR_COUNT_BT_STAGE1) )

include/fuzzy/kernel/interrupts/timer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ void interrupt_pit_enable();
44

55
void interrupt_register_0x20_irq0_pit();
66

7-
int create_infant_process_irq0_stack(int ds_ss_es_fs);
7+
// return new user_sp
8+
int create_infant_process_irq0_stack(int user_datasegment, int user_sp);

include/fuzzy/kernel/process/process.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#pragma once
2+
#include <process.h>
23
#include<stddef.h>
34

45
#define MAX_PROCESS 10
5-
// GDT_TABLE_SIZE = MAX_PROCESS*2+3
6-
#define GDT_TABLE_SIZE 23
6+
#define GDT_TABLE_SIZE MAX_PROCESS*2+3
7+
8+
typedef char ARGV[PROCESS_MAX_ARGC][PROCESS_MAX_ARG_LEN];
79

810
enum process_state{
911
STATE_COLD = 0, // STATE_COLD must be 0
@@ -36,7 +38,7 @@ int get_idt_ds_entry(int process_id);
3638
int get_idt_reverse_pid_lookup(int cs);
3739

3840
// process create or kill
39-
int process_create(char *argv[]);
41+
int process_create(int argc, char *argv[]);
4042
void process_kill(int user_ds, int status);
4143

4244
// scheduler
@@ -45,7 +47,6 @@ void process_kill(int user_ds, int status);
4547
// cs:eip with ss:esp (updated or not).
4648
void process_scheduler(int *_e_ip, int *_e_cs, int *_e_sp, int *_e_ss);
4749

48-
4950
// user space <-> kernel space data transfer helper
5051
extern void syscall_strncpy_user_to_kernel(int user_ds, char *src_es_address, char *dest_ds_address, size_t size);
5152
extern void syscall_strncpy_kernel_to_user(int user_ds, char *dest_address, char *src_address, size_t size);

include/fuzzy/memmgr/layout.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// START_ENSURE_SAME_layout_asm
44
#define MEMORY_APP_SIZE 0x20000
5+
#define STACKINIT_APP (MEMORY_APP_SIZE-4)
56
// END_ENSURE_SAME_layout_asm
67

78
// Most of the memory layout relies on the fact the kernel is first app

memory_layout.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
|--------- |-------- |-------- |-------------------------------------------- |
55
| 0x00000 | fill | 31KB | RESERVED |
66
| 0x7C00 | 0x7DFF | 512B | BOOTLOADER STAGE 1 |
7-
| 0x7E00 | 0x7EFF | 256B | SHARED STATIC CODE for real_mode library |
8-
| 0x7F00 | 0x7FFF | 256B | SHARED STATIC MEMORY for real_mode library |
7+
| 0x7E00 | 0x7FFF | 512B | SHARED STATIC CODE for real_mode library |
98
| 0x8000 | 0xBFFF | - | BOOT LOADER STAGE 2 + own stack |
10-
| 0xC000 | 0x1FFFF | - | KERNEL |
11-
| 0x20000 | 0x2FFFF | - | Application 0 |
12-
| 0x30000 | 0x3FFFF | - | Application 1 |
9+
| 0x10000 | 0x2FFFF | - | KERNEL |
10+
| 0x30000 | 0x4FFFF | - | Application 0 |
11+
| 0x50000 | 0x6FFFF | - | Application 1 |
1312
...
1413
| - | 0xFFFFF | - | 20-bit memory limit |

src/kernel/interrupts/exceptions.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,17 @@ extern void _interrupt_handler_0x1D_exception();
3333
extern void _interrupt_handler_0x1E_exception();
3434
extern void _interrupt_handler_0x1F_exception();
3535

36-
void interrupt_handler_0x00_0x1F_exception(int id,int ip, int cs) {
36+
void interrupt_handler_0x00_0x1F_exception(int id, int ip, int cs) {
37+
switch (id) {
38+
case 0x0D:
39+
PANIC(id, "[hw_exception] general_protection_fault");
40+
}
3741
PANIC(id, "[hw_exception] triggered: no handler");
3842
}
3943

44+
void interrupt_handler_0x0D_general_protection_fault(int id, int ip, int cs) {
45+
}
46+
4047
void interrupt_register_0x00_0x1F_exceptions() {
4148
print_log("[interrupts] register 0x00-0x1F exceptions");
4249
populate_idt_entry_32bit(0x00, (unsigned int)_interrupt_handler_0x00_exception, 0, 0);

src/kernel/interrupts/timer.asm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ global create_infant_process_irq0_stack
9595
push edi
9696

9797
push ds
98-
mov ecx, [ebp+0x08] ; arg0
98+
mov ecx, [ebp+0x08] ; arg0: ss
99+
mov eax, [ebp+0x0C] ; arg1; user stack esp
99100

100101
mov ds, ecx
102+
sub eax, 4
101103

102-
; user initial stack
103-
mov eax, STACKINIT_APP
104104
; kernel offset
105105
xor ecx, ecx
106106
mov [eax-0], ecx ; user: eflag

src/kernel/interrupts/timer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <fuzzy/kernel/interrupts/interrupts.h>
33
#include <fuzzy/kernel/interrupts/timer.h>
44
#include <fuzzy/kernel/process/process.h>
5+
#include <fuzzy/memmgr/stackguard/stackguard.h>
56

67
#include <lib/utils/logging.h>
78

@@ -39,6 +40,7 @@ void irq0_pit_handler(int *e_ip, int *e_cs, int *e_sp, int *e_ss) {
3940
timer_add_ticks(ticks_jumped);
4041
int newtime_ms = get_time_since_boot_ms();
4142
process_scheduler(e_ip, e_cs, e_sp, e_ss);
43+
VERIFY_STACKGUARD();
4244
}
4345

4446
void interrupt_pit_enable() {

src/kernel/process/allocation.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <fuzzy/memmgr/layout.h>
44
#include <fuzzy/kernel/panic.h>
55

6+
#include <process.h>
7+
68
/* Process ID
79
* pid 0 : kernel core
810
* pid 1 : user app 1
@@ -88,7 +90,38 @@ void process_scheduler_init() {
8890
load_gdt_table(&gdtr);
8991
}
9092

91-
int process_create(char *argv[]) {
93+
// return new user_sp
94+
static int create_infant_process_argv_stack(int user_ds, int user_sp,
95+
int argc, char *argv[]) {
96+
// assumes pointer are 4 bytes and are same as int
97+
98+
user_sp = user_sp - sizeof(ARGV);
99+
char *__us_argv_data = user_sp;
100+
syscall_strncpy_kernel_to_user(user_ds, __us_argv_data, argv, sizeof(ARGV));
101+
102+
// assumes argc < PROCESS_MAX_ARGC
103+
char *ks_to_us_argv[PROCESS_MAX_ARGC] = {NULL};
104+
for (int i = 0; i < argc; i++) {
105+
ks_to_us_argv[i] = __us_argv_data + i*PROCESS_MAX_ARG_LEN;
106+
}
107+
108+
109+
user_sp = user_sp - sizeof(ks_to_us_argv);
110+
char *__us_argv_list = user_sp;
111+
syscall_strncpy_kernel_to_user(user_ds, __us_argv_list, ks_to_us_argv, sizeof(ks_to_us_argv));
112+
113+
user_sp = user_sp - sizeof(argc);
114+
char *__us_argv = user_sp;
115+
syscall_strncpy_kernel_to_user(user_ds, __us_argv, &__us_argv_list, sizeof(__us_argv_list));
116+
117+
user_sp = user_sp - sizeof(argc);
118+
char *__us_argc = user_sp;
119+
syscall_strncpy_kernel_to_user(user_ds, __us_argc, &argc, sizeof(argc));
120+
121+
return user_sp;
122+
}
123+
124+
int process_create(int argc, char *argv[]) {
92125
// returnd pid >= 0 if success
93126
int pid = -1;
94127
for (int i = 0; i < MAX_PROCESS; ++i) {
@@ -129,8 +162,8 @@ int process_create(char *argv[]) {
129162
process->ip = 0;
130163
// initially ds == ss
131164
process->ss = get_gdt_number_from_entry_id(idt_ds_entry);
132-
process->sp = create_infant_process_irq0_stack(process->ss);
133-
// TODO: Push argv in process stack
165+
process->sp = create_infant_process_argv_stack(process->ss, STACKINIT_APP, argc, argv);
166+
process->sp = create_infant_process_irq0_stack(process->ss, process->sp);
134167
return pid;
135168
}
136169

src/kernel/process/process.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
#include <fuzzy/fs/ffs.h>
22
#include <fuzzy/kernel/process/process.h>
33
#include <fuzzy/kernel/interrupts/timer.h>
4+
#include <fuzzy/memmgr/stackguard/stackguard.h>
45

56
#include <process.h>
67

78
#include <lib/utils/logging.h>
89
#include <lib/utils/output.h>
910

10-
int process_spawn(int lba_index, int sector_count, char *argv[]) {
11+
int process_spawn(int lba_index, int sector_count, int argc, char *argv[]) {
1112
print_info("[process_spawn] create");
12-
int pid = process_create(argv);
13+
int pid = process_create(argc, argv);
1314
if(pid<0) {
1415
print_log("Failed to reserved a new pid");
1516
return -1;
1617
}
1718
print_info("[process_spawn] loading, pid: %d", pid);
19+
1820
int err = process_load_from_disk(pid, lba_index, sector_count);
1921
if (err) {
2022
print_log("Failed to load app in memory, Error: ", err);
@@ -23,6 +25,7 @@ int process_spawn(int lba_index, int sector_count, char *argv[]) {
2325
print_info("[process_spawn] ready, pid: %d", pid);
2426
struct Process *process = get_process(pid);
2527
process->state = STATE_READY;
28+
VERIFY_STACKGUARD();
2629
return 0;
2730
}
2831

@@ -37,33 +40,30 @@ int syscall_1_process_exit(int user_ds, int status) {
3740
}
3841

3942
int syscall_1_process_spawn_lba_sc(int lba_start, int sector_count) {
40-
char *fake_argv[]={"fake_spawn", NULL};
41-
return process_spawn(lba_start, sector_count, fake_argv);
43+
int fake_argc = 1;
44+
ARGV fake_argv={"fake_spawn", NULL};
45+
return process_spawn(lba_start, sector_count, fake_argc, fake_argv);
4246
}
4347

4448
int syscall_1_process_exec_lba_sc(int lba_start, int sector_count) {
4549
return process_exec(lba_start, sector_count);
4650
}
4751

4852
int syscall_1_process_spawn_fname(int user_ds, char *_us_filename, char *_us_argv[]) {
49-
char filename[FS_FFS_FILENAME_LIMIT];
50-
char argv_data[PROCESS_MAX_ARGC][PROCESS_MAX_ARG_LEN];
53+
// User must send all PROCESS_MAX_ARGC arguments.
5154
char *argv_with_uspointer[PROCESS_MAX_ARGC];
52-
char *argv[PROCESS_MAX_ARGC]; // kernel mode
55+
char filename[FS_FFS_FILENAME_LIMIT];
56+
int argc = 0; // kernel mode
57+
ARGV argv={0}; // kernel mode
5358
syscall_strncpy_user_to_kernel(user_ds, _us_filename, filename, sizeof(filename));
5459
syscall_strncpy_user_to_kernel(user_ds, _us_argv, argv_with_uspointer, sizeof(argv_with_uspointer));
5560
// if src string is NULL, then dst string also should be null.
56-
for (int i = 0; i < PROCESS_MAX_ARGC; i++) {
61+
for (int i = 0; i < PROCESS_MAX_ARGC - 1; i++) {
5762
if(argv_with_uspointer[i]==NULL) {
58-
argv[i]=NULL;
5963
break;
6064
}
61-
syscall_strncpy_user_to_kernel(user_ds, argv_with_uspointer[i], argv_data[i], sizeof(argv_data[i]));
62-
argv[i] = argv_data[i];
63-
}
64-
65-
for (int i = 0; argv[i]; i++) {
66-
printf("[kernel] arg%d: %s\n", i, argv[i]);
65+
syscall_strncpy_user_to_kernel(user_ds, argv_with_uspointer[i], argv[i], sizeof(argv[i]));
66+
argc++;
6767
}
6868

6969
union FFSFileEntry entry;
@@ -74,7 +74,7 @@ int syscall_1_process_spawn_fname(int user_ds, char *_us_filename, char *_us_arg
7474
int lba_start = resolve_abs_lba(FFS_UNIQUE_PARITION_ID, entry.content.start_block_id);
7575
int sector_count = (entry.content.filesize + FS_BLOCK_SIZE -1)/FS_BLOCK_SIZE;
7676

77-
return process_spawn(lba_start, sector_count, argv);
77+
return process_spawn(lba_start, sector_count, argc, argv);
7878
}
7979

8080
int syscall_1_process(int operation, int a0, int a1, int a2, int a3, int user_ds) {

0 commit comments

Comments
 (0)