11orange 打开文件操作从上到下的一个实例源码

桌面程序员

int main()

{

intfd;

intn;

constchar filename[] = "blah";

constchar bufw[] = "abcde";

constint rd_bytes = 3;

charbufr[rd_bytes];

assert(rd_bytes <= strlen(bufw));

/* create &write */

fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, 0644);客户端调用lib中的open函数,想打开一个文件

if (fd == -1) {

printf("failedto open %s\n", filename);

return1;

}

……..

return0;

}

库函数程序员 Lib 下的 open()

PUBLIC int open(const char *pathname, intflags)

{

MESSAGEmsg;

msg.type = OPEN;

msg.PATHNAME = (void*)pathname;

msg.FLAGS = flags;

msg.NAME_LEN = strlen(pathname);

send_recv(BOTH, TASK_FS, &msg);将该open消息发送给TASK_FS

assert(msg.type== SYSCALL_RET);

returnmsg.FD;

}

os程序员 文件系统

PUBLIC void task_fs()

{

printl("TaskFS begins.\n");

init_fs();

while(1) {

send_recv(RECEIVE,ANY, &fs_msg);

intsrc = fs_msg.source;

pcaller= &proc_table[src];

switch(fs_msg.type) {

caseOPEN:

fs_msg.FD = do_open();调用 do_open

break;

caseCLOSE:

fs_msg.RETVAL= do_close();

break;

default:

dump_msg("FS::unknownmessage:", &fs_msg);

assert(0);

break;

}

/*reply */

fs_msg.type= SYSCALL_RET;

send_recv(SEND, src, &fs_msg);

}

}

PRIVATE void init_fs()

{

inti;

/*f_desc_table[] */

for(i = 0; i < NR_FILE_DESC; i++)

memset(&f_desc_table[i],0, sizeof(struct file_desc));

/*inode_table[] */

for(i = 0; i < NR_INODE; i++)

memset(&inode_table[i],0, sizeof(struct inode));

/*super_block[] */

structsuper_block * sb = super_block;

for(; sb < &super_block[NR_SUPER_BLOCK]; sb++)

sb->sb_dev = NO_DEV;

/* open thedevice: hard disk */

MESSAGEdriver_msg;

driver_msg.type = DEV_OPEN;

driver_msg.DEVICE = MINOR(ROOT_DEV);

assert(dd_map[MAJOR(ROOT_DEV)].driver_nr!= INVALID_DRIVER);

send_recv(BOTH,dd_map[MAJOR(ROOT_DEV)].driver_nr,&driver_msg);

// dd_map[MAJOR(ROOT_DEV)].driver_nr== TASK_HD这样就发给了驱动程序

/*make FS */

mkfs();

/*load super block of ROOT */

read_super_block(ROOT_DEV);

sb= get_super_block(ROOT_DEV);

assert(sb->magic== MAGIC_V1);

root_inode= get_inode(ROOT_DEV, ROOT_INODE);

}

do_open() 函数

PUBLIC int do_open()

{

…….

intinode_nr = search_file(pathname);

structinode * pin = 0;

if(flags & O_CREAT) {

if(inode_nr) {

printl("fileexists.\n");

return-1;

}

else{

pin= create_file(pathname, flags);先分配inode_map中的一位

在分配sector_map中的 n,这样就能确定inode所在的位置,和该inode指向的i_sector

以分配inode_map中的一位为例

}

}

………

return fd;

}

PRIVATE intalloc_imap_bit(int dev)

{

intinode_nr = 0;

inti, j, k;

intimap_blk0_nr = 1 + 1; /* 1 boot sector & 1 super block */

structsuper_block * sb = get_super_block(dev);

for(i = 0; i < sb->nr_imap_sects; i++) {

RD_SECT(dev, imap_blk0_nr + i);

for(j = 0; j < SECTOR_SIZE; j++) {

/*skip `11111111' bytes */

if(fsbuf[j] == 0xFF)

continue;

/*skip `1' bits */

for(k = 0; ((fsbuf[j] >> k) & 1) != 0; k++) {}

/*i: sector index; j: byte index; k: bit index */

inode_nr= (i * SECTOR_SIZE + j) * 8 + k;

fsbuf[j]|= (1 << k);

/*write the bit to imap */

WR_SECT(dev,imap_blk0_nr + i);

break;

}

returninode_nr;

}

/*no free bit in imap */

panic("inode-mapis probably full.\n");

return0;

}

#define RD_SECT(dev,sect_nr)rw_sector(DEV_READ, \

dev, \

(sect_nr) * SECTOR_SIZE, \

