init: init nachos hw01, should pass jenkins os_group_20_hw job but fail on os_group_20_ta job

This commit is contained in:
TA
2024-09-19 18:59:13 +08:00
commit 6ad2fa368f
267 changed files with 71977 additions and 0 deletions

63
coff2noff/Makefile Normal file
View File

@@ -0,0 +1,63 @@
# Makefile for:
# coff2noff -- converts a normal MIPS executable into a Nachos executable
#
# This is a GNU Makefile. It must be used with the GNU make program.
# At UW, the GNU make program is /software/gnu/bin/make.
# In many other places it is known as "gmake".
# You may wish to include /software/gnu/bin/ early in your command
# search path, so that you will be using GNU make when you type "make".
#
# Use "make" to build the executable(s)
# Use "make clean" to remove .o files
# Use "make distclean" to remove all files produced by make, including
# the executable
#
#
# Copyright (c) 1992-1996 The Regents of the University of California.
# All rights reserved. See copyright.h for copyright notice and limitation
# of liability and disclaimer of warranty provisions.
#
# This file has been modified for use at Waterloo
#
#############################################################################
# Makefile.dep contains all machine-dependent definitions
# If you are trying to build coff2noff somewhere outside
# of the MFCF environment, you will almost certainly want
# to visit and edit Makefile.dep before doing so
#############################################################################
include Makefile.dep
CC=gcc
CFLAGS= $(HOSTCFLAGS) -DRDATA -m32
LD=gcc -m32
RM = /bin/rm
MV = /bin/mv
ifeq ($(hosttype),unknown)
buildtargets = unknownhost
else
buildtargets = coff2noff.$(hosttype)
endif
all: $(buildtargets)
# converts a COFF file to Nachos object format
coff2noff.$(hosttype): coff2noff.o
$(LD) coff2noff.o -o coff2noff.$(hosttype)
strip coff2noff.$(hosttype)
clean:
$(RM) -f coff2noff.o
distclean: clean
$(MV) coff2noff.c temp.c
$(RM) -f coff2noff.*
$(MV) temp.c coff2noff.c
unknownhost:
@echo Host type could not be determined.
@echo make is terminating
@echo If you are on an MFCF machine, contact the instructor
@echo to report this problem
@echo Otherwise, edit Makefile.dep and try again.

91
coff2noff/Makefile.dep Normal file
View File

@@ -0,0 +1,91 @@
#############################################################################
# Machine-specific definitions
#
# In the MFCF environment, this attempts to determine automatically
# the machine type and OS type. If it cannot, it gives up and
# prints a message.
#
# If you are not in the MFCF environment, you can either add a new
# automatic test for your machine/OS type, or you can set the
# necessary variables "manually" here
#############################################################################
# unfortunately, command line arguments to uname are not
# very consistent across UNIX flavours. However, the following
# seem to work almost everywhere in MFCF land
osname = $(shell uname -s)
osrelease = $(shell uname -r)
hosttype = unknown
# Test for Solaris (5.6)
# At Waterloo: agnesi,bacon,fenchel,fitch,lassar,magnus,merrill
# If Solaris, we assume we are on a SPARC, which is not necessarily
# a good assumption outside of MFCF
ifeq ($(osname),SunOS)
ifeq ($(osrelease),5.6)
HOSTCFLAGS = -DHOST_IS_BIG_ENDIAN
hosttype = sparcSolaris
endif
endif
# Test for Solaris (5.5)
# At Waterloo: hermite.math,markov.math,picard.math,wronski.math,...
# If Solaris, we assume we are on a SPARC, which is not necessarily
# a good assumption outside of MFCF
ifeq ($(osname),SunOS)
ifeq ($(osrelease),5.5)
HOSTCFLAGS = -DHOST_IS_BIG_ENDIAN
hosttype = sparcSolaris
endif
endif
# Test for Solaris (5.4)
# At Waterloo: hume.math, hypatia.math,...
# This is the same setup as Solaris 5.5
# If Solaris, we assume we are on a SPARC, which is not necessarily
# a good assumption outside of MFCF
ifeq ($(osname),SunOS)
ifeq ($(osrelease),5.4)
HOSTCFLAGS = -DHOST_IS_BIG_ENDIAN
hosttype = sparcSolaris
endif
endif
# Test for SunOS 4.xx
# At Waterloo: descartes,cayley,napier,....
# If SunOS, we assume we are on a SPARC, which is not necessarily
# a good assumption outside of MFCF
ifeq ($(osname),SunOS)
ifeq ($(osrelease),4.1.3_U1)
HOSTCFLAGS = -DHOST_IS_BIG_ENDIAN
hosttype = sparcSunOS
endif
endif
# Test for ULTRIX
# At Waterloo: cantor.math,noether.math
# Assume ULTRIX on a MIPS architecture
ifeq ($(osname),ULTRIX)
HOSTCFLAGS =
hosttype = mipsUltrix
endif
# Note:
# If you are trying to build on Linux on an x86
# try something like this, substituting whatever
# uname -s returns on your machine for the XXX
#
ifeq ($(osname),Linux)
HOSTCFLAGS =
hosttype = x86Linux
endif
ifeq ($(osname),CYGWIN_NT-5.1)
HOSTCFLAGS =
hosttype = x86Linux
endif

