mirror of
https://github.com/DoctorWkt/pdp7-unix.git
synced 2026-01-13 15:27:39 +00:00
I've added code to mkfs7 to build a free block list, to write it out to
the disk image, and to add a pointer in block zero to the beginning of the list.
This commit is contained in:
parent
bfeb833141
commit
e5457d15fb
70
tools/mkfs7
70
tools/mkfs7
@ -14,7 +14,8 @@ Getopt::Long::Configure qw(gnu_getopt);
|
||||
# Constants
|
||||
use constant NUMBLOCKS => 8000; # Number of blocks on a surface
|
||||
use constant WORDSPERBLK => 64; # 64 words per block
|
||||
use constant NUMINODEBLKS => 710; # Number of i-nodes
|
||||
use constant LASTFREEBLOCK => 6399; # That's what s9.s uses
|
||||
use constant NUMINODEBLKS => 710; # Number of i-node blocks
|
||||
use constant FIRSTINODEBLK => 2; # First i-node block number
|
||||
use constant INODESIZE => 12; # Size of an i-node
|
||||
use constant INODESPERBLK => int(WORDSPERBLK / INODESIZE);
|
||||
@ -54,12 +55,12 @@ use constant D_NUMWORDS => 8; # Eight words in a direntry
|
||||
|
||||
# Globals
|
||||
my $debug = 0;
|
||||
my @Block; # Array of blocks and words in each block
|
||||
my $nextblknum = FIRSTINODEBLK + NUMINODEBLKS; # Next free block number
|
||||
my $nextinum = 1; # i-num 0 is never used
|
||||
my @Dirstack; # Stack of directories. Each value is a ref
|
||||
# to a [ blocknum, offset, inum ] array which
|
||||
# is the next free position in the directory
|
||||
my @Block; # Array of blocks and words in each block
|
||||
my @Freelist; # List of free block numbers
|
||||
my $nextinum = 1; # i-num 0 is never used
|
||||
my @Dirstack; # Stack of directories. Each value is a ref
|
||||
# to a [ blocknum, offset, inum ] array which
|
||||
# is the next free position in the directory
|
||||
|
||||
# Debug printing
|
||||
sub dprint {
|
||||
@ -70,6 +71,50 @@ sub dprintf {
|
||||
printf(@_) if ($debug);
|
||||
}
|
||||
|
||||
# Initialise the free block list
|
||||
# s9.s sets up blocks 710 to 6399 as free
|
||||
sub init_freelist {
|
||||
foreach my $blk (FIRSTINODEBLK+NUMINODEBLKS-1 .. LASTFREEBLOCK) {
|
||||
push(@Freelist, $blk);
|
||||
}
|
||||
}
|
||||
|
||||
# Recursively write the free list of blocks to disk.
|
||||
# Set up a block with nine free block numbers in it,
|
||||
# plus a pointer to the next block in the free list.
|
||||
# Return the block number of this block with nine free block numbers
|
||||
# or 0 if we did not set up out a block.
|
||||
# The argument is only used to make the debug output pleasing
|
||||
sub write_freelist {
|
||||
no warnings 'recursion';
|
||||
my $i= shift;
|
||||
|
||||
# Get a block to store nine free block numbers
|
||||
# Return if there are no free blocks
|
||||
my $thisblock= shift(@Freelist);
|
||||
return(0) if (!defined($thisblock));
|
||||
dprint("$thisblock ");
|
||||
dprint("\n") if (($i % 14) == 0);
|
||||
|
||||
# Try to grab nine of them and store in this block
|
||||
foreach my $count (1 .. 9) {
|
||||
$Block[$thisblock][$count]= shift(@Freelist) || 0;
|
||||
}
|
||||
|
||||
# Now we need the pointer to the next block in the chain
|
||||
$Block[$thisblock][0]= write_freelist($i+1);
|
||||
|
||||
# and return our own block number
|
||||
return($thisblock);
|
||||
}
|
||||
|
||||
# Fill block zero, the sysdata block, with whatever it needs.
|
||||
# As far as we can tell, all it needs is the pointer to the
|
||||
# beginning of the free list.
|
||||
sub fill_sysdata {
|
||||
$Block[0][0]= write_freelist(6);
|
||||
}
|
||||
|
||||
# Given a size in words, allocate and return a set of block numbers
|
||||
# for the entity
|
||||
sub allocate_blocks {
|
||||
@ -77,9 +122,10 @@ sub allocate_blocks {
|
||||
my @blklist;
|
||||
|
||||
my $numblocks = int( ( $numwords + WORDSPERBLK - 1 ) / WORDSPERBLK );
|
||||
die("Not enough blocks\n") if ( ( $nextblknum + $numblocks ) >= NUMBLOCKS );
|
||||
foreach my $b ( 1 .. $numblocks ) {
|
||||
push( @blklist, $nextblknum++ );
|
||||
foreach my $cnt ( 1 .. $numblocks ) {
|
||||
my $blk= shift(@Freelist);
|
||||
die("Not enough blocks\n") if (!defined($blk));
|
||||
push( @blklist, $blk );
|
||||
}
|
||||
dprintf(
|
||||
"Allocated blocks for size %d: %d .. %d (%06o .. %06o)\n",
|
||||
@ -568,6 +614,10 @@ GetOptions(
|
||||
) or usage();
|
||||
|
||||
usage() if ( @ARGV < 1 );
|
||||
init_freelist();
|
||||
parse_proto_file( $ARGV[0] );
|
||||
dprint("Storing free list in blocks ");
|
||||
fill_sysdata();
|
||||
dprint("\n");
|
||||
dump_image( $format, $output );
|
||||
exit(0);
|
||||
|
||||
@ -18,7 +18,7 @@ sub read_word {
|
||||
return (($b1 & 0xff) |
|
||||
(($b2 & 0xff) << 8 ) |
|
||||
(($b3 & 0xff) << 16) |
|
||||
(($b3 & 0xff) << 24));
|
||||
(($b4 & 0xff) << 24));
|
||||
}
|
||||
|
||||
### Main program
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user