桌面程序员
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