49
coff2noff/coff.h Normal file
View File

@@ -0,0 +1,49 @@
/* coff.h
* Data structures that describe the MIPS COFF format.
*/
struct filehdr {
unsigned short f_magic; /* magic number */
unsigned short f_nscns; /* number of sections */
long f_timdat; /* time & date stamp */
long f_symptr; /* file pointer to symbolic header */
long f_nsyms; /* sizeof(symbolic hdr) */
unsigned short f_opthdr; /* sizeof(optional hdr) */
unsigned short f_flags; /* flags */
};
#define MIPSELMAGIC 0x0162
#define OMAGIC 0407
#define SOMAGIC 0x0701
typedef struct aouthdr {
short magic; /* see above */
short vstamp; /* version stamp */
long tsize; /* text size in bytes, padded to DW bdry*/
long dsize; /* initialized data " " */
long bsize; /* uninitialized data " " */
long entry; /* entry pt. */
long text_start; /* base of text used for this file */
long data_start; /* base of data used for this file */
long bss_start; /* base of bss used for this file */
long gprmask; /* general purpose register mask */
long cprmask[4]; /* co-processor register masks */
long gp_value; /* the gp value used for this object */
} AOUTHDR;
#define AOUTHSZ sizeof(AOUTHDR)
struct scnhdr {
char s_name[8]; /* section name */
long s_paddr; /* physical address, aliased s_nlib */
long s_vaddr; /* virtual address */
long s_size; /* section size */
long s_scnptr; /* file ptr to raw data for section */
long s_relptr; /* file ptr to relocation */
long s_lnnoptr; /* file ptr to gp histogram */
unsigned short s_nreloc; /* number of relocation entries */
unsigned short s_nlnno; /* number of gp histogram entries */
long s_flags; /* flags */
};

300
coff2noff/coff2noff.c Normal file
View File

