Пример #1
0
PUBLIC void task_fs()
{
    printl("Task FS begins.\n");

    init_fs();

    while (1) {
        send_recv(RECEIVE, ANY, &fs_msg);

        int src = fs_msg.source;
        pcaller = &proc_table[src];

        switch (fs_msg.type) {
            case OPEN:
                fs_msg.FD = do_open();
                break;

            case CLOSE:
                fs_msg.RETVAL = do_close();
                break;

            case READ:
            case WRITE:
                fs_msg.CNT = do_rdwt();
                break;

            case UNLINK:
                fs_msg.RETVAL = do_unlink();
                break;

            case RESUME_PROC:
                src = fs_msg.PROC_NR; // 恢复最初请求的进程,如 TestB
                break;

            case FORK:
                fs_msg.RETVAL = fs_fork();
                break;

            case EXIT:
                fs_msg.RETVAL = fs_exit();
                break;

            case STAT:
                fs_msg.RETVAL = do_stat();
                break;

            default:
                dump_msg("FS::unknown message:", &fs_msg);
                assert(0);
                break;
        }

        /* 如果发送者要求挂起,则不回送消息 */
        if (fs_msg.type != SUSPEND_PROC) {
            fs_msg.type = SYSCALL_RET;
            send_recv(SEND, src, &fs_msg);
        }
    }

    spin("FS");
}
Пример #2
0
/**
 * <Ring 1> Make a available Orange'S FS in the disk. It will
 *          - Write a super block to sector 1.
 *          - Create three special files: dev_tty0, dev_tty1, dev_tty2
 *          - Create the inode map
 *          - Create the sector map
 *          - Create the inodes of the files
 *          - Create `/', the root directory
 *****************************************************************************/
