Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Set default behavior to automatically normalize line endings
* text=auto

# Force LF for source files (Unix-style, common for C projects)
*.c text eol=lf
*.h text eol=lf
*.ld text eol=lf
*.sh text eol=lf

# Binary files
*.bin binary
*.elf binary
*.tar binary
*.png binary
*.ico binary
*.svg binary

25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,27 @@ The book only covers the basics of an operating system. You can do more with the
| --- | --- |
| [Shutdown command](https://github.com/nuta/operating-system-in-1000-lines/pull/59/files) | [@calvera](https://github.com/calvera) |

Let me know if you have implemented something interesting!


I added

ls
<img width="245" height="77" alt="image" src="https://github.com/user-attachments/assets/6a50e883-1f3f-4b1a-88b5-46b9425ccdfe" />


addf <filename>
<img width="374" height="154" alt="image" src="https://github.com/user-attachments/assets/3d8d4639-7b52-42a5-9559-c6f9a25c8c5d" />

readf <filename>
<img width="183" height="36" alt="image" src="https://github.com/user-attachments/assets/4e41c32f-9ec9-45f3-97eb-897c8e7da24c" />

writef <filename>

<img width="625" height="96" alt="image" src="https://github.com/user-attachments/assets/6e39a042-eb15-4c7a-b382-bda5d4d7a884" />






commands and syscalls needed
13 changes: 13 additions & 0 deletions common.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ char *strcpy(char *dst, const char *src) {
*d = '\0';
return dst;
}
int strncmp(const char *s1, const char *s2, int n) {
for (int i = 0; i < n; i++) {
unsigned char c1 = (unsigned char)s1[i];
unsigned char c2 = (unsigned char)s2[i];

if (c1 != c2)
return c1 - c2;
if (c1 == '\0') // Eğer birisi '\0' ise karşılaştırmayı bitir
return 0;
}
return 0;
}


int strcmp(const char *s1, const char *s2) {
while (*s1 && *s2) {
Expand Down
7 changes: 6 additions & 1 deletion common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ typedef uint32_t vaddr_t;
#define SYS_EXIT 3
#define SYS_READFILE 4
#define SYS_WRITEFILE 5

#define SYS_ADDFILE 6
#define SYS_READF 7
#define SYS_ADDF 8
#define SYS_WRITEF 9
#define SYS_LS 10
void *memset(void *buf, char c, size_t n);
void *memcpy(void *dst, const void *src, size_t n);
char *strcpy(char *dst, const char *src);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, int n);
void printf(const char *fmt, ...);
89 changes: 88 additions & 1 deletion kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,100 @@ void handle_syscall(struct trap_frame *f) {
yield();
}
break;
case SYS_READF: {
const char *filename = (const char *) f->a0;
struct file *file = fs_lookup(filename);
if (!file) {
f->a0 = -1; // dosya yok
break;
}

// Dosya içeriğini console’a yaz
for (int i = 0; i < file->size; i++)
putchar(file->data[i]);

f->a0 = file->size;
break;

}
case SYS_LS: {
printf("Files:\n");
for (int i = 0; i < FILES_MAX; i++) {
if (files[i].in_use) {
printf(" %s (size: %d)\n", files[i].name, files[i].size);
}
}
f->a0 = 0;
break;
}

case SYS_ADDF: {
const char *filename = (const char *) f->a0;
struct file *file = NULL;
for (int i = 0; i < FILES_MAX; i++) {
if (!files[i].in_use) {
file = &files[i];
break;
}
}
if (!file) { f->a0 = -1; break; }
file->in_use = true;
strcpy(file->name, filename);
file->size = 0;
fs_flush();
f->a0 = 0;
break;
}

case SYS_WRITEF: {
const char *filename = (const char *) f->a0;
struct file *file = fs_lookup(filename);
if (!file) { f->a0 = -1; break; }

char *buf = (char *) f->a1;
int len = f->a2;
if (len > (int) sizeof(file->data))
len = sizeof(file->data);
memcpy(file->data, buf, len);
file->size = len;
fs_flush();
f->a0 = len;
break;
}


case SYS_ADDFILE: {
const char *filename = (const char *) f->a0;

// find free slot
struct file *file = NULL;
for (int i = 0; i < FILES_MAX; i++) {
if (!files[i].in_use) {
file = &files[i];
break;
}
}

if (!file) {
f->a0 = -1; // fail
break;
}

file->in_use = true;
strcpy(file->name, filename);
file->size = 0; // boş dosya
fs_flush(); // diske yaz
f->a0 = 0; // success
break;
}

case SYS_EXIT:
printf("process %d exited\n", current_proc->pid);
current_proc->state = PROC_EXITED;
yield();
PANIC("unreachable");
case SYS_READFILE:
case SYS_WRITEFILE: {
case SYS_WRITEFILE: {
const char *filename = (const char *) f->a0;
char *buf = (char *) f->a1;
int len = f->a2;
Expand Down
2 changes: 1 addition & 1 deletion kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#define PAGE_X (1 << 3)
#define PAGE_U (1 << 4)
#define USER_BASE 0x1000000
#define FILES_MAX 2
#define FILES_MAX 3
#define DISK_MAX_SIZE align_up(sizeof(struct file) * FILES_MAX, SECTOR_SIZE)
#define SECTOR_SIZE 512
#define VIRTQ_ENTRY_NUM 16
Expand Down
25 changes: 25 additions & 0 deletions run_on_ubuntu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
set -xue

QEMU=qemu-system-riscv32
CC=/usr/bin/clang
OBJCOPY=/usr/bin/llvm-objcopy-18

CFLAGS="-std=c11 -O2 -g3 -Wall -Wextra --target=riscv32-unknown-elf -fuse-ld=lld -fno-stack-protector -ffreestanding -nostdlib"

# Build the shell.
$CC $CFLAGS -Wl,-Tuser.ld -Wl,-Map=shell.map -o shell.elf shell.c user.c common.c
$OBJCOPY --set-section-flags .bss=alloc,contents -O binary shell.elf shell.bin
$OBJCOPY -Ibinary -Oelf32-littleriscv shell.bin shell.bin.o

# Build the kernel.
$CC $CFLAGS -Wl,-Tkernel.ld -Wl,-Map=kernel.map -o kernel.elf \
kernel.c common.c shell.bin.o

(cd disk && tar cf ../disk.tar --format=ustar *.txt)

$QEMU -machine virt -bios default -nographic -serial mon:stdio --no-reboot \
-d unimp,guest_errors,int,cpu_reset -D qemu.log \
-drive id=drive0,file=disk.tar,format=raw,if=none \
-device virtio-blk-device,drive=drive0,bus=virtio-mmio-bus.0 \
-kernel kernel.elf
53 changes: 41 additions & 12 deletions shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

void main(void) {
while (1) {
prompt:
prompt:
printf("> ");
char cmdline[128];
for (int i = 0;; i++) {
Expand All @@ -11,7 +11,7 @@ void main(void) {
if (i == sizeof(cmdline) - 1) {
printf("command line too long\n");
goto prompt;
} else if (ch == '\r') {
} else if (ch == '\r' || ch == '\n') { // ENTER tuşunu hem \r hem \n olarak kontrol et
printf("\n");
cmdline[i] = '\0';
break;
Expand All @@ -20,19 +20,48 @@ void main(void) {
}
}

if (strcmp(cmdline, "hello") == 0)
if (strcmp(cmdline, "hello") == 0) {
printf("Hello world from shell!\n");
else if (strcmp(cmdline, "exit") == 0)
} else if (strcmp(cmdline, "exit") == 0) {
exit();
else if (strcmp(cmdline, "readfile") == 0) {
char buf[128];
int len = readfile("hello.txt", buf, sizeof(buf));
buf[len] = '\0';
printf("%s\n", buf);
}
else if (strcmp(cmdline, "writefile") == 0)
writefile("hello.txt", "Hello from shell!\n", 19);
else
else if (strcmp(cmdline, "ls") == 0) {
ls();
}
else if (strncmp(cmdline, "readf ", 6) == 0) {
char *filename = cmdline + 6;
int ret = readf(filename);
if (ret < 0)
printf("file not found: %s\n", filename);
} else if (strncmp(cmdline, "addf ", 5) == 0) {
char *filename = cmdline + 5;
int ret = addf(filename);
if (ret == 0)
printf("file \"%s\" added successfully!\n", filename);
else
printf("failed to add file \"%s\"\n", filename);
} else if (strncmp(cmdline, "writef ", 7) == 0) {
char *filename = cmdline + 7;
char buf[128];
printf("Enter content (end with ENTER): ");
int i = 0;
for (;;) {
char ch = getchar();
if (ch == '\r' || ch == '\n' || i == sizeof(buf) - 1) {
buf[i] = '\0';
break;
}
putchar(ch);
buf[i++] = ch;
}
int ret = writef(filename, buf, i);
if (ret >= 0)
printf("written %d bytes to %s\n", ret, filename);
else
printf("failed to write to %s\n", filename);
} else {
printf("unknown command: %s\n", cmdline);
}
}
}

21 changes: 20 additions & 1 deletion user.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ int syscall(int sysno, int arg0, int arg1, int arg2) {

return a0;
}
int ls(void) {
return syscall(SYS_LS, 0, 0, 0);
}

void putchar(char ch) {
syscall(SYS_PUTCHAR, ch, 0, 0);
Expand All @@ -32,11 +35,27 @@ int writefile(const char *filename, const char *buf, int len) {
return syscall(SYS_WRITEFILE, (int) filename, (int) buf, len);
}

int addfile(const char *filename) {
return syscall(SYS_ADDFILE, (int) filename, 0, 0);
}
int readf(const char *filename) {
return syscall(SYS_READF, (int)filename, 0, 0);
}

int addf(const char *filename) {
return syscall(SYS_ADDF, (int)filename, 0, 0);
}

int writef(const char *filename, const char *buf, int len) {
return syscall(SYS_WRITEF, (int)filename, (int)buf, len);
}


__attribute__((noreturn)) void exit(void) {
syscall(SYS_EXIT, 0, 0, 0);
for (;;);
}

__attribute__((section(".text.start")))
__attribute__((naked))
void start(void) {
Expand Down
6 changes: 6 additions & 0 deletions user.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ void putchar(char ch);
int getchar(void);
int readfile(const char *filename, char *buf, int len);
int writefile(const char *filename, const char *buf, int len);
int addfile(const char *filename);
int readf(const char *filename);
int addf(const char *filename);
int writef(const char *filename, const char *buf, int len);
int ls(void);

__attribute__((noreturn)) void exit(void);