@@ -0,0 +1,300 @@
/* coff2noff.c
*
* This program reads in a COFF format file, and outputs a NOFF format file.
* The NOFF format is essentially just a simpler version of the COFF file,
* recording where each segment is in the NOFF file, and where it is to
* go in the virtual address space.
*
* Assumes coff file is linked with either
* gld with -N -Ttext 0
* ld with -N -T 0
* to make sure the object file has no shared text.
*
* Also assumes that the COFF file has at most 3 segments:
* .text -- read-only executable instructions
* .data -- initialized data
* .bss/.sbss -- uninitialized data (should be zero'd on program startup)
#ifdef RDATA
* .rdata -- read-only data (e.g., string literals).
* mark this segment readonly to prevent it from being modified
#endif
*
*
* Copyright (c) 1992-1993 The Regents of the University of California.
* All rights reserved. See copyright.h for copyright notice and limitation
* of liability and disclaimer of warranty provisions.
*/
/*
* Modified at UW by KMS, August, 1997
* The modified program always writes the NOFF header in little-endian
* format, rather than host format. This is to avoid the problem
* that user programs run through coff2noff on a big-endian host
* would not run properly on Nachos machines running on little-endian
* hosts.
*
* Note that the Nachos address space loading code
* (in AddrSpace::Load) on big-endian hosts converts the header
* to big-endian format when it is read in.
* Thus, the little-endian header NOFF
* header should work OK whether Nachos is running on a little-endian
* host or a big-endian host.
*/
#define MAIN
#include "copyright.h"
#undef MAIN
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "coff.h"
#include "noff.h"
/****************************************************************/
/* Routines for converting words and short words to and from the
* simulated machine's format of little endian. These end up
* being NOPs when the host machine is little endian.
*/
unsigned int
WordToHost(unsigned int word) {
#ifdef HOST_IS_BIG_ENDIAN
register unsigned long result;
result = (word >> 24) & 0x000000ff;
result |= (word >> 8) & 0x0000ff00;
result |= (word << 8) & 0x00ff0000;
result |= (word << 24) & 0xff000000;
return result;
#else
return word;
#endif /* HOST_IS_BIG_ENDIAN */
}
unsigned short
ShortToHost(unsigned short shortword) {
#if HOST_IS_BIG_ENDIAN
register unsigned short result;
result = (shortword << 8) & 0xff00;
result |= (shortword >> 8) & 0x00ff;
return result;
#else
return shortword;
#endif /* HOST_IS_BIG_ENDIAN */
}
unsigned int
WordToMachine(unsigned int word) { return WordToHost(word); }
unsigned short
ShortToMachine(unsigned short shortword) { return ShortToHost(shortword); }
// this routine was borrowed from userprog/addrspace.cc
// on a big-endian machine, it converts all fields of
// the NOFF header to little-endian format
// on a little-endian machine, where the header is already
// in little-endian format, it does nothing
static void
SwapHeader (NoffHeader *noffH)
{
noffH->noffMagic = WordToHost(noffH->noffMagic);
noffH->code.size = WordToHost(noffH->code.size);
noffH->code.virtualAddr = WordToHost(noffH->code.virtualAddr);
noffH->code.inFileAddr = WordToHost(noffH->code.inFileAddr);
#ifdef RDATA
noffH->readonlyData.size = WordToHost(noffH->readonlyData.size);
noffH->readonlyData.virtualAddr =
WordToHost(noffH->readonlyData.virtualAddr);
noffH->readonlyData.inFileAddr =
WordToHost(noffH->readonlyData.inFileAddr);
#endif
noffH->initData.size = WordToHost(noffH->initData.size);
noffH->initData.virtualAddr = WordToHost(noffH->initData.virtualAddr);
noffH->initData.inFileAddr = WordToHost(noffH->initData.inFileAddr);
noffH->uninitData.size = WordToHost(noffH->uninitData.size);
noffH->uninitData.virtualAddr = WordToHost(noffH->uninitData.virtualAddr);
noffH->uninitData.inFileAddr = WordToHost(noffH->uninitData.inFileAddr);
}
/****************************************************************/
#define ReadStruct(f,s) Read(f,(char *)&s,sizeof(s))
char *noffFileName = NULL;
/* read and check for error */
void Read(int fd, char *buf, int nBytes)
{
if (read(fd, buf, nBytes) != nBytes) {
fprintf(stderr, "File is too short\n");
unlink(noffFileName);
exit(1);
}
}
/* write and check for error */
void Write(int fd, char *buf, int nBytes)
{
if (write(fd, buf, nBytes) != nBytes) {
fprintf(stderr, "Unable to write file\n");
unlink(noffFileName);
exit(1);
}
}
int main(int argc, char **argv)
{
int fdIn, fdOut, numsections, i, inNoffFile;
struct filehdr fileh;
struct aouthdr systemh;
struct scnhdr *sections;
char *buffer;
NoffHeader noffH;
if (argc < 2) {
fprintf(stderr, "Usage: %s <coffFileName> <noffFileName>\n", argv[0]);
exit(1);
}
/* open the COFF file (input) */
fdIn = open(argv[1], O_RDONLY, 0);
if (fdIn == -1) {
perror(argv[1]);
exit(1);
}
/* open the NOFF file (output) */
fdOut = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC , 0666);
if (fdIn == -1) {
perror(argv[2]);
exit(1);
}
noffFileName = argv[2];
/* Read in the file header and check the magic number. */
ReadStruct(fdIn,fileh);
fileh.f_magic = ShortToHost(fileh.f_magic);
fileh.f_nscns = ShortToHost(fileh.f_nscns);
if (fileh.f_magic != MIPSELMAGIC) {
fprintf(stderr, "File is not a MIPSEL COFF file\n");
unlink(noffFileName);
exit(1);
}
/* Read in the system header and check the magic number */
ReadStruct(fdIn,systemh);
systemh.magic = ShortToHost(systemh.magic);
if (systemh.magic != OMAGIC) {
fprintf(stderr, "File is not a OMAGIC file\n");
unlink(noffFileName);
exit(1);
}
/* Read in the section headers. */
numsections = fileh.f_nscns;
printf("numsections %d \n",numsections);
sections = (struct scnhdr *)malloc(numsections * sizeof(struct scnhdr));
Read(fdIn, (char *) sections, numsections * sizeof(struct scnhdr));
for (i = 0; i < numsections; i++) {
sections[i].s_paddr = WordToHost(sections[i].s_paddr);
sections[i].s_size = WordToHost(sections[i].s_size);
sections[i].s_scnptr = WordToHost(sections[i].s_scnptr);
}
/* initialize the NOFF header, in case not all the segments are defined
* in the COFF file
*/
noffH.noffMagic = NOFFMAGIC;
noffH.code.size = 0;
noffH.initData.size = 0;
noffH.uninitData.size = 0;
#ifdef RDATA
noffH.readonlyData.size = 0;
#endif
/* Copy the segments in */
inNoffFile = sizeof(NoffHeader);
lseek(fdOut, inNoffFile, 0);
printf("Loading %d sections:\n", numsections);
for (i = 0; i < numsections; i++) {
printf("\t\"%s\", filepos 0x%x, mempos 0x%x, size 0x%x\n",
sections[i].s_name, (unsigned int)sections[i].s_scnptr,
(unsigned int)sections[i].s_paddr, (unsigned int)sections[i].s_size);
if (sections[i].s_size == 0) {
/* do nothing! */
} else if (!strcmp(sections[i].s_name, ".text")) {
noffH.code.virtualAddr = sections[i].s_paddr;
noffH.code.inFileAddr = inNoffFile;
noffH.code.size = sections[i].s_size;
lseek(fdIn, sections[i].s_scnptr, 0);
buffer = malloc(sections[i].s_size);
Read(fdIn, buffer, sections[i].s_size);
Write(fdOut, buffer, sections[i].s_size);
free(buffer);
inNoffFile += sections[i].s_size;
} else if (!strcmp(sections[i].s_name, ".data")){
noffH.initData.virtualAddr = sections[i].s_paddr;
noffH.initData.inFileAddr = inNoffFile;
noffH.initData.size = sections[i].s_size;
lseek(fdIn, sections[i].s_scnptr, 0);
buffer = malloc(sections[i].s_size);
Read(fdIn, buffer, sections[i].s_size);
Write(fdOut, buffer, sections[i].s_size);
free(buffer);
inNoffFile += sections[i].s_size;
#ifdef RDATA
} else if (!strcmp(sections[i].s_name, ".rdata")){
noffH.readonlyData.virtualAddr = sections[i].s_paddr;
noffH.readonlyData.inFileAddr = inNoffFile;
noffH.readonlyData.size = sections[i].s_size;
lseek(fdIn, sections[i].s_scnptr, 0);
buffer = malloc(sections[i].s_size);
Read(fdIn, buffer, sections[i].s_size);
Write(fdOut, buffer, sections[i].s_size);
free(buffer);
inNoffFile += sections[i].s_size;
#endif
} else if (!strcmp(sections[i].s_name, ".bss")){
/* need to check if we have both .bss and .sbss -- make sure they
* are contiguous
*/
if (noffH.uninitData.size != 0) {
if (sections[i].s_paddr == (noffH.uninitData.virtualAddr +
noffH.uninitData.size)) {
fprintf(stderr, "Can't handle both bss and sbss\n");
unlink(noffFileName);
exit(1);
}
noffH.uninitData.size += sections[i].s_size;
} else {
noffH.uninitData.virtualAddr = sections[i].s_paddr;
noffH.uninitData.size = sections[i].s_size;
}
/* we don't need to copy the uninitialized data! */
} else {
fprintf(stderr, "Unknown segment type: %s\n", sections[i].s_name);
unlink(noffFileName);
exit(1);
}
}
lseek(fdOut, 0, 0);
// convert the NOFF header to little-endian before
// writing it to the file
SwapHeader(&noffH);
Write(fdOut, (char *)&noffH, sizeof(NoffHeader));
close(fdIn);
close(fdOut);
exit(0);
}

