【转载】[OS] Bigger Files For Xv6
原文链接:https://blog.csdn.net/yuchunyu97/article/details/78250609
版权声明:本文为CSDN博主「AIslandX」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
首先下载Xv6的源码
➜ ~ git clone git://github.com/mit-pdos/xv6-public.git
Cloning into 'xv6-public'...
remote: Counting objects: 13900, done.
remote: Total 13900 (delta 0), reused 0 (delta 0), pack-reused 13900
Receiving objects: 100% (13900/13900), 17.07 MiB | 1.38 MiB/s, done.
Resolving deltas: 100% (9459/9459), done.
目录结构如下:
➜ xv6-public git:(master) tree
.
├── BUGS
├── LICENSE
├── Makefile
├── Notes
├── README
├── TRICKS
├── asm.h
├── bio.c
├── bootasm.S
├── bootmain.c
├── buf.h
├── cat.c
├── console.c
├── cuth
├── date.h
├── defs.h
├── dot-bochsrc
├── echo.c
├── elf.h
├── entry.S
├── entryother.S
├── exec.c
├── fcntl.h
├── file.c
├── file.h
├── forktest.c
├── fs.c
├── fs.h
├── gdbutil
├── grep.c
├── ide.c
├── init.c
├── initcode.S
├── ioapic.c
├── kalloc.c
├── kbd.c
├── kbd.h
├── kernel.ld
├── kill.c
├── lapic.c
├── ln.c
├── log.c
├── ls.c
├── main.c
├── memide.c
├── memlayout.h
├── mkdir.c
├── mkfs.c
├── mmu.h
├── mp.c
├── mp.h
├── param.h
├── picirq.c
├── pipe.c
├── pr.pl
├── printf.c
├── printpcs
├── proc.c
├── proc.h
├── rm.c
├── runoff
├── runoff.list
├── runoff.spec
├── runoff1
├── sh.c
├── show1
├── sign.pl
├── sleep1.p
├── sleeplock.c
├── sleeplock.h
├── spinlock.c
├── spinlock.h
├── spinp
├── stat.h
├── stressfs.c
├── string.c
├── swtch.S
├── symlink.patch
├── syscall.c
├── syscall.h
├── sysfile.c
├── sysproc.c
├── toc.ftr
├── toc.hdr
├── trap.c
├── trapasm.S
├── traps.h
├── types.h
├── uart.c
├── ulib.c
├── umalloc.c
├── user.h
├── usertests.c
├── usys.S
├── vectors.pl
├── vm.c
├── wc.c
├── x86.h
└── zombie.c
0 directories, 99 files
在Ubuntu下运行Xv6
在Linux下运行Xv6,需要安装qemu,在qemu中运行。([qemu使用指南]( User environments))
aaa@qq.com:~/Xv6$ sudo apt-get install qemu
进入Xv6目录,编译
aaa@qq.com:~$ cd Xv6/
aaa@qq.com:~/Xv6$ make
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -O -nostdinc -I. -c bootmain.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -nostdinc -I. -c bootasm.S
ld -m elf_i386 -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
objdump -S bootblock.o > bootblock.asm
objcopy -S -O binary -j .text bootblock.o bootblock
./sign.pl bootblock
boot block is 444 bytes (max 510)
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o bio.o bio.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o console.o console.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o exec.o exec.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o file.o file.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o fs.o fs.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o ide.o ide.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o ioapic.o ioapic.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o kalloc.o kalloc.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o kbd.o kbd.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o lapic.o lapic.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o log.o log.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o main.o main.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o mp.o mp.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o picirq.o picirq.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o pipe.o pipe.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o proc.o proc.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o sleeplock.o sleeplock.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o spinlock.o spinlock.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o string.o string.c
gcc -m32 -gdwarf-2 -Wa,-divide -c -o swtch.o swtch.S
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o syscall.o syscall.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o sysfile.o sysfile.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o sysproc.o sysproc.c
gcc -m32 -gdwarf-2 -Wa,-divide -c -o trapasm.o trapasm.S
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o trap.o trap.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o uart.o uart.c
perl vectors.pl > vectors.S
gcc -m32 -gdwarf-2 -Wa,-divide -c -o vectors.o vectors.S
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o vm.o vm.c
gcc -m32 -gdwarf-2 -Wa,-divide -c -o entry.o entry.S
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -nostdinc -I. -c entryother.S
ld -m elf_i386 -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o
objcopy -S -O binary -j .text bootblockother.o entryother
objdump -S bootblockother.o > entryother.asm
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -nostdinc -I. -c initcode.S
ld -m elf_i386 -N -e start -Ttext 0 -o initcode.out initcode.o
objcopy -S -O binary initcode.out initcode
objdump -S initcode.o > initcode.asm
ld -m elf_i386 -T kernel.ld -o kernel entry.o bio.o console.o exec.o file.o fs.o ide.o ioapic.o kalloc.o kbd.o lapic.o log.o main.o mp.o picirq.o pipe.o proc.o sleeplock.o spinlock.o string.o swtch.o syscall.o sysfile.o sysproc.o trapasm.o trap.o uart.o vectors.o vm.o -b binary initcode entryother
objdump -S kernel > kernel.asm
objdump -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > kernel.sym
gcc -Werror -Wall -o mkfs mkfs.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o ulib.o ulib.c
gcc -m32 -gdwarf-2 -Wa,-divide -c -o usys.o usys.S
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o printf.o printf.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o umalloc.o umalloc.c
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o cat.o cat.c
ld -m elf_i386 -N -e main -Ttext 0 -o _cat cat.o ulib.o usys.o printf.o umalloc.o
objdump -S _cat > cat.asm
objdump -t _cat | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > cat.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o echo.o echo.c
ld -m elf_i386 -N -e main -Ttext 0 -o _echo echo.o ulib.o usys.o printf.o umalloc.o
objdump -S _echo > echo.asm
objdump -t _echo | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > echo.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o forktest.o forktest.c
# forktest has less library code linked in - needs to be small
# in order to be able to max out the proc table.
ld -m elf_i386 -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o
objdump -S _forktest > forktest.asm
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o grep.o grep.c
ld -m elf_i386 -N -e main -Ttext 0 -o _grep grep.o ulib.o usys.o printf.o umalloc.o
objdump -S _grep > grep.asm
objdump -t _grep | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > grep.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o init.o init.c
ld -m elf_i386 -N -e main -Ttext 0 -o _init init.o ulib.o usys.o printf.o umalloc.o
objdump -S _init > init.asm
objdump -t _init | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > init.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o kill.o kill.c
ld -m elf_i386 -N -e main -Ttext 0 -o _kill kill.o ulib.o usys.o printf.o umalloc.o
objdump -S _kill > kill.asm
objdump -t _kill | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > kill.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o ln.o ln.c
ld -m elf_i386 -N -e main -Ttext 0 -o _ln ln.o ulib.o usys.o printf.o umalloc.o
objdump -S _ln > ln.asm
objdump -t _ln | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > ln.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o ls.o ls.c
ld -m elf_i386 -N -e main -Ttext 0 -o _ls ls.o ulib.o usys.o printf.o umalloc.o
objdump -S _ls > ls.asm
objdump -t _ls | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > ls.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o mkdir.o mkdir.c
ld -m elf_i386 -N -e main -Ttext 0 -o _mkdir mkdir.o ulib.o usys.o printf.o umalloc.o
objdump -S _mkdir > mkdir.asm
objdump -t _mkdir | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > mkdir.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o rm.o rm.c
ld -m elf_i386 -N -e main -Ttext 0 -o _rm rm.o ulib.o usys.o printf.o umalloc.o
objdump -S _rm > rm.asm
objdump -t _rm | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > rm.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o sh.o sh.c
ld -m elf_i386 -N -e main -Ttext 0 -o _sh sh.o ulib.o usys.o printf.o umalloc.o
objdump -S _sh > sh.asm
objdump -t _sh | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > sh.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o stressfs.o stressfs.c
ld -m elf_i386 -N -e main -Ttext 0 -o _stressfs stressfs.o ulib.o usys.o printf.o umalloc.o
objdump -S _stressfs > stressfs.asm
objdump -t _stressfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > stressfs.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o usertests.o usertests.c
ld -m elf_i386 -N -e main -Ttext 0 -o _usertests usertests.o ulib.o usys.o printf.o umalloc.o
objdump -S _usertests > usertests.asm
objdump -t _usertests | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > usertests.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o wc.o wc.c
ld -m elf_i386 -N -e main -Ttext 0 -o _wc wc.o ulib.o usys.o printf.o umalloc.o
objdump -S _wc > wc.asm
objdump -t _wc | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > wc.sym
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -c -o zombie.o zombie.c
ld -m elf_i386 -N -e main -Ttext 0 -o _zombie zombie.o ulib.o usys.o printf.o umalloc.o
objdump -S _zombie > zombie.asm
objdump -t _zombie | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > zombie.sym
./mkfs fs.img README _cat _echo _forktest _grep _init _kill _ln _ls _mkdir _rm _sh _stressfs _usertests _wc _zombie
nmeta 59 (boot, super, log blocks 30 inode blocks 26, bitmap blocks 1) blocks 941 total 1000
balloc: first 567 blocks have been allocated
balloc: write bitmap block at sector 58
dd if=/dev/zero of=xv6.img count=10000
记录了10000+0 的读入
记录了10000+0 的写出
5120000 bytes (5.1 MB, 4.9 MiB) copied, 0.0263045 s, 195 MB/s
dd if=bootblock of=xv6.img conv=notrunc
记录了1+0 的读入
记录了1+0 的写出
512 bytes copied, 0.000304086 s, 1.7 MB/s
dd if=kernel of=xv6.img seek=1 conv=notrunc
记录了333+1 的读入
记录了333+1 的写出
170848 bytes (171 kB, 167 KiB) copied, 0.00172819 s, 98.9 MB/s
在qemu中运行
aaa@qq.com:~/Xv6$ qemu-system-i386 -serial mon:stdio -hdb fs.img xv6.img -smp 1 -m 512
# 或者
aaa@qq.com:~/Xv6$ qemu-system-x86_64 -smp 1 -parallel stdio -hdb fs.img xv6.img -m 512
没成功,报了个错误:
WARNING: Image format was not specified for 'fs.img' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
WARNING: Image format was not specified for 'xv6.img' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
Could not initialize SDL(No available video device) - exiting
可以看到最后一行,无法初始化SDL
因为我们是在命令行中运行的,无法使用qemu的可视化终端界面
所以,采用下面这条命令运行*(如果在终端使用,可以不用make命令,直接使用下面这条命令编译并运行)*
aaa@qq.com:~/Xv6$ make qemu-nox
运行成功,提示以下信息:
qemu-system-i386 -nographic -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp 2 -m 512
xv6...
cpu1: starting 1
cpu0: starting 0
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
init: starting sh
$
Target:bigger files for xv6
修改 Makefile
将CPUS := 2
修改为CPUS := 1
在QEMUOPTS
前添加QEMUEXTRA = -snapshot
修改 param.h
将#define FSSIZE 1000 // size of file system in blocks
修改为#define FSSIZE 20000 // size of file system in blocks
添加 big.c
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"
int
main()
{
char buf[512];
int fd, i, sectors;
fd = open("big.file", O_CREATE | O_WRONLY);
if(fd < 0){
printf(2, "big: cannot open big.file for writing\n");
exit();
}
sectors = 0;
while(1){
*(int*)buf = sectors;
int cc = write(fd, buf, sizeof(buf));
if(cc <= 0)
break;
sectors++;
if (sectors % 100 == 0)
printf(2, ".");
}
printf(1, "\nwrote %d sectors\n", sectors);
close(fd);
fd = open("big.file", O_RDONLY);
if(fd < 0){
printf(2, "big: cannot re-open big.file for reading\n");
exit();
}
for(i = 0; i < sectors; i++){
int cc = read(fd, buf, sizeof(buf));
if(cc <= 0){
printf(2, "big: read error at sector %d\n", i);
exit();
}
if(*(int*)buf != i){
printf(2, "big: read the wrong data (%d) for sector %d\n",
*(int*)buf, i);
exit();
}
}
printf(1, "done; ok\n");
exit();
}
修改 Makefile
在UPROGS
中添加一行_big\
至此,可以在qemu中运行Xv6,然后输入命令big,会显示140个block。
$ big
.
wrote 140 sectors
done; ok
inode 数据结构
在Xv6系统中,每一个文件都有一个对应的inode。inode数据结构的定义:
//-----fs.h-----
// On-disk file system format.
// Both the kernel and user programs use this header file.
#define ROOTINO 1 // root i-number
#define BSIZE 512 // block size
...
#define NDIRECT 12
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT)
// On-disk inode structure
struct dinode {
short type; // File type
short major; // Major device number (T_DEV only)
short minor; // Minor device number (T_DEV only)
short nlink; // Number of links to inode in file system
uint size; // Size of file (bytes)
uint addrs[NDIRECT+1]; // Data block addresses
};
//-----fs.c-----
// The content (data) associated with each inode is stored
// in blocks on the disk. The first NDIRECT block numbers
// are listed in ip->addrs[]. The next NINDIRECT blocks are
// listed in block ip->addrs[NDIRECT].
...
bn -= NDIRECT;
if(bn < NINDIRECT){
// Load indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT]) == 0)
...
bp = bread(ip->dev, ip->addrs[NDIRECT]);
a = (uint*)bp->data;
for(j = 0; j < NINDIRECT; j++){
if(a[j])
bfree(ip->dev, a[j]);
可以看出,一个inode有12个direct指针,它们指向磁盘中的数据块,还有一个indirect指针指向另一个indirect block,这个indirect有BSIZE / sizeof(uint)
= 128个指针指向数据块。因此,一个inode可以指向12+128 = 140个数据块。也就是运行了big
命令后输出的140 sectors
。
因此,接下来要做的就是:
修改 fs.c
修改bmap()
函数
static uint
bmap(struct inode *ip, uint bn)
{
uint addr, *a, *indirect, *double_indirect,indirect_idx, double_indirect_idx;
struct buf *bp, *bp2;
if(bn < NDIRECT){
if((addr = ip->addrs[bn]) == 0)
ip->addrs[bn] = addr =balloc(ip->dev);
return addr;
}
bn -= NDIRECT;
if(bn < NINDIRECT){
// Load indirect block, allocating ifnecessary.
if((addr = ip->addrs[NDIRECT]) == 0)
ip->addrs[NDIRECT] = addr =balloc(ip->dev);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
if((addr = a[bn]) == 0){
a[bn] = addr = balloc(ip->dev);
log_write(bp);
}
brelse(bp);
return addr;
}
bn -= NINDIRECT;
if (bn < NINDIRECT*NINDIRECT) {
// Load first indirect block, allocating ifnecessary.
if((addr = ip->addrs[NDIRECT + 1]) == 0)
ip->addrs[NDIRECT + 1] = addr =balloc(ip->dev);
bp = bread(ip->dev, addr);
indirect = (uint *) bp->data;
indirect_idx = bn / NINDIRECT;
if ((addr = indirect[indirect_idx]) == 0) {
addr = indirect[indirect_idx] =balloc(ip->dev);
log_write(bp);
}
bp2 = bread(ip->dev, addr);
double_indirect = (uint *) bp2->data;
double_indirect_idx = bn % NINDIRECT;
if((addr = double_indirect[double_indirect_idx]) == 0) {
addr =double_indirect[double_indirect_idx] = balloc(ip->dev);
log_write(bp2);
}
brelse(bp2
修改 fs.h
将#define NDIRECT 12
修改为#define NDIRECT 11
将uint addrs[NDIRECT+1]; // Data block addresses
修改为uint addrs[NDIRECT+2]; // Data block addresses
将#define MAXFILE (NDIRECT + NINDIRECT)
修改为#define MAXFILE (NDIRECT + NINDIRECT + NINDIRECT * NINDIRECT)
重新编译运行 测试结果
编译好后,重新运行big
命令
$ big
..main-loop: WARNING: I/O thread spun for 1000 iterations
...................................................................................................................................................................
wrote 16523 sectors
done; ok
可以看到block从140变成了16523,成功了。
PS:16523 = 128 ✖️ 128(doubly-indirectblocks) + 11(singly-indirect blocks) + 128(directblocks)
参考资料:
Homework: bigger files for xv6