From 0707d4d84f102ad64efd8666c597b429df8f0466 Mon Sep 17 00:00:00 2001
From: Pierre Wilke <pierre.wilke@centralesupelec.fr>
Date: Sun, 17 May 2020 21:11:41 +0200
Subject: [PATCH] MAJ link.ld pour programmes utilisateurs + fix console

---
 Makefile          |   3 +-
 kernel/console.c  |  24 ++++----
 user/link.ld      |  34 +++++++++++
 user/stack-exec.c | 152 +++++++++++++++++++++++-----------------------
 4 files changed, 123 insertions(+), 90 deletions(-)
 create mode 100644 user/link.ld

diff --git a/Makefile b/Makefile
index 3929fa7..e308597 100644
--- a/Makefile
+++ b/Makefile
@@ -91,7 +91,8 @@ tags: $(OBJS) _init
 ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o
 
 _%: %.o $(ULIB)
-	$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
+	# $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
+	$(LD) $(LDFLAGS) -Tuser/link.ld -e main -o $@ $^
 	$(OBJDUMP) -S $@ > $*.asm
 	$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
 
diff --git a/kernel/console.c b/kernel/console.c
index 567ed02..d19548e 100644
--- a/kernel/console.c
+++ b/kernel/console.c
@@ -76,15 +76,17 @@ consolewrite(struct file *f, int user_src, uint64 src, int n)
     sleep(cons, &console_number_lock);
   }
   release(&console_number_lock);
-  acquire(&cons->lock);
+  char* buf = bd_malloc(n);
   for(i = 0; i < n; i++){
-    char c;
-    if(either_copyin(&c, user_src, src+i, 1) == -1)
+    if(either_copyin(&buf[i], user_src, src+i, 1) == -1)
       break;
-    consputc(c);
+  }
+  acquire(&cons->lock);
+  for(int j = 0; j < i; j++){
+    consputc(buf[j]);
   }
   release(&cons->lock);
-
+  bd_free(buf);
   return n;
 }
 
@@ -99,7 +101,6 @@ consoleread(struct file *f, int user_dst, uint64 dst, int n)
 {
   uint target;
   int c;
-  char cbuf;
 
   target = n;
   struct cons_t* cons = &consoles[f->minor-1];
@@ -108,6 +109,8 @@ consoleread(struct file *f, int user_dst, uint64 dst, int n)
     sleep(cons, &console_number_lock);
   }
   release(&console_number_lock);
+  int len = 0;
+  char* buf = bd_malloc(n);
   acquire(&cons->lock);
   while(n > 0){
     // wait until interrupt handler has put some
@@ -132,11 +135,7 @@ consoleread(struct file *f, int user_dst, uint64 dst, int n)
     }
 
     // copy the input byte to the user-space buffer.
-    cbuf = c;
-    if(either_copyout(user_dst, dst, &cbuf, 1) == -1)
-      break;
-
-    dst++;
+    buf[len++] = c;
     --n;
 
     if(c == '\n'){
@@ -146,7 +145,8 @@ consoleread(struct file *f, int user_dst, uint64 dst, int n)
     }
   }
   release(&cons->lock);
-
+  either_copyout(user_dst, dst, buf, len);
+  bd_free(buf);
   return target - n;
 }
 
diff --git a/user/link.ld b/user/link.ld
new file mode 100644
index 0000000..684437d
--- /dev/null
+++ b/user/link.ld
@@ -0,0 +1,34 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY( _entry )
+
+PHDRS
+{
+headers PT_PHDR PHDRS ;
+text PT_LOAD FILEHDR PHDRS ;
+data PT_LOAD ;
+rodata PT_LOAD ;
+bss PT_LOAD ;
+sbss PT_LOAD ;
+}
+
+SECTIONS
+{
+. = SIZEOF_HEADERS;
+. = ALIGN(0x1000);
+.text :
+{ *(.text) } :text
+
+. = ALIGN(0x1000);
+.rodata : { *(.rodata) *(.rodata*) } :rodata
+
+. = ALIGN(0x1000);
+.data : { *(.data) } :data
+
+. = ALIGN(0x1000);
+.bss : { *(.bss) *(.sbss*) } :bss
+
+. = ALIGN(0x1000);
+.sbss : { *(.sbss*) } :sbss
+
+}
+
diff --git a/user/stack-exec.c b/user/stack-exec.c
index 358bee2..ce8305a 100644
--- a/user/stack-exec.c
+++ b/user/stack-exec.c
@@ -2,6 +2,53 @@
 #include "kernel/memlayout.h"
 #include "user/user.h"
 