PRIVATE void mkfs()
{
	MESSAGE driver_msg;
	int i, j;

	int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */

	/* get the geometry of ROOTDEV */
	struct part_info geo;
	driver_msg.type		= DEV_IOCTL;
	driver_msg.DEVICE	= MINOR(ROOT_DEV);
	driver_msg.REQUEST	= DIOCTL_GET_GEO;
	driver_msg.BUF		= &geo;
	driver_msg.PROC_NR	= TASK_FS;
	assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
	send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

	printl("dev size: 0x%x sectors\n", geo.size);

	/************************/
	/*      super block     */
	/************************/
	struct super_block sb;
	sb.magic	  = MAGIC_V1;
	sb.nr_inodes	  = bits_per_sect;
	sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
	sb.nr_sects	  = geo.size; /* partition size in sector */
	sb.nr_imap_sects  = 1;
	sb.nr_smap_sects  = sb.nr_sects / bits_per_sect + 1;
	sb.n_1st_sect	  = 1 + 1 +   /* boot sector & super block */
		sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
	sb.root_inode	  = ROOT_INODE;
	sb.inode_size	  = INODE_SIZE;
	struct inode x;
	sb.inode_isize_off= (int)&x.i_size - (int)&x;
	sb.inode_start_off= (int)&x.i_start_sect - (int)&x;
	sb.dir_ent_size	  = DIR_ENTRY_SIZE;
	struct dir_entry de;
	sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de;
	sb.dir_ent_fname_off = (int)&de.name - (int)&de;

	memset(fsbuf, 0x90, SECTOR_SIZE);
	memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);

	/* write the super block */
	WR_SECT(ROOT_DEV, 1);

	printl("devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n"
	       "        inodes:0x%x00, 1st_sector:0x%x00\n", 
	       geo.base * 2,
	       (geo.base + 1) * 2,
	       (geo.base + 1 + 1) * 2,
	       (geo.base + 1 + 1 + sb.nr_imap_sects) * 2,
	       (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
	       (geo.base + sb.n_1st_sect) * 2);

	/************************/
	/*       inode map      */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	for (i = 0; i < (NR_CONSOLES + 2); i++)
		fsbuf[0] |= 1 << i;

	assert(fsbuf[0] == 0x1F);/* 0001 1111 : 
				  *    | ||||
				  *    | |||`--- bit 0 : reserved
				  *    | ||`---- bit 1 : the first inode,
				  *    | ||              which indicates `/'
				  *    | |`----- bit 2 : /dev_tty0
				  *    | `------ bit 3 : /dev_tty1
				  *    `-------- bit 4 : /dev_tty2
				  */
	WR_SECT(ROOT_DEV, 2);

	/************************/
	/*      secter map      */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
	/*             ~~~~~~~~~~~~~~~~~~~|~   |
	 *                                |    `--- bit 0 is reserved
	 *                                `-------- for `/'
	 */
	for (i = 0; i < nr_sects / 8; i++)
		fsbuf[i] = 0xFF;

	for (j = 0; j < nr_sects % 8; j++)
		fsbuf[i] |= (1 << j);

	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

	/* zeromemory the rest sector-map */
	memset(fsbuf, 0, SECTOR_SIZE);
	for (i = 1; i < sb.nr_smap_sects; i++)
		WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

	/************************/
	/*       inodes         */
	/************************/
	/* inode of `/' */
	memset(fsbuf, 0, SECTOR_SIZE);
	struct inode * pi = (struct inode*)fsbuf;
	pi->i_mode = I_DIRECTORY;
	pi->i_size = DIR_ENTRY_SIZE * 4; /* 4 files:
					  * `.',
					  * `dev_tty0', `dev_tty1', `dev_tty2',
					  */
	pi->i_start_sect = sb.n_1st_sect;
	pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
	/* inode of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1)));
		pi->i_mode = I_CHAR_SPECIAL;
		pi->i_size = 0;
		pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
		pi->i_nr_sects = 0;
	}
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

	/************************/
	/*          `/'         */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	struct dir_entry * pde = (struct dir_entry *)fsbuf;

	pde->inode_nr = 1;
	strcpy(pde->name, ".");

	/* dir entries of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pde++;
		pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
		sprintf(pde->name, "dev_tty%d", i);
	}
	WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Пример #3
0
int
cbuf_create(spdid_t spdid, unsigned long size, int cbid)
{
	struct cbuf_comp_info *cci;
	struct cbuf_info *cbi;
	struct cbuf_meta *meta;
	struct cbuf_bin *bin;
	int ret = 0;
	unsigned int id = (unsigned int)cbid;

	printl("cbuf_create\n");
	if (unlikely(cbid < 0)) return 0;
	CBUF_TAKE();
	tracking_start(NULL, CBUF_CRT);

	cci = cbuf_comp_info_get(spdid);
	if (unlikely(!cci)) goto done;

	/* 
	 * Client wants to allocate a new cbuf, but the meta might not
	 * be mapped in.
	 */
	if (!cbid) {
		/* TODO: check if have enough free memory: ask mem manager */
		/*memory usage exceeds the target, block this thread*/
		if (size + cci->allocated_size > cci->target_size) {
			cbuf_shrink(cci, size);
			if (size + cci->allocated_size > cci->target_size) {
				cbuf_thread_block(cci, size);
				return 0;
			}
		}

 		cbi = malloc(sizeof(struct cbuf_info));

		if (unlikely(!cbi)) goto done;
		/* Allocate and map in the cbuf. Discard inconsistent cbufs */
		/* TODO: Find a better way to manage those inconsistent cbufs */
		do {
			id   = cmap_add(&cbufs, cbi);
			meta = cbuf_meta_lookup(cci, id);
		} while(meta && CBUF_INCONSISENT(meta));

		cbi->cbid        = id;
		size             = round_up_to_page(size);
		cbi->size        = size;
		cbi->owner.m     = NULL;
		cbi->owner.spdid = spdid;
		INIT_LIST(&cbi->owner, next, prev);
		INIT_LIST(cbi, next, prev);
		if (cbuf_alloc_map(spdid, &(cbi->owner.addr), 
				   (void**)&(cbi->mem), NULL, size, MAPPING_RW)) {
			goto free;
		}
	} 
	/* If the client has a cbid, then make sure we agree! */
	else {
		cbi = cmap_lookup(&cbufs, id);
		if (unlikely(!cbi)) goto done;
		if (unlikely(cbi->owner.spdid != spdid)) goto done;
	}
	meta = cbuf_meta_lookup(cci, id);

	/* We need to map in the meta for this cbid.  Tell the client. */
	if (!meta) {
		ret = (int)id * -1;
		goto done;
	}
	
	/* 
	 * Now we know we have a cbid, a backing structure for it, a
	 * component structure, and the meta mapped in for the cbuf.
	 * Update the meta with the correct addresses and flags!
	 */
	memset(meta, 0, sizeof(struct cbuf_meta));
	meta->sz            = cbi->size >> PAGE_ORDER;
	meta->cbid_tag.cbid = id;
	CBUF_FLAG_ADD(meta, CBUF_OWNER);
	CBUF_PTR_SET(meta, cbi->owner.addr);
	CBUF_REFCNT_INC(meta);

	/*
	 * When creates a new cbuf, the manager should be the only
	 * one who can access the meta
	 */
	/* TODO: malicious client may trigger this assertion, just for debug */
	assert(CBUF_REFCNT(meta) == 1);
	assert(CBUF_PTR(meta));
	cbi->owner.m = meta;

	/*
	 * Install cbi last. If not, after return a negative cbid, 
	 * collection may happen and get a dangle cbi
	 */
	bin = cbuf_comp_info_bin_get(cci, size);
	if (!bin) bin = cbuf_comp_info_bin_add(cci, size);
	if (unlikely(!bin)) goto free;
	if (bin->c) ADD_LIST(bin->c, cbi, next, prev);
	else        bin->c   = cbi;
	cci->allocated_size += size;
	ret = (int)id;
done:
	tracking_end(NULL, CBUF_CRT);
	CBUF_RELEASE();

	return ret;
free:
	cmap_del(&cbufs, id);
	free(cbi);
	goto done;
}
Пример #4
0
PUBLIC void task_fs()
{

	init_buffer();
	printl("VFS: VFS is running.\n");

	MESSAGE msg;
	struct file_system * fs;
	while (1){
		send_recv(RECEIVE, ANY, &msg);
		int src = msg.source;
		pcaller = &proc_table[src];
		int msgtype = msg.type;

		fs = file_systems;
		switch (msgtype) {
	 	case FS_REGISTER:
			register_filesystem(&msg);
			break;
		case OPEN:
			printl("Doing open, %d\n", fs->open);
			msg.FD = fs->open(&msg);
			printl("Done open, %d\n", fs->open);
			break;
		case CLOSE:
			msg.RETVAL = fs->close(&msg);
			break;
		case READ:
		case WRITE:
			msg.CNT = fs->rdwt(&msg);
			break;
		case UNLINK:
			msg.RETVAL = fs->unlink(&msg);
			break;
		case MOUNT:
			msg.RETVAL = fs->mount(&msg);
			break;
		case UMOUNT:
			msg.RETVAL = fs->umount(&msg);
			break;
		case MKDIR:
			msg.RETVAL = fs->mkdir(&msg);
			break;
		case RESUME_PROC:
			src = msg.PROC_NR;
			break;
		case FORK:
			msg.RETVAL = fs->fork(&msg);
			break;
		case EXIT:
			msg.RETVAL = fs->exit(&msg);
			break;
		case LSEEK:
			msg.OFFSET = fs->lseek(&msg);
			break;
		case STAT:
			msg.RETVAL = fs->stat(&msg);
			break;
		case CHROOT:
			msg.RETVAL = fs->chroot(&msg);
			break;
		case CHDIR:
			msg.RETVAL = fs->chdir(&msg);
			break; 
		default:
			dump_msg("VFS: Unknown message:", &msg);
			assert(0);
			break;
		}

		/* reply */
		if (msg.type != SUSPEND_PROC) {
			msg.type = SYSCALL_RET;
			send_recv(SEND, src, &msg);
		}
	}
}
Пример #5
0
program()
{
        printl(listfiles().convert(FM,"\n"));
}
Пример #6
0
static int do_open(MESSAGE *message){
    int i,fd=-1;
    const char *path;
    char dirname[MAX_FILENAME_LENGTH]={0};
    char filename[MAX_FILENAME_LENGTH]={0};
    int flags;
    int inode_index;
    struct s_file_descriptor *pfd=NULL;
    struct s_inode *pinode=NULL;
    /* struct s_inode parent_dir_inode; */
    PROCESS *process;

    path=message->arg_pointer;
    flags=message->flags;
    process=pid2process(message->source_pid);
    
    pfd=get_free_fd_from_table();
    pinode=get_free_inode_from_table();
    if(pfd==NULL || pinode==NULL){
        set_error_index(NO_FD_INODE);
        return -1;
    }
    
    //分离父目录路径和文件名
    if(!strip_path(path,dirname,filename)){
        return -1;
    }
#ifdef DEBUG_FS
    printl("dir_name=%s file_name=%s\n",dirname,filename);
#endif

    //搜索文件
    inode_index=search_file(dirname,filename,GET_FILE_TYPE(flags));
    if(inode_index<0){
        if((flags & O_CREATE)==0){
            return -1;
        }
        inode_index=create_file(dirname,filename,GET_FILE_TYPE(flags));
        if(inode_index<0){
            return -1;
        }
    }
    assert(inode_index>=0,"");
    get_inode_by_index(inode_index,pinode);
#ifdef DEBUG_FS
    printl("pinode.start_index=%d(in do_open)",pinode->i_start_sector_index);
#endif
    /*SDTIN=0,STDOUT=1,STDERROR=2*/
    for(i=3;i<FILE_COUNT;i++){
        if(process->file_descriptor[i]==NULL){
            fd=i;
            break;
        }
    }
    
    if(fd>=0){
        process->file_descriptor[fd]=pfd;
    
        pfd->fd_inode=pinode;
        pfd->fd_op_mode=GET_FILE_OP(flags);
        pfd->fd_position=0;

        pinode->i_inode_index=inode_index;
#ifdef DEBUG_FS
        printl("inode_index=%d(in do_open)\n",pinode->i_inode_index);
        printl("data_sector_index=%d data_sector_length=%d\n",process->file_descriptor[fd]->fd_inode->i_start_sector_index,process->file_descriptor[fd]->fd_inode->i_sectors_length);
#endif
        return fd;
    }else{
        set_error_index(PROCESS_FD_POINTER_NOT_ENOUGH);
        return -1;
    }
}
Пример #7
0
static void free_smap_bit(int bits_index,int bits_length){
    assert(bits_length==1,"only for sector_length=1 currently!");

#ifdef DEBUG_FS
    printl("bits_index=%d bits_length=%d(int free_smap_bit)\n",bits_index,bits_length);
#endif

    u8 fsbuf[SECTOR_SIZE];
    int sector_index,sector_length,bits_off, bytes_index,bytes_start,bytes_end;

    sector_index=get_smap_first_index(super_block)+bits_index/BITS_PER_SECTOR;
    sector_length=(bits_index+bits_length+BITS_PER_SECTOR-1)/BITS_PER_SECTOR;
    bits_off=bits_index%BITS_PER_SECTOR;
    bytes_start=(bits_off+BITS_PER_BYTE-1)/BITS_PER_BYTE;
    bytes_end=(bits_off+bits_length)/BITS_PER_BYTE;
#ifdef DEBUG_FS
    printl("bytes_start=%d bytes_end=%d (in fre_smap_bit)\n",bytes_start,bytes_end);
#endif    

    //读取smap数据
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              sector_index*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    /*分为三步处理:
      bits:           -------------------------------------------------
                         |  |  |                          |   |   |
      bits_index         8m ^   8(m+1)                   8n   ^   8(n+1)
      step:                | 1|            2             | 3 |
     */
    for(bits_index=bits_off;bits_index%BITS_PER_BYTE!=0 && bits_index<bits_off+bits_length;bits_index++){
#ifdef DEBUG_FS
        printl("bits_index=%d(step 1. in fre_smap_bit)",bits_index);
#endif
        fsbuf[bits_index/BITS_PER_BYTE] &=~(1<<bits_index%BITS_PER_BYTE); 
    }
#ifdef DEBUG_FS
    printl("\n");
#endif
    for(bytes_index=bytes_start;bytes_index<bytes_end;bytes_index++){
#ifdef DEBUG_FS
        printl("bytes_index=%d(step 2. in fre_smap_bit)",bytes_index);
#endif
        fsbuf[bytes_index]=0;
    }
#ifdef DEBUG_FS
    printl("\n");
#endif
    if(bytes_start<bytes_end){/*需要step3操作的情况*/
        for(bits_index=bytes_end*BITS_PER_BYTE;bits_index<bits_off+bits_length;bits_index++){
#ifdef DEBUG_FS
            printl("bits_index=%d(step 3. in fre_smap_bit)",bits_index);
#endif
            fsbuf[bits_index/BITS_PER_BYTE] &=~(1<<bits_index%BITS_PER_BYTE); 
        }
    }
/* #ifdef DEBUG_FS */
    printl("\n");
/* #endif */

    //更新smap数据
    rw_sector(INFO_FS_WRITE,
              ROOT_DEVICE,
              sector_index*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
}
Пример #8
0
/*
  Get some informations on the FLASH upgrade:
  - size
  - ROM base address
  - os version
  - calc type
*/
int ti68k_get_tib_infos(const char *filename, IMG_INFO *tib, int preload)
{
	FlashContent content;
	FlashContent *ptr;
	int nheaders = 0;
	int i;

	// No filename, exits
	if(!strcmp(g_basename(filename), ""))
	   return ERR_CANT_OPEN;

	// Check valid file
	if(!tifiles_file_is_ti(filename))
		return ERR_NOT_TI_FILE;
		
	if(!tifiles_file_is_tib(filename))
		return ERR_INVALID_UPGRADE;

	// Load file
	if(tifiles_file_read_flash(filename, &content) != 0)
        return ERR_INVALID_UPGRADE;
	
	// count headers
  	for (ptr = &content; ptr != NULL; ptr = ptr->next)
    	nheaders++;
  	
  	// keep the last one (data)
  	for (i = 0, ptr = &content; i < nheaders - 1; i++)
    	ptr = ptr->next;
    	
  	// Load TIB into memory and relocate at SPP
	if(tib->data == NULL)
  		tib->data = malloc(SPP + ptr->data_length + 4);
	if(tib->data == NULL)
		return ERR_MALLOC;

    memset(tib->data + SPP, 0xff, ptr->data_length);
  	memcpy(tib->data + SPP, ptr->data_part, ptr->data_length);
  	
  	// Update current rom infos
    tib->rom_base = tib->data[BO+5 + SPP] & 0xf0;

	// libtifiles can't distinguish TI89/TI89t and 92+/V200. We need to look.
	switch(ptr->device_type & 0xff)
	{
		case DEVICE_TYPE_89:    // can be a Titanium, too
            switch(tib->rom_base & 0xff)
            {
            case 0x20: tib->calc_type = TI89;  break;
            case 0x80: tib->calc_type = TI89t; break;
            default: return ERR_INVALID_UPGRADE;
            }
		break;
		case DEVICE_TYPE_92P:
            switch(tib->rom_base & 0xff)
            {
            case 0x20: tib->calc_type = V200;  break;
            case 0x40: tib->calc_type = TI92p; break;
            default: return ERR_INVALID_UPGRADE;
            }
		break;
		default:
			printl(0, "TIB problem: %02x!\n", 0xff & ptr->device_type);
			return ERR_INVALID_UPGRADE;
		break;
	}
    
  	tib->flash = FLASH_ROM;
  	tib->has_boot = 0;
  	tib->size = ptr->data_length + SPP;

  	get_rom_version(tib->data, tib->size, tib->version);
  	
  	tifiles_content_delete_flash(&content);
	if(!preload)
		free(tib->data);

  	return 0;
}
Пример #9
0
/*
  	Convert a romdump into an image.
	This kind of image is complete (boot & certificate).
*/
int ti68k_convert_rom_to_image(const char *srcname, const char *dirname, char **dstname)
{
  	FILE *f; 
  	int err;
	IMG_INFO img;
	char *ext;
	gchar *basename;

	*dstname = NULL;

	// No filename, exits
	if(!strcmp(g_basename(srcname), ""))
	   return ERR_CANT_OPEN;

	// Preload romdump
	memset(&img, 0, sizeof(IMG_INFO));
	err = ti68k_get_rom_infos(srcname, &img, !0);
	if(err)
    {
	    free(img.data);
      	printl(0, _("Unable to get informations on ROM dump: %s\n"), srcname);
      	return err;
    }
	ti68k_display_rom_infos(&img);

	// Create destination file
	basename = g_path_get_basename(srcname);
	ext = strrchr(basename, '.');
  	*ext='\0';
	strcat(basename, ".img");

	*dstname = g_strconcat(dirname, basename, NULL);
	g_free(basename);

	// Open dest file
  	f = fopen(*dstname, "wb");
  	if(f == NULL)
    {
      	fprintf(stderr, "Unable to open this file: <%s>\n", *dstname);
      	return ERR_CANT_OPEN;
    }

	// Some V200 and TI89 Titanium ROMs are half the size
	if((img.size < 4*MB) && (img.calc_type == V200 || img.calc_type == TI89t))
	{
		img.size = 4*MB;
		img.data = realloc(img.data, 4*MB + 4);
		printf("Completing image to 4MB !\n");
		memset(img.data + 2*MB, 0xff, 2*MB);
	}

	// Fill header
	strcpy(img.signature, "TiEmu img v2.00");
	img.header_size = sizeof(IMG_INFO);
    img.revision = IMG_REV;

	// Write file
	fwrite(&img, 1, sizeof(IMG_INFO), f);
	fwrite(img.data, sizeof(char), img.size, f);

	// Close file
	fclose(f);

  	return 0;
}
Пример #10
0
/*
 * Produces a number of object files in /tmp named objname.o.pid.o
 * with no external dependencies.
 *
 * gen_stub_prog is the address to the client stub generation prog
 * st_object is the address of the symmetric trust object.
 *
 * This is kind of a big hack.
 */
void
gen_stubs_and_link(char *gen_stub_prog, struct service_symbs *services)
{
	int pid = getpid();
	char tmp_str[2048];

	while (services) {
		int i;
		struct symb_type *symbs = &services->undef;
		char dest[256];
		char tmp_name[256];
		char *obj_name, *orig_name, *str;

		orig_name = services->obj;
		obj_name = basename(services->obj);
		sprintf(tmp_name, "/tmp/%s.%d", obj_name, pid);
		
/*		if (symbs->num_symbs == 0) {
			sprintf(tmp_str, "cp %s %s.o", 
				orig_name, tmp_name);
			system(tmp_str);

			str = malloc(strlen(tmp_name)+3);
			strcpy(str, tmp_name);
			strcat(str, ".o");
			free(services->obj);
			services->obj = str;

			services = services->next;
			continue;
		}
*/
		/* make the command line for an invoke the stub generator */
		strcpy(tmp_str, gen_stub_prog);

		if (symbs->num_symbs > 0) {
			strcat(tmp_str, " ");
			strcat(tmp_str, symbs->symbs[0].name);
		}
		for (i = 1 ; i < symbs->num_symbs ; i++) {
			strcat(tmp_str, ",");
			strcat(tmp_str, symbs->symbs[i].name);
		}

		/* invoke the stub generator */
		sprintf(dest, " > %s_stub.S", tmp_name);
		strcat(tmp_str, dest);
		printl(PRINT_DEBUG, "%s\n", tmp_str);
		system(tmp_str);

		/* compile the stub */
		sprintf(tmp_str, GCC_BIN " -m32 -c -o %s_stub.o %s_stub.S", 
			tmp_name, tmp_name);
		system(tmp_str);

		/* link the stub to the service */
		sprintf(tmp_str, LINKER_BIN " -m elf_i386 -r -o %s.o %s %s_stub.o", 
			tmp_name, orig_name, tmp_name);
		system(tmp_str);

		/* Make service names reflect their new linked versions */
		str = malloc(strlen(tmp_name)+3);
		strcpy(str, tmp_name);
		strcat(str, ".o");
		free(services->obj);
		services->obj = str;
		
		sprintf(tmp_str, "rm %s_stub.o %s_stub.S", tmp_name, tmp_name);
		system(tmp_str);

		services = services->next;
	}

	return;
}
Пример #11
0
/*
	Get some informations on the ROM dump:
	- size
	- ROM base address
	- FLASH/EPROM
	- os version
	- calc type
	Note: if the data field is NULL, memory is allocated. 
	Otherwise, data is overwritten.
	Thanks to Kevin for HW2 detection code.
*/
int ti68k_get_rom_infos(const char *filename, IMG_INFO *rom, int preload)
{
  	FILE *file;
    HW_PARM_BLOCK hwblock;

	// No filename, exits
    if(!strcmp(g_basename(filename), ""))
	    return ERR_CANT_OPEN;

	// Open file
  	file = fopen(filename, "rb");
  	if(file == NULL)
    {
      printl(0, _("Unable to open this file: <%s>\n"), filename);
      return ERR_CANT_OPEN;
    }

  	// Retrieve ROM size
  	fseek(file, 0, SEEK_END);
  	rom->size = ftell(file);
  	fseek(file, 0, SEEK_SET);

  	if(rom->size < 256) 
    	return ERR_INVALID_ROM_SIZE;
  	if (rom->size > 4*MB)
    	return ERR_INVALID_ROM_SIZE;
  
	if(rom->data == NULL)
  		rom->data = malloc(rom->size + 4);
	if(rom->data == NULL)
		return ERR_MALLOC;
  	memset(rom->data, 0xff, rom->size);
  	fread(rom->data, 1, rom->size, file);
  	fclose(file);

    rom->has_boot = 1;
    rom->rom_base = rom->data[0x05] & 0xf0;
  	rom->flash = (rom->data[0x65] & 0x0f) ? 0 : FLASH_ROM;

    get_rom_version(rom->data, rom->size, rom->version);

    if(!rom->flash)
    {
        rom->calc_type = TI92;
        rom->hw_type = HW1;
    }
    else
    {
        // Get hw param block to determine calc type & hw type
        if(ti68k_get_hw_param_block(rom->data, rom->rom_base, &hwblock) == -1)
			return ERR_INVALID_ROM;
        ti68k_display_hw_param_block(&hwblock);

        switch(hwblock.hardwareID)
        {
        case HWID_TI92P: rom->calc_type = TI92p; break;
        case HWID_TI89: rom->calc_type = TI89;  break;
        case HWID_V200: rom->calc_type = V200;  break;
        case HWID_TI89T: rom->calc_type = TI89t; break;
        default: break;
        }

        if(rom->flash)
        {
            if(hwblock.len < 24)
                rom->hw_type = HW1;
            else
                rom->hw_type = (char)hwblock.gateArray;
        }
    }

	if(!preload)
		free(rom->data);

	return 0;
}
Пример #12
0
/**
 * Perform the exec() system call.
 * 
 * @return  Zero if successful, otherwise -1.
 *****************************************************************************/
PUBLIC int do_exec()
{
	/* get parameters from the message */
	int name_len = mm_msg.NAME_LEN;	/* length of filename */
	int src = mm_msg.source;	/* caller proc nr. */
	assert(name_len < MAX_PATH);

	char pathname[MAX_PATH];
	phys_copy((void*)va2la(TASK_MM, pathname),
		  (void*)va2la(src, mm_msg.PATHNAME),
		  name_len);
	pathname[name_len] = 0;	/* terminate the string */

	/* change the directory of task fs to the caller's work directory  */
	tell_fs(CHDIR, src, 0, 0);

	/* get the file size */
	struct stat s;
	int ret = stat(pathname, &s);
	if (ret != 0) {
		printl("{MM} MM::do_exec()::stat() returns error. %s", pathname);
		return -1;
	}

	/* read the file */
	int fd = open(pathname, O_RDWR);
	if (fd == -1)
		return -1;
	assert(s.st_size < MMBUF_SIZE);
	read(fd, mmbuf, s.st_size);
	close(fd);

	/* setup the arg stack */
	int orig_stack_len = mm_msg.BUF_LEN;
	char stackcopy[PROC_ORIGIN_STACK];
	phys_copy((void*)va2la(TASK_MM, stackcopy),
		  (void*)va2la(src, mm_msg.BUF),
		  orig_stack_len);

	/* clean up the image of the current process */
	free_mem(src);

	/* the information about elf32 */
	u32 start_text = 0, end_text = 0, start_data = 0, end_data = 0;

	/* overwrite the current proc image with the new one */
	Elf32_Ehdr* elf_hdr = (Elf32_Ehdr*)(mmbuf);
	int i;
	for (i = 0; i < elf_hdr->e_phnum; i++) {
		Elf32_Phdr* prog_hdr = (Elf32_Phdr*)(mmbuf + elf_hdr->e_phoff +
			 			(i * elf_hdr->e_phentsize));
		if (prog_hdr->p_type == PT_LOAD) {
			assert(prog_hdr->p_vaddr + prog_hdr->p_memsz <
				PROC_IMAGE_SIZE_DEFAULT);
			phys_copy((void*)va2la(src, (void*)prog_hdr->p_vaddr),
				  (void*)va2la(TASK_MM,
						 mmbuf + prog_hdr->p_offset),
				  prog_hdr->p_filesz);
			if ((PF_R | PF_W) == prog_hdr->p_flags) {
					//the data segment
//					printl("elf32 .data start %d, size %d\n", prog_hdr->p_vaddr
//									, prog_hdr->p_memsz);
					start_data = prog_hdr->p_vaddr;
					end_data = start_data + prog_hdr->p_memsz;
			} else if ((PF_R | PF_X) == prog_hdr->p_flags) {
					//the text segment
//					printl("elf32 .text start %d, size %d\n", prog_hdr->p_vaddr
//									, prog_hdr->p_memsz);
					start_text = prog_hdr->p_vaddr;
					end_text = start_text + prog_hdr->p_memsz;
			}
		}
	}

	/* setup the arg stack */
//	int orig_stack_len = mm_msg.BUF_LEN;
//	char stackcopy[PROC_ORIGIN_STACK];
//	phys_copy((void*)va2la(TASK_MM, stackcopy),
//		  (void*)va2la(src, mm_msg.BUF),
//		  orig_stack_len);

	initial_brk(src, start_text, end_text, start_data, end_data);

	int * orig_stack = (int*)(VM_SIZE - PROC_ORIGIN_STACK);

	int delta = (int)orig_stack - (int)mm_msg.BUF;

	int argc = 0;
	if (orig_stack_len) {	/* has args */
		char **q = (char**)stackcopy;
		for (; *q != 0; q++,argc++)
			*q += delta;
	}

	phys_copy((void*)va2la(src, orig_stack),
		  (void*)va2la(TASK_MM, stackcopy),
		  orig_stack_len);

	proc_table[src].regs.ecx = argc; /* argc */
	proc_table[src].regs.eax = (u32)orig_stack; /* argv */

	/* setup eip & esp */
	proc_table[src].regs.eip = elf_hdr->e_entry; /* @see _start.asm */
	proc_table[src].regs.esp = VM_SIZE - PROC_ORIGIN_STACK;

	strcpy(proc_table[src].name, pathname);

	return 0;
}
Пример #13
0
/**
 * Remove a file.
 *
 * @note We clear the i-node in inode_array[] although it is not really needed.
 *       We don't clear the data bytes so the file is recoverable.
 * 
 * @return On success, zero is returned.  On error, -1 is returned.
 *****************************************************************************/
PUBLIC int do_unlink()
{
	char pathname[MAX_PATH];

	/* get parameters from the message */
	int name_len = fs_msg.NAME_LEN;	/* length of filename */
	int src = fs_msg.source;	/* caller proc nr. */
	assert(name_len < MAX_PATH);
	phys_copy((void*)va2la(TASK_FS, pathname),
		  (void*)va2la(src, fs_msg.PATHNAME),
		  name_len);
	pathname[name_len] = 0;

	if (strcmp(pathname , "/") == 0) {
		printl("FS:do_unlink():: cannot unlink the root\n");
		return -1;
	}

	int inode_nr = search_file(pathname);
	if (inode_nr == INVALID_INODE) {	/* file not found */
		printl("FS::do_unlink():: search_file() returns "
			"invalid inode: %s\n", pathname);
		return -1;
	}

	char filename[MAX_PATH];
	struct inode * dir_inode;
	if (strip_path(filename, pathname, &dir_inode) != 0)
		return -1;

	struct inode * pin = get_inode(dir_inode->i_dev, inode_nr);

	if (pin->i_mode != I_REGULAR) { /* can only remove regular files */
		printl("cannot remove file %s, because "
		       "it is not a regular file.\n",
		       pathname);
		return -1;
	}

	if (pin->i_cnt > 1) {	/* the file was opened */
		printl("cannot remove file %s, because pin->i_cnt is %d.\n",
		       pathname, pin->i_cnt);
		return -1;
	}

	struct super_block * sb = get_super_block(pin->i_dev);

	/*************************/
	/* free the bit in i-map */
	/*************************/
	int byte_idx = inode_nr / 8;
	int bit_idx = inode_nr % 8;
	assert(byte_idx < SECTOR_SIZE);	/* we have only one i-map sector */
	/* read sector 2 (skip bootsect and superblk): */
	RD_SECT(pin->i_dev, 2);
	assert(fsbuf[byte_idx % SECTOR_SIZE] & (1 << bit_idx));
	fsbuf[byte_idx % SECTOR_SIZE] &= ~(1 << bit_idx);
	WR_SECT(pin->i_dev, 2);

	/**************************/
	/* free the bits in s-map */
	/**************************/
	/*
	 *           bit_idx: bit idx in the entire i-map
	 *     ... ____|____
	 *                  \        .-- byte_cnt: how many bytes between
	 *                   \      |              the first and last byte
	 *        +-+-+-+-+-+-+-+-+ V +-+-+-+-+-+-+-+-+
	 *    ... | | | | | |*|*|*|...|*|*|*|*| | | | |
	 *        +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
	 *         0 1 2 3 4 5 6 7     0 1 2 3 4 5 6 7
	 *  ...__/
	 *      byte_idx: byte idx in the entire i-map
	 */
	bit_idx  = pin->i_start_sect - sb->n_1st_sect + 1;
	byte_idx = bit_idx / 8;
	int bits_left = pin->i_nr_sects;
	int byte_cnt = (bits_left - (8 - (bit_idx % 8))) / 8;

	/* current sector nr. */
	int s = 2  /* 2: bootsect + superblk */
		+ sb->nr_imap_sects + byte_idx / SECTOR_SIZE;

	RD_SECT(pin->i_dev, s);

	int i;
	/* clear the first byte */
	for (i = bit_idx % 8; (i < 8) && bits_left; i++,bits_left--) {
		//assert((fsbuf[byte_idx % SECTOR_SIZE] >> i & 1) == 1);
		fsbuf[byte_idx % SECTOR_SIZE] &= ~(1 << i);
	}

	/* clear bytes from the second byte to the second to last */
	int k;
	i = (byte_idx % SECTOR_SIZE) + 1;	/* the second byte */
	for (k = 0; k < byte_cnt; k++,i++,bits_left-=8) {
		if (i == SECTOR_SIZE) {
			i = 0;
			WR_SECT(pin->i_dev, s);
			RD_SECT(pin->i_dev, ++s);
		}
		//assert(fsbuf[i] == 0xFF);
		fsbuf[i] = 0;
	}

	/* clear the last byte */
	if (i == SECTOR_SIZE) {
		i = 0;
		WR_SECT(pin->i_dev, s);
		RD_SECT(pin->i_dev, ++s);
	}
	unsigned char mask = ~((unsigned char)(~0) << bits_left);
	//assert((fsbuf[i] & mask) == mask);
	fsbuf[i] &= (~0) << bits_left;
	WR_SECT(pin->i_dev, s);

	/***************************/
	/* clear the i-node itself */
	/***************************/
	pin->i_mode = 0;
	pin->i_size = 0;
	pin->i_start_sect = 0;
	pin->i_nr_sects = 0;
	sync_inode(pin);
	/* release slot in inode_table[] */
	put_inode(pin);

	/************************************************/
	/* set the inode-nr to 0 in the directory entry */
	/************************************************/
	int dir_blk0_nr = dir_inode->i_start_sect;
	int nr_dir_blks = (dir_inode->i_size + SECTOR_SIZE) / SECTOR_SIZE;
	int nr_dir_entries =
		dir_inode->i_size / DIR_ENTRY_SIZE; /* including unused slots
						     * (the file has been
						     * deleted but the slot
						     * is still there)
						     */
	int m = 0;
	struct dir_entry * pde = 0;
	int flg = 0;
	int dir_size = 0;

	for (i = 0; i < nr_dir_blks; i++) {
		RD_SECT(dir_inode->i_dev, dir_blk0_nr + i);

		pde = (struct dir_entry *)fsbuf;
		int j;
		for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) {
			if (++m > nr_dir_entries)
				break;

			if (pde->inode_nr == inode_nr) {
				/* pde->inode_nr = 0; */
				memset(pde, 0, DIR_ENTRY_SIZE);
				WR_SECT(dir_inode->i_dev, dir_blk0_nr + i);
				flg = 1;
				break;
			}

			if (pde->inode_nr != INVALID_INODE)
				dir_size += DIR_ENTRY_SIZE;
		}

		if (m > nr_dir_entries || /* all entries have been iterated OR */
		    flg) /* file is found */
			break;
	}
	assert(flg);
	if (m == nr_dir_entries) { /* the file is the last one in the dir */
		dir_inode->i_size = dir_size;
		sync_inode(dir_inode);
	}

	return 0;
}
Пример #14
0
PRIVATE void mkfs()
{
    MESSAGE driver_msg;
    int bits_per_sect = SECTOR_SIZE * 8;

    struct part_info geo;
    driver_msg.type = DEV_IOCTL;
    driver_msg.DEVICE = MINOR(ROOT_DEV);
    driver_msg.REQUEST = DIOCTL_GET_GEO;
    driver_msg.BUF = &geo;
    driver_msg.PROC_NR = TASK_FS;
    assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
    send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

    printl("dev base: 0x%x, dev size: 0x%x sectors\n", geo.base, geo.size);

    /***********************/
    /*     super block     */
    /***********************/
    struct super_block sb;
    sb.magic = MAGIC_V1;
    sb.nr_inodes = bits_per_sect;
    sb.nr_sects = geo.size;
    sb.nr_imap_sects = 1;
    sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1;
    sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
    sb.n_1st_sect = 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
    sb.root_inode = ROOT_INODE;
    sb.inode_size = INODE_SIZE;
    sb.inode_isize_off = offsetof(struct inode, i_size);
    sb.inode_start_off = offsetof(struct inode, i_start_sect);
    sb.dir_ent_size = DIR_ENTRY_SIZE;
    sb.dir_ent_inode_off = offsetof(struct dir_entry, inode_nr);
    sb.dir_ent_fname_off = offsetof(struct dir_entry, name);

    memset(fsbuf, 0x90, SECTOR_SIZE);
    memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);

    WR_SECT(ROOT_DEV, 1); // write the super block

    printl(
        "devbase: 0x%x00, sb: 0x%x00, imap: 0x%x00, smap: 0x%x00\n"
        "     inodes: 0x%x00, 1st_sector: 0x%x00\n", 
        geo.base * 2,
        (geo.base + 1) * 2,
        (geo.base + 1 + 1) * 2,
        (geo.base + 1 + 1 + sb.nr_imap_sects) * 2,
        (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
        (geo.base + sb.n_1st_sect) * 2
    );

    /***********************/
    /*      inode Map      */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    for (int i = 0; i < (NR_CONSOLES + 3); i++)
        fsbuf[0] |= 1 << i;

    assert(fsbuf[0] == 0x3F); /* 0011 1111
                               *   || |||`- bit 0 : reserved
                               *   || ||`-- bit 1 : the frist inode which indicates '/'
                               *   || |`--- bit 2 : /dev_tty0
                               *   || `---- bit 3 : /dev_tty1
                               *   |`------ bit 4 : /dev_tty2
                               *   `------- bit 5 : /cmd.tar
                               */
    WR_SECT(ROOT_DEV, 2);

    /***********************/
    /*      sector Map     */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    int nr_sects = NR_DEFAULT_FILE_SECTS + 1;

    int i;
    for (i = 0; i < nr_sects / 8; i++)
        fsbuf[i] = 0xFF;

    for (int j = 0; j < nr_sects % 8; j++)
        fsbuf[i] |= (1 << i);

    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

    memset(fsbuf, 0x0, SECTOR_SIZE);
    for (int i = 1; i < sb.nr_smap_sects; i++)
        WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

    /* cmd.tar */
    int bit_offset = INSTALL_START_SECT - sb.n_1st_sect + 1; // sect M <-> bit (M - sb.n_1stsect + 1)
    int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8);
    int bit_left = INSTALL_NR_SECTS;
    int cur_sect = bit_offset / (SECTOR_SIZE * 8);
    RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
    while (bit_left) {
        int byte_off = bit_off_in_sect / 8;
        /* this line is ineffecient in a loop, but I don't care */
        fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8);
        bit_left--;
        bit_off_in_sect++;
        if (bit_off_in_sect == (SECTOR_SIZE * 8)) {
            WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
            cur_sect++;
            RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
            bit_off_in_sect = 0;
        }
    }
    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);

    /***********************/
    /*        inodes       */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    struct inode *pi = (struct inode *)fsbuf;
    pi->i_mode = I_DIRECTORY;
    pi->i_size = DIR_ENTRY_SIZE * 5; // 5 files
    pi->i_start_sect = sb.n_1st_sect;
    pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
    
    for (int i = 0; i < NR_CONSOLES; i++) {
        pi = (struct inode *)(fsbuf + (INODE_SIZE * (i + 1)));
        pi->i_mode = I_CHAR_SPECIAL;
        pi->i_size = 0;
        pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
        pi->i_nr_sects = 0;
    }
    /* inode of `/cmd.tar' */
    pi = (struct inode*)(fsbuf + (INODE_SIZE * (NR_CONSOLES + 1)));
    pi->i_mode = I_REGULAR;
    pi->i_size = INSTALL_NR_SECTS * SECTOR_SIZE;
    pi->i_start_sect = INSTALL_START_SECT;
    pi->i_nr_sects = INSTALL_NR_SECTS;
    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

    /***********************/
    /*         '/'         */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    struct dir_entry *pde = (struct dir_entry *)fsbuf;

    pde->inode_nr = 1;
    strcpy(pde->name, ".");

    for (int i = 0; i < NR_CONSOLES; i++) {
        pde++;
        pde->inode_nr = i + 2;
        sprintf(pde->name, "dev_tty%d", i);
    }
    (++pde)->inode_nr = NR_CONSOLES + 2;
    strcpy(pde->name, "cmd.tar");
    WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Пример #15
