OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Apr 24, 2024 5:24 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: [Solved] Increasing the filesystem block size in the xv6 OS
PostPosted: Wed Jul 20, 2016 7:56 pm 
Offline

Joined: Wed Jul 20, 2016 7:35 pm
Posts: 5
I'm bring up a reasonable set of C libraries (libc, libcurses etc.) plus a set of system utilities on the xv6 OS. In doing so, I'm starting to hit the 70K filesize limit imposed by the kernel (512 byte blocks, only one level of block indirection).

I believe strongly in keeping the xv6 kernel small and I don't want to touch it as possible. If I could double the block size, that would be great.

The vanilla xv6 code is at https://github.com/mit-pdos/xv6-public. My code is at https://github.com/DoctorWkt/xv6-minix2. I've moved some files around.

The kernel seems set up to change the block size. However, when I change the blocksize (BSIZE in include/xv6/fs.h) from 512 to 1024, the kernel doesn't boot. I can see the system trying to load /etc/init but that never happens.

By using gdb on the system running on Qemu, I can see the kernel calling idestart() [ in kern/ide.c ], which sends the PIO commands to the IDE controller. I don't know enough about IDE and PIO mode, but from what I've learned it looks OK.

I can see ideintr() field the first interrupt and copy the first 1K block into the kernel. Then idestart() is called to read a second block, but ideintr() never gets called a second time, so this seems to indicate that there is no second interrupt to indicate that the second IDE command was successful.

The system works fine with a block size of 512. I'd really appreciate ideas, suggestions, things I can try to diagnose the problem. Remember, I want to make as minimal changes to the kernel once we work out how to fix the problem!

Thanks in advance, Warren


Last edited by DoctorWkt on Sat Jul 23, 2016 6:02 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Wed Jul 20, 2016 8:00 pm 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
Is it possible that the implementation assumes that the block translates into a single physical sector? Disk sectors are 512-bytes long.


Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Wed Jul 20, 2016 10:24 pm 
Offline

Joined: Wed Jul 20, 2016 7:35 pm
Posts: 5
Here's the relevant code from the xv6 kernel
Code:
#define BSIZE 512  // block size

struct buf {
  int flags;
  uint dev;
  uint blockno;
  struct buf *prev; // LRU cache list
  struct buf *next;
  struct buf *qnext; // disk queue
  uchar data[BSIZE];
};

#define SECTOR_SIZE   512

// Start the request for b.  Caller must hold idelock.
static void
idestart(struct buf *b)
{
  if(b == 0)
    panic("idestart");
  if(b->blockno >= FSSIZE)
    panic("incorrect blockno");
  int sector_per_block =  BSIZE/SECTOR_SIZE;
  int sector = b->blockno * sector_per_block;

  if (sector_per_block > 7) panic("idestart");
 
  idewait(0);
  outb(0x3f6, 0);  // generate interrupt
  outb(0x1f2, sector_per_block);  // number of sectors
  outb(0x1f3, sector & 0xff);
  outb(0x1f4, (sector >> 8) & 0xff);
  outb(0x1f5, (sector >> 16) & 0xff);
  outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((sector>>24)&0x0f));
  if(b->flags & B_DIRTY){
    outb(0x1f7, IDE_CMD_WRITE);
    outsl(0x1f0, b->data, BSIZE/4);
  } else {
    outb(0x1f7, IDE_CMD_READ);
  }
}

// Interrupt handler.
void
ideintr(void)
{
  struct buf *b;

  // First queued buffer is the active request.
  acquire(&idelock);
  if((b = idequeue) == 0){
    release(&idelock);
    // cprintf("spurious IDE interrupt\n");
    return;
  }
  idequeue = b->qnext;

  // Read data if needed.
  if(!(b->flags & B_DIRTY) && idewait(1) >= 0)
    insl(0x1f0, b->data, BSIZE/4);
 
  // Wake process waiting for this buf.
  b->flags |= B_VALID;
  b->flags &= ~B_DIRTY;
  wakeup(b);
 
  // Start disk on next buf in queue.
  if(idequeue != 0)
    idestart(idequeue);

  release(&idelock);
}


static inline void
insl(int port, void *addr, int cnt)
{
  asm volatile("cld; rep insl" :
               "=D" (addr), "=c" (cnt) :
               "d" (port), "0" (addr), "1" (cnt) :
               "memory", "cc");
}