SECTOR_SIZE, /* read one sector */ \

TASK_FS, \

fsbuf);

#define WR_SECT(dev,sect_nr)rw_sector(DEV_WRITE, \

dev, \

(sect_nr) * SECTOR_SIZE, \

SECTOR_SIZE, /* write one sector */ \

TASK_FS, \

fsbuf);

PUBLIC intrw_sector(int io_type, int dev, u64 pos, int bytes,int proc_nr,

void* buf)

{

MESSAGEdriver_msg;

driver_msg.type=io_type;

driver_msg.DEVICE = MINOR(dev);

driver_msg.POSITION = pos;

driver_msg.BUF = buf;

driver_msg.CNT = bytes;

driver_msg.PROC_NR = proc_nr;

assert(dd_map[MAJOR(dev)].driver_nr!= INVALID_DRIVER);

send_recv(BOTH, dd_map[MAJOR(dev)].driver_nr,&driver_msg);

// dd_map[MAJOR(ROOT_DEV)].driver_nr== TASK_HD这样就发给了驱动程序

return0;

}

驱动程序员

PUBLIC void task_hd()

{

MESSAGEmsg;

init_hd();

while(1) {

send_recv(RECEIVE,ANY, &msg);

intsrc = msg.source;

switch(msg.type) {

caseDEV_OPEN:

hd_open(msg.DEVICE);

break;

caseDEV_CLOSE:

hd_close(msg.DEVICE);

break;

case DEV_READ:

case DEV_WRITE:

hd_rdwt(&msg);

break;

caseDEV_IOCTL:

hd_ioctl(&msg);

break;

default:

dump_msg("HDdriver::unknown msg", &msg);

spin("FS::main_loop (invalidmsg.type)");

break;

}

send_recv(SEND,src, &msg);

}

}

/*****************************************************************************

* hd_rdwt

*****************************************************************************/

/**

*<Ring 1> This routine handles DEV_READ and DEV_WRITE message.

*

*@param p Message ptr.

*****************************************************************************/

PRIVATE void hd_rdwt(MESSAGE * p)

{

intdrive = DRV_OF_DEV(p->DEVICE);

u64pos = p->POSITION;

assert((pos>> SECTOR_SIZE_SHIFT) < (1 << 31));

/**

* We only allow to R/W from a SECTOR boundary:

*/

assert((pos& 0x1FF) == 0);

u32sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); /* pos / SECTOR_SIZE */

intlogidx = (p->DEVICE - MINOR_hd1a) % NR_SUB_PER_DRIVE;

sect_nr += p->DEVICE < MAX_PRIM ?

hd_info[drive].primary[p->DEVICE].base:

hd_info[drive].logical[logidx].base;

structhd_cmd cmd;

cmd.features = 0;

cmd.count = (p->CNT + SECTOR_SIZE - 1) /SECTOR_SIZE;

cmd.lba_low = sect_nr & 0xFF;

cmd.lba_mid = (sect_nr >> 8) & 0xFF;

cmd.lba_high = (sect_nr >> 16) & 0xFF;

cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr>> 24) & 0xF);

cmd.command = (p->type == DEV_READ) ? ATA_READ :ATA_WRITE;

hd_cmd_out(&cmd);

intbytes_left = p->CNT;

void * la = (void*)va2la(p->PROC_NR,p->BUF);

while(bytes_left) {

intbytes = min(SECTOR_SIZE, bytes_left);

if(p->type == DEV_READ) {

interrupt_wait();

port_read(REG_DATA,hdbuf, SECTOR_SIZE);

phys_copy(la, (void*)va2la(TASK_HD,hdbuf), bytes);

}

else{

if(!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT))

panic("hdwriting error.");

port_write(REG_DATA,la, bytes);

interrupt_wait();

}

bytes_left-= SECTOR_SIZE;

la+= SECTOR_SIZE;

}

}

一些汇编写的函数

;=====================================================================

; void port_read(u16 port,void* buf, int n);

; =====================================================================

port_read:

mov edx,[esp + 4] ; port

mov edi,[esp + 4 + 4] ; buf

mov ecx, [esp + 4 + 4 + 4] ; n

shr ecx,1

cld

rep insw

ret

; ======================================================================

; void port_write(u16 port,void* buf, int n);

; ======================================================================

port_write:

mov edx,[esp + 4] ; port

mov esi,[esp + 4 + 4] ; buf

mov ecx,[esp + 4 + 4 + 4] ; n

shr ecx, 1

cld

rep outsw

ret

你可能感兴趣的:(11orange 打开文件操作从上到下的一个实例源码)