void do_syscall(TrapFrame *tf) { switch(tf->eax) { /* The ``add_irq_handle'' system call is artificial. We use it to * let user program register its interrupt handlers. But this is * very dangerous in a real operating system. Therefore such a * system call never exists in GNU/Linux. */ case 0: cli(); add_irq_handle(tf->ebx, (void*)tf->ecx); sti(); break; case SYS_brk: sys_brk(tf); break; /* TODO: Add more system calls. */ case SYS_write: sys_write(tf); break; case SYS_open : tf->eax = fs_open((char *)tf->ebx, tf->ecx); break; case SYS_read : tf->eax = fs_read(tf->ebx, (void *)tf->ecx, tf->edx); break; case SYS_lseek : tf->eax = fs_lseek(tf->ebx, tf->ecx, tf->edx); break; case SYS_close : tf->eax = fs_close(tf->ebx); break; default: panic("Unhandled system call: id = %d", tf->eax); } }
void cmd_lseek(void) { uint8_t mode; DWORD off; // Принимаем режим и смещение mode = wrecv(); recvBin((uint8_t*)&off, 4); // Режим передачи и подтверждение sendStart(ERR_WAIT); // Размер файла if(mode==100) { if(fs_getfilesize()) return; } // Размер диска else if(mode==101) { if(fs_gettotal()) return; } // Свободное место на диске else if(mode==102) { if(fs_getfree()) return; } else { /* Устаналиваем смещение. fs_tmp сохраняется */ if(fs_lseek(off, mode)) return; } // Передаем результат send(ERR_OK_CMD); sendBin((uint8_t*)&fs_tmp, 4); lastError = 0; // На всякий случай, результат уже передан }
//unsigned long fs_loadElfLibrary(struct file *file, unsigned long tmp_stack, unsigned long stack_len, unsigned long aux_addr) { unsigned long fs_elf_load(struct file *file,unsigned long tmp_stack, unsigned long stack_len, unsigned long aux_addr) { struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; unsigned long elf_bss, bss_start, bss, len; int retval, error, i, j; struct elfhdr elf_ex; Elf64_Addr p_entry; unsigned long *aux_vec, aux_index, load_addr; struct task_struct *task=g_current_task; error = 0; fs_lseek(file, 0, 0); retval = fs_read(file, (unsigned char *) &elf_ex, sizeof(elf_ex)); if (retval != sizeof(elf_ex)) { error = -1; goto out; } if (ut_memcmp((unsigned char *) elf_ex.e_ident, (unsigned char *) ELFMAG, SELFMAG) != 0) { error = -2; goto out; } if (elf_ex.e_type == ET_DYN) elf_ex.e_type=ET_EXEC; /* First of all, some simple consistency checks */ //if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || if (elf_ex.e_type != ET_EXEC || !elf_check_arch(&elf_ex)) { DEBUG("error:(not executable type or mismatch in architecture %x %x %x \n",elf_ex.e_type,elf_ex.e_phnum,elf_check_arch(&elf_ex)); error = -3; goto out; } /* Now read in all of the header information */ j = sizeof(struct elf_phdr) * elf_ex.e_phnum; /* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */ elf_phdata = mm_malloc(j, 0); if (!elf_phdata) { error = -4; goto out; } eppnt = elf_phdata; fs_lseek(file, (unsigned long) elf_ex.e_phoff, 0); retval = fs_read(file, (unsigned char *) eppnt, j); if (retval != j) { error = -5; goto out; } DEBUG("START address : %x offset :%x \n",ELF_PAGESTART(eppnt->p_vaddr),eppnt->p_offset); for (j = 0, i = 0; i < elf_ex.e_phnum; i++){ if ((eppnt + i)->p_type == PT_LOAD) j++; } if (j == 0) { error = -6; goto out; } load_addr = ELF_PAGESTART(eppnt->p_vaddr); p_entry = elf_ex.e_entry; task->mm->start_code = 0; task->mm->end_code =0; for (i = 0; i < elf_ex.e_phnum; i++, eppnt++) /* mmap all loadable program headers */ { if (eppnt->p_type != PT_LOAD) continue; //ut_log("%d: LOAD section: vaddr:%x filesz:%x offset:%x flags:%x \n",i,ELF_PAGESTART(eppnt->p_vaddr),eppnt->p_filesz,eppnt->p_offset,eppnt->p_flags); /* Now use mmap to map the library into memory. */ error = 1; if (eppnt->p_filesz > 0) { unsigned long addr; unsigned long start_addr = ELF_PAGESTART(eppnt->p_vaddr); unsigned long end_addr= eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); addr = vm_mmap(file, start_addr, end_addr, eppnt->p_flags, 0, (eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr)),"text"); if (addr == 0) error = 0; if (task->mm->start_code ==0 || task->mm->start_code > start_addr ) task->mm->start_code = start_addr; if (task->mm->end_code < end_addr ) task->mm->end_code = end_addr; } //if (error != ELF_PAGESTART(eppnt->p_vaddr)) if (error != 1) { error = -6; goto out; } elf_bss = eppnt->p_vaddr + eppnt->p_filesz; // padzero(elf_bss); /* TODO : bss start address in not at the PAGE_ALIGN or ELF_MIN_ALIGN , need to club this partial page with the data */ // len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss_start = eppnt->p_filesz + eppnt->p_vaddr; bss = eppnt->p_memsz + eppnt->p_vaddr; //ut_log(" bss start :%x end:%x memsz:%x elf_bss:%x \n",bss_start, bss,eppnt->p_memsz,elf_bss); if (bss > bss_start) { vm_setupBrk(bss_start, bss - bss_start); } error = 0; } out: if (elf_phdata) { mm_free(elf_phdata); } if (error != 0) { ut_log(" ERROR in elf loader filename :%s :%d\n",file->filename,-error); } else { task->mm->stack_bottom = USERSTACK_ADDR+USERSTACK_LEN; elf_initialize_userspace_stack(elf_ex,aux_addr,tmp_stack, stack_len,load_addr); vm_mmap(0, USER_SYSCALL_PAGE, 0x1000, PROT_READ | PROT_EXEC |PROT_WRITE, MAP_ANONYMOUS, 0,"fst_syscal"); //ut_memset((unsigned char *)SYSCALL_PAGE,(unsigned char )0xcc,0x1000); ut_memcpy((unsigned char *)USER_SYSCALL_PAGE,(unsigned char *)&__vsyscall_page,0x1000); if (g_conf_syscall_debug==1){ //pagetable_walk(4,g_current_task->mm->pgd,1,0); } } DEBUG(" Program start address(autod) : %x \n",elf_ex.e_entry); if (error == 0) return p_entry; else return 0; }
unsigned long fs_elf_check_prepare(struct file *file,unsigned char **argv, unsigned char **env,unsigned long *t_argc, unsigned long *t_argv,unsigned long *stack_len, unsigned long *aux_addr,unsigned char **elf_interpreter, unsigned long *tmp_stackp) { struct elf_phdr *elf_phdata=0; struct elf_phdr *eppnt; int retval, error, i, j; struct elfhdr elf_ex; Elf64_Addr p_entry; unsigned long tmp_stack_top=0; error = 0; fs_lseek(file, 0, 0); retval = fs_read(file, (unsigned char *) &elf_ex, sizeof(elf_ex)); if (retval != sizeof(elf_ex)) { error = -1; return 0; } if (ut_memcmp((unsigned char *) elf_ex.e_ident, (unsigned char *) ELFMAG, SELFMAG) != 0) { error = -2; return 0; } if (elf_ex.e_type == ET_DYN) elf_ex.e_type=ET_EXEC; if (elf_ex.e_type != ET_EXEC || !elf_check_arch(&elf_ex)) { DEBUG("error:(not executable type or mismatch in architecture %x %x %x \n",elf_ex.e_type,elf_ex.e_phnum,elf_check_arch(&elf_ex)); error = -3; return 0; } /* Now read in all of the header information */ j = sizeof(struct elf_phdr) * elf_ex.e_phnum; /* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */ elf_phdata = mm_malloc(j, 0); if (!elf_phdata) { error = -4; return 0; } eppnt = elf_phdata; fs_lseek(file, (unsigned long) elf_ex.e_phoff, 0); retval = fs_read(file, (unsigned char *) eppnt, j); if (retval != j) { goto out; } p_entry = elf_ex.e_entry; *elf_interpreter=0; for (i = 0; i < elf_ex.e_phnum; i++, eppnt++) /* mmap all loadable program headers */ { if (eppnt->p_type == PT_INTERP){ *elf_interpreter = (char *) ut_calloc(eppnt->p_filesz+1); fs_lseek(file, (unsigned long) eppnt->p_offset, 0); retval = fs_read(file, (unsigned char *) *elf_interpreter, eppnt->p_filesz); //ut_printf(" interpreter :%s: \n",*elf_interpreter); break; } } tmp_stack_top = setup_userstack(argv, env, stack_len, t_argc, t_argv, aux_addr, *elf_interpreter); *tmp_stackp=tmp_stack_top; if (tmp_stack_top == 0) { goto out; } tmp_stack_top = tmp_stack_top + (MAX_USERSPACE_STACK_TEMPLEN - *stack_len); out: if (elf_phdata) { mm_free(elf_phdata); } if (tmp_stack_top==0 && *elf_interpreter!=0){ ut_free(*elf_interpreter); } return tmp_stack_top; }
void fs_rewind(int fd) { fs_lseek(fd,0,SEEK_SET); }
static void sys_lseek (TrapFrame *tf) { tf->eax = fs_lseek (tf->ebx, tf->ecx, tf->edx); }
fpos_t __sseek(void *cookie, fpos_t offset, int whence) { FILE *fp = cookie; return (fs_lseek(fp->_file, (off_t)offset, whence)); }
void do_syscall(TrapFrame *tf) { switch(tf->eax) { /* The ``add_irq_handle'' system call is artificial. We use it to * let user program register its interrupt handlers. But this is * very dangerous in a real operating system. Therefore such a * system call never exists in GNU/Linux. */ case 0: cli(); // Log("tf->ebx %x",tf->ebx); add_irq_handle(tf->ebx, (void*)tf->ecx); sti(); break; case SYS_brk: { sys_brk(tf); break; } /* TODO: Add more system calls. */ case SYS_write: { /* if(tf->ebx==1) { // asm volatile (".byte 0xd6" : : "a"(SYS_write), "c"(tf->ecx), "d"(tf->edx)); int i; for(i=0; i<tf->edx; i++) { serial_printc(*(char *)(tf->ecx + i)); } tf->eax = tf->edx; break; } else break;*/ uint32_t buf = tf->ecx; uint32_t len = tf->edx; if(tf->ebx == 1 || tf->ebx == 2) { int cnt =0; while(cnt < len) { serial_printc(*((char*)buf++)); cnt++; } tf->eax = len; } else if(tf->ebx >=3) tf->eax = fs_write(tf->ebx, (void*)buf, len); else tf->eax = -1; break; } case SYS_open: { tf->eax = fs_open((char*)tf->ebx); break; } case SYS_read: { tf->eax = fs_read(tf->ebx, (void*)tf->ecx, tf->edx); break; } case SYS_lseek: { tf->eax = fs_lseek(tf->ebx, tf->ecx, tf->edx); break; } case SYS_close: { tf->eax = fs_close(tf->ebx); break; } default: panic("Unhandled system call: id = %d", tf->eax); } }