static inline void
outsl(int port, const void *addr, int cnt)
{
  asm volatile("cld; rep outsl" :
               "=S" (addr), "=c" (cnt) :
               "d" (port), "0" (addr), "1" (cnt) :
               "cc");
}


The lines outsl(0x1f0, b->data, BSIZE/4); and insl(0x1f0, b->data, BSIZE/4); are writing/reading the buffer in 32-bit word units, so yes it does look like the code is trying to read/write the correct amount of data. And outb(0x1f2, sector_per_block); is setting up the transfer to be the correct number of 512-byte sectors in each block.

Hope this helps. Thanks! Warren


Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Wed Jul 20, 2016 10:43 pm 
Offline

Joined: Wed Jul 20, 2016 7:35 pm
Posts: 5
Ha, I worked it out. The code wasn't issuing the ATA commands for multiple sectors. Here's my working changes:

Code:
#define IDE_CMD_READ  0x20
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_RDMUL 0xC4
#define IDE_CMD_WRMUL 0xC5

. . .

  int sector_per_block =  BSIZE/SECTOR_SIZE;
  int sector = b->blockno * sector_per_block;
  uchar read_cmd=  (sector_per_block ==1) ? IDE_CMD_READ :  IDE_CMD_RDMUL;
  uchar write_cmd= (sector_per_block ==1) ? IDE_CMD_WRITE : IDE_CMD_WRMUL;

. . .

  if(b->flags & B_DIRTY){
    outb(0x1f7, write_cmd);
    outsl(0x1f0, b->data, BSIZE/4);
  } else {
    outb(0x1f7, read_cmd);
  }


Cheers, Warren


Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Thu Jul 21, 2016 12:09 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
With 128-140KB file size limits you may be able to run a rather usable C compiler in the system!

The sizes of my Smaller C compiler's binaries for Linux (self-compiled):
smlrc 131072
smlrpp 126976
smlrl 53248
smlrcc 40960
n2f 28672

The C library for Linux (self-compiled):
lcl.a 178000 (compiled using NASM (debug info retained))
lcl.a 124472 (compiled using n2f + FASM)

FASM for Linux:
fasm 103342

I see you've added some missing stuff, e.g. lseek.

These are the system calls used in my library/compiler, very conservative use:
Code:
>findstr sys_ *.c
clock.c:  asm("mov eax, 43\n" // sys_times
close.c:  asm("mov eax, 6\n" // sys_close
exit.c:  asm("mov eax, 1\n" // sys_exit
isatty.c:  asm("mov eax, 54\n" // sys_ioctl
localtim.c:  asm("mov eax, 78\n" // sys_gettimeofday
lseek.c:  asm("mov eax, 19\n" // sys_lseek
malloc.c:  asm("mov eax, 45\n" // sys_brk
mktime.c:  asm("mov eax, 78\n" // sys_gettimeofday
open.c:  asm("mov eax, 5\n" // sys_open
read.c:  asm("mov eax, 3\n" // sys_read
rename.c:  asm("mov eax, 38\n" // sys_rename
system.c:  asm("mov eax, 2\n" // sys_fork
system.c:  asm("mov eax, 7\n" // sys_waitpid
system.c:  asm("mov eax, 11\n" // sys_execve
time.c:  asm("mov eax, 13\n" // sys_time
tmpnam.c:  asm("mov eax, 33\n" // sys_access
unlink.c:  asm("mov eax, 10\n" // sys_unlink
write.c:  asm("mov eax, 4\n" // sys_write


Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Thu Jul 21, 2016 2:07 am 
Offline

Joined: Wed Jul 20, 2016 7:35 pm
Posts: 5
Looks good. I'll add it to the list of things to try and bring up on the system :-)

Thanks, Warren


Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Thu Jul 21, 2016 2:15 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
Feel free to ask questions about the code.


Top
 Profile  
 
 Post subject: Re: Increasing the filesystem block size in the xv6 OS
PostPosted: Wed Jun 17, 2020 4:20 pm 
Offline
Member
Member

Joined: Tue Apr 24, 2018 9:46 pm
Posts: 74
DoctorWkt wrote:
Looks good. I'll add it to the list of things to try and bring up on the system :-)

Hi, did you ever get around to this?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: AlmaX3, Bing [Bot], Google [Bot], Majestic-12 [Bot] and 132 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group