0
/**
 * Perform the exec() system call.
 * 
 * @return  Zero if successful, otherwise -1.
 *****************************************************************************/
PUBLIC int do_exec()
{
	/* get parameters from the message */
	int name_len = mm_msg.NAME_LEN;	/* length of filename */
	int src = mm_msg.source;	/* caller proc nr. */
	assert(name_len < MAX_PATH);

	char pathname[MAX_PATH];
	phys_copy((void*)va2la(TASK_MM, pathname),
		  (void*)va2la(src, mm_msg.PATHNAME),
		  name_len);
	pathname[name_len] = 0;	/* terminate the string */

	/* get the file size */
	struct stat s;
	int ret = stat(pathname, &s);
	if (ret != 0) {
		printl("{MM} MM::do_exec()::stat() returns error. %s", pathname);
		return -1;
	}

	/* read the file */
	int fd = open(pathname, O_RDWR);
	if (fd == -1)
		return -1;
	assert(s.st_size < MMBUF_SIZE);
	read(fd, mmbuf, s.st_size);
	close(fd);

	/* overwrite the current proc image with the new one */
	Elf32_Ehdr* elf_hdr = (Elf32_Ehdr*)(mmbuf);
	int i;
	for (i = 0; i < elf_hdr->e_phnum; i++) {
		Elf32_Phdr* prog_hdr = (Elf32_Phdr*)(mmbuf + elf_hdr->e_phoff +
			 			(i * elf_hdr->e_phentsize));
		if (prog_hdr->p_type == PT_LOAD) {
			assert(prog_hdr->p_vaddr + prog_hdr->p_memsz <
				PROC_IMAGE_SIZE_DEFAULT);
			phys_copy((void*)va2la(src, (void*)prog_hdr->p_vaddr),
				  (void*)va2la(TASK_MM,
						 mmbuf + prog_hdr->p_offset),
				  prog_hdr->p_filesz);
		}
	}

	/* setup the arg stack */
	int orig_stack_len = mm_msg.BUF_LEN;
	char stackcopy[PROC_ORIGIN_STACK];
	phys_copy((void*)va2la(TASK_MM, stackcopy),
		  (void*)va2la(src, mm_msg.BUF),
		  orig_stack_len);

	u8 * orig_stack = (u8*)(PROC_IMAGE_SIZE_DEFAULT - PROC_ORIGIN_STACK);

	int delta = (int)orig_stack - (int)mm_msg.BUF;

	int argc = 0;
	if (orig_stack_len) {	/* has args */
		char **q = (char**)stackcopy;
		for (; *q != 0; q++,argc++)
			*q += delta;
	}

	phys_copy((void*)va2la(src, orig_stack),
		  (void*)va2la(TASK_MM, stackcopy),
		  orig_stack_len);

	proc_table[src].regs.ecx = argc; /* argc */
	proc_table[src].regs.eax = (u32)orig_stack; /* argv */

	/* setup eip & esp */
	proc_table[src].regs.eip = elf_hdr->e_entry; /* @see _start.asm */
	proc_table[src].regs.esp = PROC_IMAGE_SIZE_DEFAULT - PROC_ORIGIN_STACK;

	strcpy(proc_table[src].name, pathname);

	return 0;
}
Пример #16
0
/*
	Convert an upgrade into an image.
  	The image has neither boot block nor certificate.
*/
int ti68k_convert_tib_to_image(const char *srcname, const char *dirname, char **dstname,
							   int hw_type)
{
	FILE *f; 
  	int err;
	IMG_INFO img;
	char *ext;
	gchar *basename;
	int i, j;
	int num_blocks, last_block;
    int real_size;
	HW_PARM_BLOCK hwpb;

	*dstname = NULL;

	// No filename, exits
	if(!strcmp(g_basename(srcname), ""))
	   return ERR_CANT_OPEN;

	// Preload upgrade
	memset(&img, 0, sizeof(IMG_INFO));
	err = ti68k_get_tib_infos(srcname, &img, !0);
	if(err)
    {
	    free(img.data);
      	printl(0, _("Unable to get informations on FLASH upgrade: %s\n"), srcname);
      	return err;
    }
	ti68k_display_tib_infos(&img);

	// Create destination file
	basename = g_path_get_basename(srcname);
	ext = strrchr(basename, '.');
  	*ext='\0';
	strcat(basename, ".img");

	*dstname = g_strconcat(dirname, basename, NULL);
	g_free(basename);

	// Open dest file
  	f = fopen(*dstname, "wb");
  	if(f == NULL)
    {
      	fprintf(stderr, "Unable to open this file: <%s>\n", *dstname);
      	return ERR_CANT_OPEN;
    }

	// Fill header
	strcpy(img.signature, "TiEmu img v2.00");
	img.header_size = sizeof(IMG_INFO);
	img.revision = IMG_REV;
    real_size = img.size - SPP;
    img.size = ti68k_get_rom_size(img.calc_type);
    if(img.calc_type == TI89t)
        img.hw_type = HW3;  //default
    else if(hw_type == -1)
        img.hw_type = HW2;  //default
	else
		img.hw_type = hw_type;
	
	// Write header
	fwrite(&img, 1, sizeof(IMG_INFO), f);
  
  	// Write boot block
    memcpy(img.data, &img.data[SPP + BO], 256);
    fwrite(img.data, 1, 256, f);

    // Write hardware param block

	// fill structure
	hwpb.len = 24;
	switch(img.calc_type)
	{
		case TI89:
			hwpb.hardwareID = HWID_TI89;
			hwpb.hardwareRevision = img.hw_type - 1;
			break;
		case TI92p:
			hwpb.hardwareID = HWID_TI92P;
			hwpb.hardwareRevision = img.hw_type - 1;
			break;
		case V200:
			hwpb.hardwareID = HWID_V200;
			hwpb.hardwareRevision = 2;
			break;
		case TI89t:
			hwpb.hardwareID = HWID_TI89T;
			hwpb.hardwareRevision = 2;
			break;
	}
	hwpb.bootMajor = hwpb.bootRevision = hwpb.bootBuild = 1;
	hwpb.gateArray = img.hw_type;
	ti68k_put_hw_param_block(img.data, img.rom_base, &hwpb);

	// write filler
	fputc(0xfe, f); fputc(0xed, f); fputc(0xba, f); fputc(0xbe, f);
	//fwrite(&hwpb, 1hwpb.len+2, f);

	// write address (pointer)
    fputc(0x00, f);
    fputc(img.rom_base, f);
    fputc(0x01, f);
    fputc(0x08, f);

	// write structure
	fputc(MSB(hwpb.len), f);	
	fputc(LSB(hwpb.len), f);
	fputc(MSB(MSW(hwpb.hardwareID)), f);
	fputc(LSB(MSW(hwpb.hardwareID)), f);
	fputc(MSB(LSW(hwpb.hardwareID)), f);
	fputc(LSB(LSW(hwpb.hardwareID)), f);
	fputc(MSB(MSW(hwpb.hardwareRevision)), f);
	fputc(LSB(MSW(hwpb.hardwareRevision)), f);
	fputc(MSB(LSW(hwpb.hardwareRevision)), f);
	fputc(LSB(LSW(hwpb.hardwareRevision)), f);
	fputc(MSB(MSW(hwpb.bootMajor)), f);
	fputc(LSB(MSW(hwpb.bootMajor)), f);
	fputc(MSB(LSW(hwpb.bootMajor)), f);
	fputc(LSB(LSW(hwpb.bootMajor)), f);
	fputc(MSB(MSW(hwpb.hardwareRevision)), f);
	fputc(LSB(MSW(hwpb.hardwareRevision)), f);
	fputc(MSB(LSW(hwpb.hardwareRevision)), f);
	fputc(LSB(LSW(hwpb.hardwareRevision)), f);
	fputc(MSB(MSW(hwpb.bootBuild)), f);
	fputc(LSB(MSW(hwpb.bootBuild)), f);
	fputc(MSB(LSW(hwpb.bootBuild)), f);
	fputc(LSB(LSW(hwpb.bootBuild)), f);
	fputc(MSB(MSW(hwpb.gateArray)), f);
	fputc(LSB(MSW(hwpb.gateArray)), f);
	fputc(MSB(LSW(hwpb.gateArray)), f);
	fputc(LSB(LSW(hwpb.gateArray)), f);

	// Fill with 0xff up-to System Part
  	for(i = 0x108 + hwpb.len+2; i < SPP; i++)
    	fputc(0xff, f);
  
  	// Copy FLASH upgrade at 0x12000 (SPP)
  	num_blocks = real_size / 65536;
  	for(i = 0; i < num_blocks; i++ )
    {
      	printl(0, ".");
      	fflush(stdout);

      	fwrite(&img.data[65536 * i + SPP], sizeof(char), 65536, f);
    }

  	last_block = real_size % 65536;
   	fwrite(&img.data[65536 * i + SPP], sizeof(char), last_block, f);
  
  	printl(0, "\n");
  	printl(0, "Completing to %iMB size\n", img.size >> 20);
  	for(j = SPP + real_size; j < img.size; j++)
  		fputc(0xff, f);
  
  	// Close file
  	fclose(f);

  	return 0;
}
Пример #17
0
Файл: exec.c Проект: 1m69/OS67
int exec(char *path, char **argv){
    int i;
    char *s, *name;
    uint32_t sz, sp, off, argc, pa, ustack[3 + MAX_ARGC + 1];
    pde_t *pgdir, *old_pgdir;
    struct inode *ip;
    struct elf32hdr eh;
    struct proghdr ph;
    
    printl("exec: try to read `%s` form disk...\n", path);

    pgdir = 0;
    i = off = 0;

    pgdir = (pde_t *)pmm_alloc();
    kvm_init(pgdir);

    // exception handle pgdir
    //
    if ((ip = p2i(path)) == 0){
        goto bad;
    }
    ilock(ip);

    // read elf header
    if (iread(ip, (char *)&eh, 0, sizeof(eh)) < (int)sizeof(eh)){
        goto bad;
    }

    printl("exec: parsering elf\n");
    // print_elfhdr(&eh);

    if (eh.magic != ELF_MAGIC){
        goto bad;
    }

    printl("exec: load program section to memory\n");

    // load program to memory
    sz = USER_BASE;
    for (i = 0, off = eh.phoff; i < eh.phnum; i++, off += sizeof(ph)){
        if (iread(ip, (char *)&ph, off, sizeof(ph)) != sizeof(ph)){
            goto bad;
        }
        // print_proghdr(&ph);
        if (ph.type != ELF_PROG_LOAD){
            continue;
        }
        if (ph.memsz < ph.filesz){
            goto bad;
        }
        if ((sz = uvm_alloc(pgdir, sz, ph.vaddr + ph.memsz)) == 0){
            goto bad;
        }
        if (uvm_load(pgdir, ph.vaddr, ip, ph.off, ph.filesz) < 0){
            goto bad;
        }
    }

    iunlockput(ip);
    ip = 0;

    printl("exec: build user stack\n");
    /* build user stack */
    sz = PAGE_ALIGN_UP(sz);
    if ((sz = uvm_alloc(pgdir, sz, sz + 2*PAGE_SIZE)) == 0){
        goto bad;
    }

    /* leave a unaccessable page between kernel stack */
    if (vmm_get_mapping(pgdir, sz - 2*PAGE_SIZE, &pa) == 0){  // sz is no mapped
        goto bad;
    }
    vmm_map(pgdir, sz - 2*PAGE_SIZE, pa, PTE_K | PTE_P | PTE_W);

    sp = sz;
    if (vmm_get_mapping(pgdir, sz - PAGE_SIZE, &pa) == 0){  // sz is no mapped
        goto bad;
    }
    pa += PAGE_SIZE;

    printl("exec: argv ");
    for (argc = 0; argv[argc]; argc++){
        if (argc > MAX_ARGC) {
            goto bad;
        }
        printl("%d: %s ",argc, argv[argc]);
        // "+1" leava room for '\0'  "&~3" align 4
        sp = (sp - (strlen(argv[argc]) + 1)) & ~3;    // sync with pa
        pa = (pa - (strlen(argv[argc]) + 1)) & ~3;    

        strcpy((char *)pa, argv[argc]);
        ustack[3+argc] = sp;  // argv[argc]
    }
    printl("\n");

    ustack[3+argc] = 0;

    ustack[0] = 0xffffffff;
    ustack[1] = argc;   // count of arguments
    ustack[2] = sp - (argc+1)*4;    // pointer of argv[0]

    sp -= (3 + argc + 1)*4;
    pa -= (3 + argc + 1)*4;
    memcpy((void *)pa, ustack, (3 + argc + 1)*4);   // combine

    for (name = s = path; *s; s++){
        if (*s == '/'){
            name = s + 1;
        }
    }
    printl("exec: prepare for new process `%s`\n", name);

    cli();  // 不清楚此处是否会有死锁或冲突的风险, 反正关中断也不要钱
    strncpy(proc->name, name, sizeof(proc->name));

    old_pgdir = proc->pgdir;
    proc->pgdir = pgdir;
    proc->size = sz - USER_BASE;
    proc->fm->eip = eh.entry;
    proc->fm->user_esp = sp;
    uvm_switch(proc);

    printl("exec: free old pgdir\n");
    uvm_free(old_pgdir);
    old_pgdir  = 0;
    old_pgdir ++;
    sti();

    return 0;

bad:
    printl("exec: bad\n");
    if (pgdir){
        uvm_free(pgdir);
    }
    if (ip){
        iunlockput(ip);
    }
    return -1;
}
Пример #18
0
/*
    Convert an romdump into image and replace SPP by upgrade.
    The resulting image has boot block.
*/
int ti68k_merge_rom_and_tib_to_image(const char *srcname1, const char *srcname2, 
                                     const char *dirname, char **dstname)
{
    FILE *f; 
  	int err;
	IMG_INFO img;
	char *ext;
	gchar *basename;
    int real_size;

    *dstname = NULL;

	// No filename, exits
	if(!strcmp(g_basename(srcname1), ""))
		return ERR_CANT_OPEN;

	if(!strcmp(g_basename(srcname2), ""))
		return ERR_CANT_OPEN;

	// Preload romdump
    memset(&img, 0, sizeof(IMG_INFO));
	err = ti68k_get_rom_infos(srcname1, &img, !0);
	if(err)
    {
	    free(img.data);
      	printl(0, _("Unable to get informations on ROM dump: %s\n"), srcname1);
      	return err;
    }
	ti68k_display_rom_infos(&img);

    // Save size
    real_size = img.size;

    // Load upgrade

    err = ti68k_get_tib_infos(srcname2, &img, !0);
	if(err)
    {
	    free(img.data);
      	printl(0, _("Unable to get informations on ROM dump: %s\n"), srcname2);
      	return err;
    }
	ti68k_display_tib_infos(&img);

	// Create destination file
	basename = g_path_get_basename(srcname1);
	ext = strrchr(basename, '.');
  	*ext='\0';
	strcat(basename, ".img");

	*dstname = g_strconcat(dirname, basename, NULL);
	g_free(basename);

    // Restore size
    img.size = real_size;

	// Open dest file
  	f = fopen(*dstname, "wb");
  	if(f == NULL)
    {
      	fprintf(stderr, "Unable to open this file: <%s>\n", *dstname);
      	return ERR_CANT_OPEN;
    }

	// Fill header
	strcpy(img.signature, "TiEmu img v2.00");
	img.header_size = sizeof(IMG_INFO);
	img.revision = IMG_REV;
    img.has_boot = 1;

	// Write file
	fwrite(&img, 1, sizeof(IMG_INFO), f);
	fwrite(img.data, sizeof(char), img.size, f);

	// Close file
	fclose(f);

  	return 0;
}
Пример #19
0
static /* int */void do_write(MESSAGE *message){
    u8 fsbuf[SECTOR_SIZE*DEFAULT_FILE_SECTOR_LENGTH];
    const char *buf;
    int start_position,sector_length,length,data_sector_index;
    PROCESS *process;
    struct s_file_descriptor* pfd;

    process=pid2process(message->source_pid);
    if(message->fd==STDOUT && process->file_descriptor[message->fd]==NULL){
#ifdef DEBUG_FS
        printl("pid=%d (in do_write)\n",message->source_pid);
#endif
/*pfd->fd_inode->i_mode & I_CHAR_SPECIAL !=0*/
        /* int device=pfd->fd_inode->i_start_sector_index; */
        message->process_index=message->source_pid;
        send_receive(SEND,TASK_TTY/* dd_map[DRIVER(device)] */,message);
        /* message->type=INFO_SUSPEND_PROCESS; */
    }else{
        
        pfd=process->file_descriptor[message->fd];
        if((pfd->fd_op_mode & O_WRONLY)==0 && (pfd->fd_op_mode & O_RDWR)==0){
            set_error_index(FILE_CANNOT_WRITE);
            message->length=-1;
            return;
        }
        buf=message->arg_pointer;
        
        start_position=pfd->fd_position;
        if(start_position >= pfd->fd_inode->i_sectors_length*SECTOR_SIZE){
            set_error_index(FILE_ALLOC_MEM_USEUP);
            message->length=-1;
            return;
        }
        length=min(start_position+message->length,pfd->fd_inode->i_sectors_length*SECTOR_SIZE);
        sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
        data_sector_index=pfd->fd_inode->i_start_sector_index;
        
#ifdef DEBUG_FS
        /* printl("1 %d %d length=%d\n",start_position,message->length,length); */
        printl("sector_index=%d sector_length=%d(in do_write)\n",data_sector_index,sector_length);
#endif
        rw_sector(INFO_FS_READ,
                  ROOT_DEVICE,
                  (data_sector_index)*SECTOR_SIZE,
                  sector_length*SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        memcpy(fsbuf+start_position,buf,length-start_position);
        /* printl("2 %d %d\n",data_sector_index,length); */
        rw_sector(INFO_FS_WRITE,
                  ROOT_DEVICE,
                  (data_sector_index)*SECTOR_SIZE,
                  sector_length*SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        
        /* printl("3 inode.i_size=%d\n",pfd->fd_inode->i_size); */
        pfd->fd_inode->i_size=length;
        /* printl("inode_index=%d\n",pfd->fd_inode->i_inode_index); */
        sync_inode(pfd->fd_inode->i_inode_index,*(pfd->fd_inode));
        
        pfd->fd_position=length;  
        message->length=length-start_position;
    }
}
Пример #20
0
/*
  	Scan images in a given directory and write list into img_list.txt.
*/
int ti68k_scan_images(const char *dirname, const char *filename)
{
	FILE *file;
	IMG_INFO img;
	GDir *dir;
	GError *error = NULL;
	G_CONST_RETURN gchar *dirent;
	gchar *path, *str;
	int ret;
	struct stat f_info;
  	char *line[7];

  	printl(0, _("Scanning images/upgrades... "));

	// Create file (and overwrite)
	file = fopen(filename, "wt");
    if(file == NULL)
	{
	  	fprintf(stderr, _("Unable to open this file: <%s>\n"), filename);
	  	return ERR_CANT_OPEN;
	} 	

  	// List all files available in the directory
	dir = g_dir_open(dirname, 0, &error);
	if (dir == NULL) 
	{
		fprintf(stderr, _("Opendir error\n"));
      	return ERR_CANT_OPEN_DIR;
	}
  
	while ((dirent = g_dir_read_name(dir)) != NULL) 
	{
  		if (dirent[0] == '.') 
  			continue;
   
	  	path = g_strconcat(dirname, dirent, NULL);
	  	
		ret = stat(path, &f_info);
		if(ret == -1)
		{
			fprintf(stderr, _("Can not stat: <%s>\n"), dirent);
	      	perror("stat: ");
		}
		else
		{
			if(ti68k_is_a_img_file(path))
			{
				memset(&img, 0, sizeof(IMG_INFO));
				ret = ti68k_get_img_infos(path, &img);
				if(ret)
				{
					fprintf(stderr, _("Can not get ROM/update info: <%s>\n"), path);
					break;
				}
			}
            else
				continue;

			str = g_strdup_printf("%iKB", (int)(img.size >> 10));

		  	line[0] = (char *)dirent;
		  	line[1] = (char *)ti68k_calctype_to_string(img.calc_type);
	  		line[2] = img.version;
	  		line[3] = (char *)ti68k_romtype_to_string(img.flash);
	  		line[4] = str;
			line[5] = img.has_boot ? _("yes") : _("no");
			line[6] = (char *)ti68k_hwtype_to_string(img.hw_type);
	  
		  	fprintf(file, "%s,%s,%s,%s,%s,%s,%s\n", 
		  			line[0], line[1], line[2], 
		  			line[3], line[4], line[5], line[6]);
			g_free(str);
		}
	  	g_free(path);
    }      

	// Close
	g_dir_close(dir);
  
  	fclose(file);
  	printl(0, _("Done.\n"));
  
  	return 0;
}
Пример #21
0
/*****************************************************************************
 *                                spin
 *****************************************************************************/
PUBLIC void spin(char * func_name)
{
    printl("");
    while (1) {}
}
Пример #22
0
Файл: printf.c Проект: lsd53/pa4
//****************************************************************************
static int print (char **out, int *varg)
{
   int post_decimal ;
   int width, pad ;
   unsigned dec_width = 6 ;
   int pc = 0;
   char *format = (char *) (*varg++);
	char scr[2];
	for (; *format != 0; ++format) {
		if (*format == '%') {
			++format;
			width = pad = 0;
			if (*format == '\0')
				break;
			if (*format == '%')
				goto out;
			if (*format == '-') {
				++format;
				pad = PAD_RIGHT;
			}
			while (*format == '0') {
				++format;
				pad |= PAD_ZERO;
			}
         post_decimal = 0 ;
         if (*format == '.'  ||
            (*format >= '0' &&  *format <= '9')) {

            while (1) {
               if (*format == '.') {
                  post_decimal = 1 ;
                  dec_width = 0 ;
                  format++ ;
               } else if ((*format >= '0' &&  *format <= '9')) {
                  if (post_decimal) {
                     dec_width *= 10;
                     dec_width += *format - '0';
                  } else {
                     width *= 10;
                     width += *format - '0';
                  }
                  format++ ;
               } else {
                  break;
               }
            }
         }
	 int ll = 0;
	 if (*format == 'l') {
            ++format;
	    if (*format == 'l') {
	       ++format;
	       ll = 1;
	    }
	 }
         switch (*format) {
         case 's':
            {
            char *s = *((char **) varg++);   //lint !e740
            // printf("[%s] w=%u\n", s, width) ;
            pc += prints (out, s ? s : "(null)", width, pad);
            }
            break;
         case 'd':
	    if (ll) {
	       if (((unsigned int)varg & 7) != 0) varg++; // MIPS requires 8 byte aligned long longs
	       long long *llptr = (long long *) varg;
	       long long llval = *llptr++;
	       varg = (int *) llptr;
	       pc += printl (out, llval, 10, 1, width, pad, 'a');
	    } else {
	       pc += printi (out, *varg++, 10, 1, width, pad, 'a');
	    }
            break;
         case 'x':
	    if (ll) {
	       if (((unsigned int)varg & 7) != 0) varg++; // MIPS requires 8 byte aligned long longs
	       long long *llptr = (long long *) varg;
	       long long llval = *llptr++;
	       varg = (int *) llptr;
	       pc += printl (out, llval, 16, 0, width, pad, 'a');
	    } else {
	       pc += printi (out, *varg++, 16, 0, width, pad, 'a');
	    }
            break;
         case 'p':
	    pc += prints (out, "0x", 0, 0);
            pc += printi (out, *varg++, 16, 0, width ? width : 8, pad ? pad : PAD_ZERO , 'a');
            break;
         case 'X':
	    if (ll) {
	       if (((unsigned int)varg & 7) != 0) varg++; // MIPS requires 8 byte aligned long longs
	       long long *llptr = (long long *) varg;
	       long long llval = *llptr++;
	       varg = (int *) llptr;
	       pc += printl (out, llval, 16, 0, width, pad, 'A');
	    } else {
	       pc += printi (out, *varg++, 16, 0, width, pad, 'A');
	    }
            break;
         case 'u':
	    if (ll) {
	       if (((unsigned int)varg & 7) != 0) varg++; // MIPS requires 8 byte aligned long longs
	       long long *llptr = (long long *) varg;
	       long long llval = *llptr++;
	       varg = (int *) llptr;
	       pc += printl (out, llval, 10, 0, width, pad, 'a');
	    } else {
	       pc += printi (out, *varg++, 10, 0, width, pad, 'a');
	    }
            break;
         case 'c':
            /* char are converted to int then pushed on the stack */
            scr[0] = *varg++;
            scr[1] = '\0';
            pc += prints (out, scr, width, pad);
            break;

         case 'f':
            {
	    //if (((unsigned int)varg & 7) != 0) varg++; // MIPS requires 8 byte aligned doubles
            double *dblptr = (double *) varg ;  //lint !e740 !e826  convert to double pointer
            double dbl = *dblptr++ ;   //  increment double pointer
            varg = (int *) dblptr ;    //lint !e740  copy updated pointer back to base pointer
            char bfr[81] ;
            // unsigned slen =
            dbl2stri(bfr, dbl, dec_width) ;
            // stuff_talkf("[%s], width=%u, dec_width=%u\n", bfr, width, dec_width) ;
            pc += prints (out, bfr, width, pad);
            }
            break;

         default:
            printchar (out, '%');
            printchar (out, *format);
            break;
         }
		}
		else {
		 out:
			printchar (out, *format);
			++pc;
		}
	}
	if (out)
		**out = '\0';
	return pc;
}
Пример #23
0
Файл: open.c Проект: Zach41/OS
PUBLIC int do_open() {
    int fd = -1;
    char pathname[MAX_PATH];

    int flags = fs_msg.FLAGS;
    int name_len = fs_msg.NAME_LEN;
    int src = fs_msg.source;
    assert(name_len < MAX_PATH);

    memcpy((void*)va2la(TASK_FS, pathname), (void*)va2la(src, fs_msg.PATHNAME), name_len);
    pathname[name_len] = 0;

    int i;
    for(i=0; i<NR_FILES; i++) {
	/* a empty filp item */
	if (pcaller -> filp[i] == 0)
	    break;
    }
    fd = i;
    /* printl("PATHNAME: %s, NAME_LEN: %d, FD: %d\n", pathname, name_len, fd); */
    if (fd <0 || fd >= NR_FILES)
	panic("file[] is full. PID: %d", proc2pid(pcaller));

    for(i=0; i<NR_FILE_DESC; i++) {
	/* a empty file descriptor */
	if (f_desc_table[i].fd_inode == 0)
	    break;
    }
    if (i >= NR_FILE_DESC)
	panic("f_desc_table[] is full. PID: %d", proc2pid(pcaller));

    // FIXME: search_file is wrong
    int inode_nr = search_file(pathname);
    
    struct inode* pin = 0;
    if (flags & O_CREAT) {
	if (inode_nr) {
	    /* file exists */
	    printl("file exists\n");
	    return -1;
	} else {
	    pin = create_file(pathname, flags);
	    /* dump_inode(pin); */
	}
    } else {
	assert(flags & O_RDWR);

	char filename[MAX_PATH];
	struct inode* dir_inode;
	if (strip_path(filename, pathname, &dir_inode) != 0)
	    return -1;
	pin = get_inode(dir_inode -> i_dev, inode_nr);
    }

    if (pin) {
	pcaller -> filp[fd] = &f_desc_table[i];

	f_desc_table[i].fd_inode = pin;

	f_desc_table[i].fd_mode  = flags;

	f_desc_table[i].fd_pos   = 0;
	f_desc_table[i].fd_cnt   = 1;

	int imode = pin -> i_mode & I_TYPE_MASK;

	if (imode == I_CHAR_SPECIAL) {
	    /* tty */
	    MESSAGE msg;
	    msg.type = DEV_OPEN;

	    int dev = pin -> i_start_sect;
	    assert(MAJOR(dev) == 4);
	    assert(dd_map[MAJOR(dev)].driver_nr != INVALID_DRIVER);

	    msg.DEVICE = MINOR(dev);
	    send_recv(BOTH, dd_map[MAJOR(dev)].driver_nr, &msg);
	} else if (imode == I_DIRECTORY) {
	    assert(pin -> i_num == ROOT_INODE);
	} else {
	    assert(pin -> i_mode == I_REGULAR);
	}
    } else {
	return -1;
    }

    return fd;
}
Пример #24
0
/*======================================================================*
                               TestA
 *======================================================================*/
void TestA()
{
	int fd;
	int i, n;

	char filename[MAX_FILENAME_LEN+1] = "blah";
	const char bufw[] = "abcde";
	const int rd_bytes = 3;
	char bufr[rd_bytes];

	assert(rd_bytes <= strlen(bufw));

	/* create */
	fd = open(filename, O_CREAT | O_RDWR);
	assert(fd != -1);
	printl("File created: %s (fd %d)\n", filename, fd);

	/* write */
	n = write(fd, bufw, strlen(bufw));
	assert(n == strlen(bufw));

	/* close */
	close(fd);

	/* open */
	fd = open(filename, O_RDWR);
	assert(fd != -1);
	printl("File opened. fd: %d\n", fd);

	/* read */
	n = read(fd, bufr, rd_bytes);
	assert(n == rd_bytes);
	bufr[n] = 0;
	printl("%d bytes read: %s\n", n, bufr);

	/* close */
	close(fd);

	char * filenames[] = {"/foo", "/bar", "/baz"};

	/* create files */
	for (i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) {
		fd = open(filenames[i], O_CREAT | O_RDWR);
		assert(fd != -1);
		printl("File created: %s (fd %d)\n", filenames[i], fd);
		close(fd);
	}

	char * rfilenames[] = {"/bar", "/foo", "/baz", "/dev_tty0"};

	/* remove files */
	for (i = 0; i < sizeof(rfilenames) / sizeof(rfilenames[0]); i++) {
		if (unlink(rfilenames[i]) == 0)
			printl("File removed: %s\n", rfilenames[i]);
		else
			printl("Failed to remove file: %s\n", rfilenames[i]);
	}
	
	TestD();

	
	

	char tty_name[] = "/dev_tty0";

	char rdbuf[128];


	int fd_stdin  = open(tty_name, O_RDWR);
	assert(fd_stdin  == 0);
	int fd_stdout = open(tty_name, O_RDWR);
	assert(fd_stdout == 1);

//	char filename[MAX_FILENAME_LEN+1] = "zsp01";
	const char bufwns[80] = {0};
//	const int rd_bytes = 3;
//	char bufr[rd_bytes];
	
	clear();
	welcome();
	
	while (1) {
		printl("hunix->");
		int r = read(fd_stdin, rdbuf, 70);
		rdbuf[r] = 0;
		//show();
		if (strcmp(rdbuf, "process") == 0)
		{
			ProcessManage();
		}
		else if(strcmp(rdbuf, "TextBook") == 0)
		{
			TextBook(fd_stdin, fd_stdout);
		}
		else if (strcmp(rdbuf, "filemng") == 0)
		{
			printf("File Manager is already running on CONSOLE-1 ! \n");
			continue;

		}else if (strcmp(rdbuf, "help") == 0)
		{
			help();
		}
		else if (strcmp(rdbuf, "NewFile") == 0)
		{

			NewFile(fd_stdin, fd_stdout);
		}
		else if(strcmp(rdbuf, "RemoveFile") == 0)
		{
			RemoveFile(fd_stdin, fd_stdout);
		}
		else if(strcmp(rdbuf, "WriteFile") == 0)
		{
			WriteFile(fd_stdin, fd_stdout);
		}
		else if(strcmp(rdbuf, "ReadFile") == 0)
		{
			ReadFile(fd_stdin, fd_stdout);
		}
		else if(strcmp(rdbuf, "Chess") == 0)
		{
			chess(fd_stdin, fd_stdout);
		}
		else if(strcmp(rdbuf, "Add") == 0)
		{
			Add(fd_stdin, fd_stdout);
		}
		else if(strcmp(rdbuf, "welcome") == 0)
		{
			welcome();
		}
		else if(strcmp(rdbuf, "number") == 0)
		{
			number(fd_stdin, fd_stdout);
		}
		else if (strcmp(rdbuf, "clear") == 0)
		{
			clear();
			
		}
		else
			printf("Command not found, please check!\n");
	}
	

	spin("TestA");
}
Пример #25
0
/**
 * <Ring 1> The main loop of TASK FS.
 * 
 *****************************************************************************/
PUBLIC void task_fs()
{
	printl("Task FS begins.\n");
	init_fs();
	spin("FS");
}
Пример #26
0
void TestD()
{
	printl("hello Ninux");
}
static void
trans_vm_close(struct vm_area_struct *vma)
{
    printl("trans_munmap\n");
    return;
}
Пример #28
0
program()
{

    //check command syntax
    //edit filename
    if (dcount(COMMAND,FM)<2)
        abort("Syntax is 'edic osfilename'");

    var verbose=OPTIONS.ucase().index("V");

    var editor=osgetenv("VISUAL");
    var linenopattern="$LINENO ";
    if (not editor)
        editor.osgetenv("EDITOR");

    //TODO simplify this editor finding code

    //enable edit at first error for crimson editor (no quotes around filename for cedt)
    if (editor.lcase().index("cedt") and not editor.index("$") )
        editor^=" /L:$LINENO $FILENAME";

    //look for installed nano
    //if (SLASH eq "\\" and not index(PLATFORM_,"x64")) {
    var nanopath="";
    if (SLASH eq "\\") {

        //look for nano.exe next to edic.exe
        if (not editor)
            nanopath=EXECPATH.swap("edic","nano");
        if (nanopath.osfile())
            editor="nano $LINENO'$FILENAME'";
    }

    //look for nano in parent bin
    if (not editor) {
        nanopath="..\\bin\\nano.exe";
        if (nanopath.osfile())
            editor="nano $LINENO'$FILENAME'";
    }

    //look for nano in release directory during exodus development
    if (not editor) {
        nanopath="..\\..\\release\\cygwin\\bin\\nano.exe";
        if (nanopath.osfile())
            editor="..\\..\\release\\cygwin\\bin\\nano $LINENO'$FILENAME'";
        else {
            nanopath="..\\"^nanopath;
            if (nanopath.osfile())
                editor="..\\..\\..\\release\\cygwin\\bin\\nano $LINENO'$FILENAME'";
        }
    }

    if (editor.index("nano"))
        linenopattern="+$LINENO ";

    //otherwise on windows try to locate CYGWIN nano or vi
    var cygwinpath="";
    if (not editor and SLASH eq "\\") {
        //from environment variable
        cygwinpath=osgetenv("CYGWIN_BIN");
        //else from current disk
        if (not cygwinpath)
            cygwinpath="\\cygwin\\bin\\";
        //else from c:
        if (not osdir(cygwinpath))
            cygwinpath="c:\\cygwin\\bin\\";
        //else give up
        if (not osdir(cygwinpath))
            cygwinpath="";

        if (cygwinpath and cygwinpath[-1] ne SLASH)
            cygwinpath^=SLASH;
        //editor=cygwinpath^"bash --login -i -c \"/bin/";
        editor=cygwinpath;
        if (osfile(cygwinpath^"nano.exe") or osfile("nano.exe")) {
            editor="nano $LINENO'$FILENAME'";
            if (osfile(cygwinpath^"nano.exe"))
                editor.splicer(1,0,cygwinpath);
            //editor^="\"";
            linenopattern="+$LINENO ";
        } else if (osfile(cygwinpath^"vi.exe") or osfile("vi.exe")) {
            editor="vi -c \":$LINENO\" $FILENAME";
            if (osfile(cygwinpath^"vi.exe"))
                editor.splicer(1,0,cygwinpath);
            //editor^="\"";
        } else
            editor="";
    }
    if (SLASH eq "\\") {
        //configure nanorc (on windows)
        //TODO same for non-windows
        //nano on windows looks for nanorc config file as follows (probably merges all found)
        //C:\cygwin\usr\local\etc\nanorc
        //C:\cygwin\etc\nanorc (only if cygwin exists)
        //C:\Documents and Settings\USERNAME\.nanorc  ($HOMEDRIVE$HOMEPATH)
        var nanorcfilename;
        if (cygwinpath) {
            nanorcfilename=cygwinpath.field(SLASH,1,dcount(cygwinpath,SLASH)-2) ^ SLASH ^ "etc" ^ SLASH ^ "nanorc";
        } else {
            nanorcfilename=osgetenv("HOME");
            if (not nanorcfilename)
                nanorcfilename=osgetenv("HOMEDRIVE") ^ osgetenv("HOMEPATH");
            if (nanorcfilename[-1] ne SLASH)
                nanorcfilename^=SLASH;
            nanorcfilename^=".nanorc";
        }
        if (not osfile(nanorcfilename)) {
            //var nanorctemplatefilename=EXECPATH.field(SLASH,1,dcount(EXECPATH,SLASH)-1) ^ SLASH ^ "nanorc";
            var nanorctemplatefilename=nanopath.field(SLASH,1,dcount(nanopath,SLASH)-1) ^ SLASH ^ "nanorc";
            if (not osfile(nanorctemplatefilename))
                nanorctemplatefilename.swapper("release","..\\release");
            //if (not osfile(nanorctemplatefilename))
            //	nanorctemplatefilename.swapper("release","..\\"^PLATFORM_^"\\release");
            if (oscopy(nanorctemplatefilename,nanorcfilename)) {
                printl("Copied " ^ nanorctemplatefilename.quote() ^ " to " ^ nanorcfilename.quote());
                var ().input("Note: nano c++ syntax highlighting has been installed. Press Enter ... ");
            } else {
                errputl("Could not copy " ^ nanorctemplatefilename.quote() ^ " to " ^ nanorcfilename.quote());
                if (not osfile(nanorctemplatefilename))
                    errputl("nano syntax highlighting file is missing.");
            }
        }
        if(not osgetenv("HOME"))
            ossetenv("HOME",osgetenv("HOMEDRIVE") ^ osgetenv("HOMEPATH"));
    }

    if (not editor) {
        if (SLASH eq "/")
            editor="nano ";
        else
            editor="notepad";
        printl("Environment EDITOR not set. Using " ^ editor);
    }

    //editor="vi";
    editor.swapper("nano ", "nano --const --nowrap --autoindent --suspend ");

    if (editor.index("nano"))
        printl("http://www.nano-editor.org/dist/v2.1/nano.html");

    //configure nano syntax highlighting
    var filenames=field(COMMAND,FM,2,99999);
    var nfiles=dcount(filenames,FM);
    var filen=0;
    while (filen<nfiles) {
        filen+=1;
        var filename=filenames.a(filen).unquote();

        //split out trailing line number after :
        var startatlineno=field(filename,":",2);
        if (startatlineno.isnum())
            filename=field(filename,":",1);
        else
            startatlineno="";

        filename.trimmerb(".");
        if (not index(field2(filename,SLASH,-1),"."))
            filename^=".cpp";

        var iscompilable=filename.field2(".",-1)[1].lcase() ne "h";

        //make absolute in case EDITOR changes current working directory
        var editcmd=editor;
        if (editcmd.index("$ABSOLUTEFILENAME")) {
            editcmd.swapper("$ABSOLUTEFILENAME","$FILENAME");

            filename=oscwd()^SLASH^filename;
        }
        //prepare a skeleton exodus cpp file
        var newfile=false;
        if (iscompilable and not osfile(filename)) {

            var basefilename=field2(filename,SLASH,-1);
            basefilename=basefilename.field(".",dcount(basefilename,".")-1);

            var progtype;
            var question="1=Normal Program, 2=External Subroutine or Function";
            //question^="\n3=main(), 4=simple so/dll\n";
            question^="\n"^basefilename.quote()^" does not exist. Create what? (1-2) ";
            while (true) {
                if (basefilename.substr(1,5).lcase() eq "dict_")
                    progtype=5;
                else
                    progtype.input(question);
                if (progtype eq 2)
                    progtype="classlib";
                else if (progtype eq 3)
                    progtype="main";
                else if (progtype eq 4)
                    progtype="mainlib";
                else if (progtype eq 1)
                    progtype="class";
                else if (progtype eq 5)
                    progtype="dict";
                else
                    stop();
                break;
            }

            newfile=true;
            var blankfile="";
            if (progtype eq "main" or progtype eq "mainlib") {
                startatlineno="4,9";
                blankfile^="#include <exodus/exodus.h>\n";
                blankfile^="\n";
                blankfile^="program() {\n";
                blankfile^="\tprintl(\""^basefilename^" says 'Hello World!'\");\n";
                if (progtype eq "mainlib")
                    blankfile^="\treturn 0;\n";
                blankfile^="}\n";
                if (progtype eq "mainlib")
                    blankfile.swapper("program()","function "^basefilename^"()");
            } else if (progtype eq "class" or progtype eq "classlib") {
                startatlineno="6,9";
                blankfile^="#include <exodus/program.h>\n";
                //programinit() as 2nd line to avoid ppl in external functions before programinit
                //blankfile^="\n";
                blankfile^="programinit()\n";
                blankfile^="\n";
                blankfile^="function main(";
                //the .h maker not able to parse this yet and is rather clumsy anyway
                //if (progtype eq "classlib")
                //	blankfile^="/*in arg1, out arg2*/";
                blankfile^=") {\n";
                blankfile^="\tprintl(\""^basefilename^" says 'Hello World!'\");\n";
                blankfile^="\treturn 0;\n";
                blankfile^="}\n";
                blankfile^="\nprogramexit()";
                blankfile^="\n";

                if (progtype eq "classlib")
                    blankfile.swapper("program","library");
            } else if (progtype eq "dict") {
                startatlineno="6,9";
                blankfile^="#include <exodus/dict.h>\n\n";
                //programinit() as 2nd line to avoid ppl in external functions before programinit
                //blankfile^="\n";
                blankfile^="dict(EXAMPLEDICTID1) {\n";
                blankfile^="\tANS=RECORD(1)^\"x\";\n";
                blankfile^="}\n\n";

                blankfile^="dict(EXAMPLEDICTID2) {\n";
                blankfile^="\tANS=RECORD(2)^\"x\";\n";
                blankfile^="}\n";

            }

            if (blankfile[1] ne "\n")
                blankfile^="\n";
            if (SLASH ne "/")
                blankfile.swapper("\n","\r\n");

            if (not oswrite(blankfile,filename))
                stop("Cannot create "^filename^". Invalid file name, or no rights here.");
            //      startatlineno="4,9";
            //startatlineno="";
        }

        var editcmd0=editcmd;
        var linenopattern0=linenopattern;

        //keep editing and compiling until no errors
        while (true) {

            editcmd=editcmd0;
            linenopattern=linenopattern0;

            //record the current file update timestamp
            var fileinfo=osfile(filename);

            //build the edit command
            if (editcmd.index("$LINENO")) {
                if (not startatlineno)
                    linenopattern="";
                else
                    linenopattern.swapper("$LINENO",startatlineno.field(",",1));
                editcmd.swapper("$LINENO",linenopattern);
            }
            if (editcmd.index("$FILENAME"))
                editcmd.swapper("$FILENAME",filename);
            else
                editcmd ^= " " ^ filename;

            //call the editor
            if (verbose)
                printl(editcmd);
            osshell(editcmd);

            //if the file hasnt been updated
            var fileinfo2=osfile(filename);
            if (fileinfo2 ne fileinfo)
                newfile=false;
            else {
                //delete the skeleton
                printl("File unchanged. Not saving.");
                if (newfile)
                    osdelete(filename);
                //move to the next file
                break;
            }

            //clear the screen (should be cls on win)
            if (SLASH eq "/")
                osshell("clear");
            //else
            //	osshell("cls");

            if (not iscompilable)
                break;

            //build the compiler command
            var compiler="compile";
            var compileoptions="";
            var compilecmd=compiler ^ " " ^ filename.quote() ^ compileoptions;
            //capture the output
            var compileoutputfilename=filename ^ ".2";
            if (SLASH eq "/")
                compilecmd ^= " 2>&1 | tee " ^ compileoutputfilename.quote();
            else
                compilecmd ^= " > " ^ compileoutputfilename.quote() ^ " 2>&1";

            //call the compiler
            if (verbose)
                printl(compilecmd);
            osshell(compilecmd);

            //var tt;
            //tt.inputl("Press Enter ...");

            //if any errors then loop back to edit again
            var errors;
            if (osread(errors,compileoutputfilename)) {
                osdelete(compileoutputfilename);

                if (SLASH ne "/")
                    print(errors);

                startatlineno="";
                var charn;
                //gnu style error lines
                if (charn=index(errors, ": error:")) {
                    startatlineno=errors.substr(charn-9,9);

                    //printl(startatlineno);
                    startatlineno=startatlineno.field2(":",2);
                    //printl(startatlineno);
                    //msvc style error lines
                    //test.cpp(6) : error C2143: syntax error : missing ';' before '}'
                } else if (charn=index(errors,") : error ")) {
                    startatlineno=errors.substr(charn-10,10).field2("(",2);
                }
                if (startatlineno) {
                    print("Press any key to re-edit at line "^startatlineno^" ... ");
                    var().input("");
                    continue;
                }
            }

            break;
        }

    }
}
Пример #29
0
/*
 * For a certain principal, collect any unreferenced and not_in 
 * free list cbufs so that they can be reused.  This is the 
 * garbage-collection mechanism.
 *
 * Collect cbufs and add them onto the shared component's ring buffer.
 *
 * This function is semantically complicated. It can return no cbufs 
 * even if they are available to force the pool of cbufs to be
 * expanded (the client will call cbuf_create in this case). 
 * Or, the common case: it can return a number of available cbufs.
 */
int
cbuf_collect(spdid_t spdid, unsigned long size)
{
	struct cbuf_info *cbi;
	struct cbuf_comp_info *cci;
	struct cbuf_shared_page *csp;
	struct cbuf_bin *bin;
	int ret = 0;

	printl("cbuf_collect\n");

	CBUF_TAKE();
	cci  = cbuf_comp_info_get(spdid);
	tracking_start(&cci->track, CBUF_COLLECT);
	if (unlikely(!cci)) ERR_THROW(-ENOMEM, done);
	if (size + cci->allocated_size <= cci->target_size) goto done;

	csp  = cci->csp;
	if (unlikely(!csp)) ERR_THROW(-EINVAL, done);

	assert(csp->ring.size == CSP_BUFFER_SIZE);
	ret = CK_RING_SIZE(cbuf_ring, &csp->ring);
	if (ret != 0) goto done;
	/* 
	 * Go through all cbufs we own, and report all of them that
	 * have no current references to them.  Unfortunately, this is
	 * O(N*M), N = min(num cbufs, PAGE_SIZE/sizeof(int)), and M =
	 * num components.
	 */
	size = round_up_to_page(size);
	bin  = cbuf_comp_info_bin_get(cci, size);
	if (!bin) ERR_THROW(0, done);
	cbi  = bin->c;
	do {
		if (!cbi) break;
		/*
		 * skip cbufs which are in freelist. Coordinates with cbuf_free to 
		 * detect such cbufs correctly. 
		 * We must check refcnt first and then next pointer.
		 *
		 * If do not check refcnt: the manager may check "next" before cbuf_free 
		 * (when it is NULL), then switch to client who calls cbuf_free to set 
		 * "next", decrease refcnt and add cbuf to freelist. Then switch back to 
		 * manager, but now it will collect this in-freelist cbuf.
		 * 
		 * Furthermore we must check refcnt before the "next" pointer: 
		 * If not, similar to above case, the manager maybe preempted by client 
		 * between the manager checks "next" and refcnt. Therefore the manager 
		 * finds the "next" is null and refcnt is 0, and collect this cbuf.
		 * Short-circuit can prevent reordering. 
		 */
		assert(cbi->owner.m);
		if (!CBUF_REFCNT(cbi->owner.m) && !CBUF_IS_IN_FREELIST(cbi->owner.m)
                 		    && !cbuf_referenced(cbi)) {
			struct cbuf_ring_element el = { .cbid = cbi->cbid };
			cbuf_references_clear(cbi);
			if (!CK_RING_ENQUEUE_SPSC(cbuf_ring, &csp->ring, &el)) break;
			/*
			 * Prevent other collection collecting those cbufs.
			 * The manager checks if the shared ring buffer is empty upon 
			 * the entry, if not, it just returns. This is not enough to 
			 * prevent double-collection. The corner case is: 
			 * after the last one in ring buffer is dequeued and 
			 * before it is added to the free-list, the manager  
			 * appears. It may collect the last one again.
			 */
			cbi->owner.m->next = (struct cbuf_meta *)1;
			if (++ret == CSP_BUFFER_SIZE) break;
		}
		cbi = FIRST_LIST(cbi, next, prev);
	} while (cbi != bin->c);
	if (ret) cbuf_thd_wake_up(cci, ret*size);

done:
	tracking_end(&cci->track, CBUF_COLLECT);
	CBUF_RELEASE();
	return ret;
}

/* 
 * Called by cbuf_deref.
 */
int
cbuf_delete(spdid_t spdid, unsigned int cbid)
{
	struct cbuf_comp_info *cci;
	struct cbuf_info *cbi;
	struct cbuf_meta *meta;
	int ret = -EINVAL, sz;

	printl("cbuf_delete\n");
	CBUF_TAKE();
	tracking_start(NULL, CBUF_DEL);

	cci  = cbuf_comp_info_get(spdid);
	if (unlikely(!cci)) goto done;
	cbi  = cmap_lookup(&cbufs, cbid);
	if (unlikely(!cbi)) goto done;
	meta = cbuf_meta_lookup(cci, cbid);

	/*
	 * Other threads can access the meta data simultaneously. For
	 * example, others call cbuf2buf which increase the refcnt.
	 */
	CBUF_REFCNT_ATOMIC_DEC(meta);
	/* Find the owner of this cbuf */
	if (cbi->owner.spdid != spdid) {
		cci = cbuf_comp_info_get(cbi->owner.spdid);
		if (unlikely(!cci)) goto done;
	}
	if (cbuf_free_unmap(cci, cbi)) 	goto done;
	if (cci->allocated_size < cci->target_size) {
		cbuf_thd_wake_up(cci, cci->target_size - cci->allocated_size);
	}
	ret = 0;
done:
	tracking_end(NULL, CBUF_DEL);
	CBUF_RELEASE();
	return ret;
}

/* 
 * Called by cbuf2buf to retrieve a given cbid.
 */
int
cbuf_retrieve(spdid_t spdid, unsigned int cbid, unsigned long size)
{
	struct cbuf_comp_info *cci, *own;
	struct cbuf_info *cbi;
	struct cbuf_meta *meta, *own_meta;
	struct cbuf_maps *map;
	vaddr_t dest;
	void *page;
	int ret = -EINVAL, off;

	printl("cbuf_retrieve\n");

	CBUF_TAKE();
	tracking_start(NULL, CBUF_RETRV);

	cci        = cbuf_comp_info_get(spdid);
	if (!cci) {printd("no cci\n"); goto done; }
	cbi        = cmap_lookup(&cbufs, cbid);
	if (!cbi) {printd("no cbi\n"); goto done; }
	/* shouldn't cbuf2buf your own buffer! */
	if (cbi->owner.spdid == spdid) {
		printd("owner\n"); 
		goto done;
	}
	meta       = cbuf_meta_lookup(cci, cbid);
	if (!meta) {printd("no meta\n"); goto done; }
	assert(!(meta->nfo & ~CBUF_INCONSISENT));

	map        = malloc(sizeof(struct cbuf_maps));
	if (!map) {printd("no map\n"); ERR_THROW(-ENOMEM, done); }
	if (size > cbi->size) {printd("too big\n"); goto done; }
	assert(round_to_page(cbi->size) == cbi->size);
	size       = cbi->size;
	/* TODO: change to MAPPING_READ */
	if (cbuf_alloc_map(spdid, &map->addr, NULL, cbi->mem, size, MAPPING_RW)) {
		printc("cbuf mgr map fail spd %d mem %p sz %lu cbid %u\n", spdid, cbi->mem, size, cbid);
		goto free;
	}

	INIT_LIST(map, next, prev);
	ADD_LIST(&cbi->owner, map, next, prev);
	CBUF_PTR_SET(meta, map->addr);
	map->spdid          = spdid;
	map->m              = meta;
	meta->sz            = cbi->size >> PAGE_ORDER;
	meta->cbid_tag.cbid = cbid;
	own                 = cbuf_comp_info_get(cbi->owner.spdid);
	if (unlikely(!own)) goto done;
	/*
	 * We need to inherit the relinquish bit from the sender. 
	 * Otherwise, this cbuf cannot be returned to the manager. 
	 */
	own_meta            = cbuf_meta_lookup(own, cbid);
	if (CBUF_RELINQ(own_meta)) CBUF_FLAG_ADD(meta, CBUF_RELINQ);
	ret                 = 0;
done:
	tracking_end(NULL, CBUF_RETRV);

	CBUF_RELEASE();
	return ret;
free:
	free(map);
	goto done;
}

vaddr_t
cbuf_register(spdid_t spdid, unsigned int cbid)
{
	struct cbuf_comp_info  *cci;
	struct cbuf_meta_range *cmr;
	void *p;
	vaddr_t dest, ret = 0;

	printl("cbuf_register\n");
	CBUF_TAKE();
	tracking_start(NULL, CBUF_REG);

	cci = cbuf_comp_info_get(spdid);
	if (unlikely(!cci)) goto done;
	cmr = cbuf_meta_lookup_cmr(cci, cbid);
	if (cmr) ERR_THROW(cmr->dest, done);

	/* Create the mapping into the client */
	if (cbuf_alloc_map(spdid, &dest, &p, NULL, PAGE_SIZE, MAPPING_RW)) goto done;
	assert((unsigned int)p == round_to_page(p));
	cmr = cbuf_meta_add(cci, cbid, p, dest);
	assert(cmr);
	ret = cmr->dest;
done:
	tracking_end(NULL, CBUF_REG);

	CBUF_RELEASE();
	return ret;
}

static void
cbuf_shrink(struct cbuf_comp_info *cci, int diff)
{
	int i, sz;
	struct cbuf_bin *bin;
	struct cbuf_info *cbi, *next, *head;

	for (i = cci->nbin-1 ; i >= 0 ; i--) {
		bin = &cci->cbufs[i];
		sz = (int)bin->size;
		if (!bin->c) continue;
		cbi = FIRST_LIST(bin->c, next, prev);
		while (cbi != bin->c) {
			next = FIRST_LIST(cbi, next, prev);
			if (!cbuf_free_unmap(cci, cbi)) {
				diff -= sz;
				if (diff <= 0) return;
			}
			cbi = next;
		}
		if (!cbuf_free_unmap(cci, cbi)) {
			diff -= sz;
			if (diff <= 0) return;
		}
	}
	if (diff > 0) cbuf_mark_relinquish_all(cci);
}
Пример #30
0
/**
 * <Ring 1> The main loop of TASK FS.
 *
 *****************************************************************************/
PUBLIC void task_fs()
{
    printl("Task FS begins.\n");

    init_fs();

    while (1) {
        send_recv(RECEIVE, ANY, &fs_msg);

        int msgtype = fs_msg.type;
        int src = fs_msg.source;
        pcaller = &proc_table[src];

        switch (msgtype) {
        case OPEN:
            fs_msg.FD = do_open();
            break;
        case CLOSE:
            fs_msg.RETVAL = do_close();
            break;
        case READ:
        case WRITE:
            fs_msg.CNT = do_rdwt();
            break;
        case UNLINK:
            fs_msg.RETVAL = do_unlink();
            break;
        case RESUME_PROC:
            src = fs_msg.PROC_NR;
            break;
        case LS:
            fs_msg.RETVAL = do_ls();
            break;
        /* case LSEEK: */
        /*  fs_msg.OFFSET = do_lseek(); */
        /*  break; */
        /* case FORK: */
        /*  fs_msg.RETVAL = fs_fork(); */
        /*  break; */
        /* case EXIT: */
        /*  fs_msg.RETVAL = fs_exit(); */
        /*  break; */
        /* case STAT: */
        /*  fs_msg.RETVAL = do_stat(); */
        /*  break; */
        default:
            dump_msg("FS::unknown message:", &fs_msg);
            assert(0);
            break;
        }

#ifdef ENABLE_DISK_LOG
        char * msg_name[128];
        msg_name[OPEN]   = "OPEN";
        msg_name[CLOSE]  = "CLOSE";
        msg_name[READ]   = "READ";
        msg_name[WRITE]  = "WRITE";
        msg_name[LSEEK]  = "LSEEK";
        msg_name[UNLINK] = "UNLINK";
        msg_name[LS]   = "LS";
        /* msg_name[EXIT]   = "EXIT"; */
        /* msg_name[STAT]   = "STAT"; */

        switch (msgtype) {
        case LS:
        case CLOSE:
        case UNLINK:
            //dump_fd_graph("%s just finished.", msg_name[msgtype]);
            //panic("");
        case OPEN:
        case READ:
        case WRITE:
        /* case FORK: */
        /* case LSEEK: */
        /* case EXIT: */
        /* case STAT: */
            break;
        case RESUME_PROC:
        case DISK_LOG:
            break;
        default:
            assert(0);
        }
#endif

        /* reply */
        if (fs_msg.type != SUSPEND_PROC) {
            fs_msg.type = SYSCALL_RET;
            send_recv(SEND, src, &fs_msg);
        }
    }
}