+/*
+  # test.S
+  # riscv64-unknown-elf-as -march=rv64gc -fpic test.S
+  # riscv64-unknown-elf-objdump -d /tmp/a.out
+
+  # write(1, s, sizeof(s))
+
+  # fd = 1
+  li a0, 1
+  # syscall write -> a7 = 16
+  li a7, 16
+
+  # looking for the address of the string to print, after ret (0x82, 0x80)
+
+  auipc a1, 0
+  .loop:
+  lbu t0, 0(a1)
+  addi a1, a1, 1
+  li t1, 0x80
+  beq t0, t1, .endloop
+  j .loop
+  .endloop:
+
+  # computing the length of the string, look for 0 byte
+  mv a2, a1
+  .loop2:
+  lbu t0, 0(a2)
+  addi a2, a2, 1
+  beq t0, zero, .endloop2
+  j .loop2
+  .endloop2:
+  sub a2, a2, a1
+
+  ecall
+
+  ret
+
+  .mystring:
+  auipc a1, 4
+  ret
+  "Hello"
+  .mystringend:
+  auipc a2, -4
+  ret
+
+*/
+
 
 char code[] = {
   // li a0, 1
@@ -43,87 +90,38 @@ char code[] = {
   'H', 'e', 'l', 'l', 'o', '!', 0x0a, 0
 };
 
-
-int
-main(int argc, char *argv[])
-{
-
-  /*
-    # test.S
-    # riscv64-unknown-elf-as -march=rv64gc -fpic test.S
-    # riscv64-unknown-elf-objdump -d /tmp/a.out
-
-    # write(1, s, sizeof(s))
-
-    # fd = 1
-    li a0, 1
-    # syscall write -> a7 = 16
-    li a7, 16
-
-    # looking for the address of the string to print, after ret (0x82, 0x80)
-
-    auipc a1, 0
-    .loop:
-    lbu t0, 0(a1)
-    addi a1, a1, 1
-    li t1, 0x80
-    beq t0, t1, .endloop
-    j .loop
-    .endloop:
-
-    # computing the length of the string, look for 0 byte
-    mv a2, a1
-    .loop2:
-    lbu t0, 0(a2)
-    addi a2, a2, 1
-    beq t0, zero, .endloop2
-    j .loop2
-    .endloop2:
-    sub a2, a2, a1
-
-    ecall
-
-    ret
-
-    .mystring:
-    auipc a1, 4
-    ret
-    "Hello"
-    .mystringend:
-    auipc a2, -4
-    ret
-
-   */
-
-  char code_stack[100];
-  for(int i = 0; i < sizeof(code); i++){
-    code_stack[i] = code[i];
-  }
-
+void do_fork(void (*fn)(void)){
   int pid = fork();
   if(pid < 0){
     printf("fork failed\n"); exit(1);
+  } else if (pid == 0){
+    fn();
+  } else {
+    wait(0);
   }
-  if(pid == 0){
-    ((void(*)(void))(code_stack))();
-    printf("I successfully ran the stack.\n");
-    exit(0);
-  }
-  else {
-    // in .rodata
-    pid = fork();
-    if(pid < 0){
-      printf("fork failed\n"); exit(1);
-    }
-    if(pid == 0){
-      ((void(*)(void))(code))();
-      printf("I successfully ran the rodata.\n");
-      exit(0);
-    }
-    else {
-      wait(0);
-      wait(0);
-    }
+}
+
+void test_code1(){
+  ((void(*)(void))(code))();
+  printf("code1: cette ligne devrait-elle s'afficher ?\n");
+  exit(0);
+}
+
+void test_code2(){
+  char code2[100];
+  for(int i = 0; i < sizeof(code); i++){
+    code2[i] = code[i];
   }
+
+  ((void(*)(void))(code2))();
+  printf("code2: cette ligne devrait-elle s'afficher ?\n");
+  exit(0);
+}
+
+int
+main(int argc, char *argv[])
+{
+  do_fork(test_code1);
+  do_fork(test_code2);
   exit(0);
 }
-- 
GitLab