BIN
coff2noff/coff2noff.o Normal file

Binary file not shown.

BIN
coff2noff/coff2noff.x86Linux Executable file

Binary file not shown.

24
coff2noff/copyright.h Normal file
View File

@@ -0,0 +1,24 @@
/*
Copyright (c) 1992-1996 The Regents of the University of California.
All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without written agreement is
hereby granted, provided that the above copyright notice and the following
two paragraphs appear in all copies of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifdef MAIN /* include the copyright message in every executable */
static char *copyright = "Copyright (c) 1992-1993 The Regents of the University of California. All rights reserved.";
#endif // MAIN

28
coff2noff/noff.h Normal file
View File

@@ -0,0 +1,28 @@
/* noff.h
* Data structures defining the Nachos Object Code Format
*
* Basically, we only know about three types of segments:
* code (read-only), initialized data, and unitialized data
*/
#define NOFFMAGIC 0xbadfad /* magic number denoting Nachos
* object code file
*/
typedef struct segment {
int virtualAddr; /* location of segment in virt addr space */
int inFileAddr; /* location of segment in this file */
int size; /* size of segment */
} Segment;
typedef struct noffHeader {
int noffMagic; /* should be NOFFMAGIC */
Segment code; /* executable code segment */
Segment initData; /* initialized data segment */
#ifdef RDATA
Segment readonlyData; /* read only data */
#endif
Segment uninitData; /* uninitialized data segment --
* should be zero'ed before use
*/
} NoffHeader;