20 Commits

Author SHA1 Message Date
745732f9e0 works better, but weird failures 2018-03-25 23:02:18 +02:00
9b46824596 Create README.md 2018-03-25 23:02:18 +02:00
b08f83a54b Remove unncessary variable definitions 2018-03-25 23:02:18 +02:00
648fa467d6 ARM: Compile whole tree with clang.
Note: GCC is still the default compiler, to use clang do the following:

 $ BUILDVARS="" ./releasetools/arm_sdimage.sh
2018-03-25 23:02:17 +02:00
40308cd1ed ARM: Remove linker script for VM.
The linker script has been replaced by small adaptations to make sure
the required structures are aligned at runtime per hardware
requirements.

In some cases, the linker script failed to guarantee proper physical
addresses alignement.

This is important for page entries descriptors which are required to be
aligned as the MMU doesn't support unaligned accesses to those.

Change-Id: I3e22d3da102230be2534b4261e2c6c937e367de6
2018-03-25 23:02:17 +02:00
Arne Welzel
35b65c5af1 minix/tests/arm: naive tests to cause data aborts
Some assembly code to cause unaligned access as well as
segmentation faults to exercise the data abort path.

Change-Id: Ie419114b76a8db849537a94fda781019cf14d50d
2018-03-25 17:44:11 +02:00
Arne Welzel
0dd719f1bd kernel/arm: send SIGSEGV to processes
On second thought, handle unknown faults caused by processes by sending
SIGSEGV to them instead of bringing the whole system to a grind.

arm/archconst: use values defined in armreg.h

Change-Id: Ieed5bb06910ab0c8eef1e68b0b4eec680867acd3
2018-03-25 15:16:29 +02:00
Arne Welzel
5e9e5b98f6 bsd.own.mk: use -mno-unaligned-access on ARM
Without this option, gcc may emit code accessing unaligned memory. This,
and the fact that SCTRL.A (System Control Register - Alignment Check) is
set to 1 in Minix causes data aborts when such code is encountered.

This was the cause of #104. The `minix-service' executable caused
unaligned memory accesses calling into getpwnam(). These then trigger
data abort exceptions. On ARM, these were previously forwarded to `vm'
as pagefaults. However, `vm' did not properly handle them, but instead
allocated one page for the faulting address (over and over again) and
then resumed the process at the faulting instruction (over and over
again). This behavior masked the whole story as an OOM.

Below the assembly version getpwent.c in which unaligned memory
accesses are even highlighted...

 ...
 341         ldr     lr, [sp, #48]
 342         cmp     lr, #0
 343         bne     .L46
 344         ldr     r0, [r4]        @ unaligned
 345         add     r1, r7, #5
 346         str     r0, [sp, #4]    @ unaligned
 347         ldr     r4, [sp, #4]
 348         mov     r5, r4, asr #31
 349         strd    r4, [r8, #40]
 ...

This should fix #104. It was tested on an actual Beaglebone Black.

An alternative fix would be to disable alignment checking by setting
SCTRL.A to 0 and allowing unaligned memory accesses.

Change-Id: I4d366eb0af1b2936bca369fd28014fb829228ad5
2018-03-25 11:23:21 +02:00
Arne Welzel
7c3424c244 kernel/arm: do not treat all data aborts as pagefaults
For now, distinguish alignment, translation and permission faults.
The first kind of faults cause the kernel to send SIGBUS to the
process causing the fault, the latter two are forwarded to `vm' as
pagefaults. Previously, any data abort was forwarded to `vm' as
a pagefault, resulting in hard to debug issue #104.

Any unhandled fault status results in a disaster. This seems
better than naively hoping `vm' can do something about it.

Change-Id: I526f575bb2681e087e20fd49c5c0846cdd450c31
2018-03-25 11:22:35 +02:00
Marcelo Alencar
a27e58e1f7 Fix brazilian ABNT2 keymap
This adds two missing keys (0x73 and 0x7e) and fixes KP_PERIOD (it
should type a comma, not a period), as mentioned in

https://groups.google.com/d/msg/minix3/Pezep_HOL3I/mnfZXAeLsTMJ

Closes #247

Change-Id: Id85d04e36adcaa1a502cac8e5013396ea92502fe
2018-03-23 07:38:56 +01:00
blackdragonepic
4667c87c4d remove a duplicate include
removed #include <minix/type.h> duplicate

Closes #246

Change-Id: Icd575c452d562eb601133157a77d9d995ce043e9
2018-03-23 07:38:25 +01:00
Nik Nyby
2117e99cef Update usage man page: remove reference to /usr/ast
This directory no longer exists, probably since the netbsd file layout
re-organization.

Closes #244

Change-Id: Ie4e3761dbf3adbdd76cb6323f920a4abab6b29d5
2018-03-23 07:37:54 +01:00
Nik Nyby
9866ad31fd fs/mfs: Remove a few assert.h includes
Those are unnecessary.

Closes #241

Change-Id: I26db0f07c65e7d078e642001b97e6d4313e6660a
2018-03-23 07:36:59 +01:00
Nik Nyby
24f3305be0 mkfs.mfs: fix typo in error message
Closes #242

Change-Id: I91ec2b36b2abfa897a43c97d886578fd28a5c768
2018-03-23 07:33:25 +01:00
Krystian Lewandowski
b2ee0702ff pci server crashes during boot on Qubes OS
I tried to launch Minix3 in Qubes OS. While there is no problem to boot
minix as a qube (in Qubes OS terminology) before 3641562, it fails with
the commit (and after). I didn't digg into PCI handling but this change
fixes the problem. Minix handles NULL case from pci_subclass_name.

Change-Id: I162424d92b613598e6eb845a71f90a02e31041db
2017-11-16 23:05:02 +01:00
Jean-Baptiste Boric
39d31d9fab ARM: Remove dependency on mtools
Instead of formatting the image, and then using the mtools to copy on it
the boot partition files, we use makefs to directly generate the
partition.

Change-Id: I468e3100842177f3f55edbfdb910941bafa576ba
2017-07-12 08:20:16 +02:00
rlfnb
b67d2ae9e2 Fixed broken multiboot struct
Change-Id: Ib59fb04a45c4417588bf204a5a6e6306f5097e22
2017-07-12 07:40:10 +02:00
rlfnb
d4dd6511b9 replace tickdelay with micro_delay to be quantum-agnostic
Change-Id: Ie449d797389a178372035d797c84b02d636788cd
2017-06-01 19:48:56 +02:00
David van Moolenbroek
3e2c6c9674 isofs: support directories with many entries
In particular, remove the hardcoded limit of 4096 entries in a single
directory, as there are (at least) real DVDs out there with more
entries than that.  The implementation of this change requires a
second pass on large directories; performance optimizations are left
to future work.

Change-Id: Ia865ac95797fa2dd36b086779c3f1fef6b2f6a6f
2017-05-17 23:25:11 +00:00
David van Moolenbroek
502e7ff953 at_wini: bump hardcoded ATAPI limit to DVD size
at_wini was previously hardcoded to present ATAPI devices as having a
size of 800 MiB, which was enough for CDs but not for DVDs.  This
patch increases the device size to 8500 MiB, which should be large
enough to cover all DVDs.

Change-Id: I7d3192e4ecd0708a655663c1007ff517ed969580
2017-05-17 23:16:52 +00:00
43 changed files with 483 additions and 437 deletions

17
README.md Normal file
View File

@@ -0,0 +1,17 @@
# Build MINIX/arm with clang
It is now possible to build a full minix distribution for BeaglBone White/Black and BeagleBoardxM using clang instead of GCC.
This also add support to run the Kuya tests on ARM, which was not possible when GCC was used, because of problems in the C++ exception handling.
## Known Bugs
The following tests still fails:
1. 53: Division by zero does not trigger exceptions
2. 75: ru.tv_secs can't be zero (and is zero)
3. 85: hangs
4. isofs: Fails because of an out of memory condition
5. vnd: crash
6. Running two times the kyua tests in a row, without rebooting in between will lead to a mostly failed second run because of copy-on-write errors.

View File

@@ -81,6 +81,9 @@
./usr/include/arm/vm.h minix-comp
./usr/include/arm/vmparam.h minix-comp
./usr/include/arm/wchar_limits.h minix-comp
./usr/include/clang-3.6/arm_acle.h minix-comp llvm,llvmcmds
./usr/include/clang-3.6/arm_neon.h minix-comp llvm,llvmcmds
./usr/include/clang-3.6/stdatomic.h minix-comp llvm,llvmcmds
./usr/include/evbarm minix-comp
./usr/include/evbarm/disklabel.h minix-comp
./usr/include/evbarm/intr.h minix-comp

View File

@@ -0,0 +1,9 @@
#
# Sorted using sort_set.pl in releasetools.
# to add an entry simply add it at the end of the
# file and run
# ../../../../releasetools/sort_set.pl < mi > out
# mv out mi
#
./usr/tests/minix-posix/test_arm_segfault minix-tests
./usr/tests/minix-posix/test_arm_unaligned minix-tests

View File

@@ -3816,6 +3816,7 @@ class ARMTargetInfo : public TargetInfo {
SizeType = UnsignedInt;
switch (T.getOS()) {
case llvm::Triple::Minix:
case llvm::Triple::NetBSD:
WCharType = SignedInt;
break;

View File

@@ -275,7 +275,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
// FIXME: Thumb should just be another -target-feaure, not in the triple.
#if defined(__minix) || 1
// Minix/ARM-specific force to ARMv7 and EABI.
StringRef Suffix = "v7";
StringRef Suffix = "v7a";
Triple.setEnvironment(llvm::Triple::EABI);
#else
StringRef Suffix = Triple.isOSBinFormatMachO()

View File

@@ -665,6 +665,10 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
}
break;
case llvm::Triple::Minix:
FloatABI = "softfp";
break;
default:
switch(Triple.getEnvironment()) {
case llvm::Triple::GNUEABIHF:
@@ -796,6 +800,9 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
ABIName = "aapcs";
break;
default:
if (Triple.getOS() == llvm::Triple::Minix)
ABIName = "apcs-gnu";
if (Triple.getOS() == llvm::Triple::NetBSD)
ABIName = "apcs-gnu";
else
@@ -7733,6 +7740,11 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
// Many NetBSD architectures support more than one ABI.
// Determine the correct emulation for ld.
switch (getToolChain().getArch()) {
case llvm::Triple::arm:
case llvm::Triple::thumb:
CmdArgs.push_back("-m");
CmdArgs.push_back("armelf_minix");
break;
case llvm::Triple::x86:
CmdArgs.push_back("-m");
CmdArgs.push_back("elf_i386_minix");

View File

@@ -638,6 +638,8 @@ llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
if (!KernelZeroFlagVal.hasValue()) {
if (OS == llvm::Triple::FreeBSD)
KernelZeroFlagVal = 0x0100;
else if (OS == llvm::Triple::Minix)
KernelZeroFlagVal = 0x0002;
else if (OS == llvm::Triple::NetBSD)
KernelZeroFlagVal = 0x0002;
else if (OS == llvm::Triple::OpenBSD)

View File

@@ -1074,6 +1074,8 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
// supported by LLVM.
// FIXME: Should warn once that we're falling back.
switch (getOS()) {
case llvm::Triple::Minix:
return "cortex-a8";
case llvm::Triple::NetBSD:
switch (getEnvironment()) {
case llvm::Triple::GNUEABIHF:

View File

@@ -59,6 +59,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo(StringRef TT) {
// Exceptions handling
switch (TheTriple.getOS()) {
case Triple::Minix:
case Triple::NetBSD:
ExceptionsType = ExceptionHandling::DwarfCFI;
break;

View File

@@ -26,7 +26,6 @@ extern u32_t system_hz;
static void el2_init(dpeth_t *dep);
static void el2_stop(dpeth_t *dep);
static void milli_delay(unsigned long millis);
/*===========================================================================*
* el2_init *
@@ -154,9 +153,9 @@ dpeth_t * dep;
/* Resets board */
outb_el2(dep, EL2_CNTR, ECNTR_RESET | thin);
milli_delay(1);
micro_delay(1000);
outb_el2(dep, EL2_CNTR, thin);
milli_delay(5);
micro_delay(5000);
/* Map the address PROM to lower I/O address range */
outb_el2(dep, EL2_CNTR, ECNTR_SAPROM | thin);
@@ -184,11 +183,6 @@ dpeth_t * dep;
return 1;
}
static void milli_delay(unsigned long millis)
{
tickdelay(MILLIS_TO_TICKS(millis));
}
#endif /* ENABLE_3C503 */
/** 3c503.c **/

View File

@@ -32,7 +32,6 @@ static u8_t pat3[]= { 0x96, 0x69, 0x5A, 0xA5 };
static int test_8(dpeth_t *dep, int pos, u8_t *pat);
static int test_16(dpeth_t *dep, int pos, u8_t *pat);
static void ne_stop(dpeth_t *dep);
static void milli_delay(unsigned long millis);
/*===========================================================================*
* ne_probe *
@@ -56,9 +55,9 @@ int ne_probe(dpeth_t *dep)
{
/* Reset the ethernet card */
byte= inb_ne(dep, NE_RESET);
milli_delay(2);
micro_delay(2000);
outb_ne(dep, NE_RESET, byte);
milli_delay(2);
micro_delay(2000);
/* Reset the dp8390 */
outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
@@ -310,15 +309,10 @@ dpeth_t *dep;
/* Reset the ethernet card */
byte= inb_ne(dep, NE_RESET);
milli_delay(2);
micro_delay(2000);
outb_ne(dep, NE_RESET, byte);
}
static void milli_delay(unsigned long millis)
{
tickdelay(MILLIS_TO_TICKS(millis));
}
#endif /* ENABLE_NE2000 */
/*

View File

@@ -239,7 +239,7 @@ e1000_reset_hw(e1000_t * e)
e1000_reg_set(e, E1000_REG_CTRL, E1000_REG_CTRL_RST);
/* Wait one microsecond. */
tickdelay(1);
micro_delay(16000);
}
/*
@@ -792,7 +792,7 @@ eeprom_ich_init(e1000_t * e)
ret_val = 0;
break;
}
tickdelay(1);
micro_delay(16000);
}
if (ret_val == 0) {
/*
@@ -834,7 +834,7 @@ eeprom_ich_cycle(e1000_t * e, u32_t timeout)
hsfsts.regval = E1000_READ_FLASH_REG16(e, ICH_FLASH_HSFSTS);
if (hsfsts.hsf_status.flcdone == 1)
break;
tickdelay(1);
micro_delay(16000);
} while (i++ < timeout);
if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0)
@@ -867,7 +867,7 @@ eeprom_ich(e1000_t * e, int reg)
e->flash_base_addr;
do {
tickdelay(1);
micro_delay(16000);
/* Steps */
ret_val = eeprom_ich_init(e);

View File

@@ -607,7 +607,7 @@ fxp_t *fp;
/* Reset device */
fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
tickdelay(micros_to_ticks(CSR_PORT_RESET_DELAY));
micro_delay(CSR_PORT_RESET_DELAY);
/* Disable interrupts */
fxp_outb(port, SCB_INT_MASK, SIM_M);

View File

@@ -655,7 +655,7 @@ lan8710a_init_hw(netdriver_addr_t * addr, unsigned int instance)
LAN8710A_DEBUG_PRINT(("Autonegotiation failed"));
break;
}
tickdelay(100);
micro_delay(1666666);
}
/* GMII RX and TX release from reset. */

View File

@@ -1729,8 +1729,9 @@ static int atapi_open(void)
/* Should load and lock the device and obtain its size. For now just set the
* size of the device to something big. What is really needed is a generic
* SCSI layer that does all this stuff for ATAPI and SCSI devices (kjb). (XXX)
* .."something big" is now the maximum size of the largest type of DVD.
*/
w_wn->part[0].dv_size = (u64_t)(800L*1024) * 1024;
w_wn->part[0].dv_size = (u64_t)(8500L*1024) * 1024;
return(OK);
}

View File

@@ -53,7 +53,7 @@
K(GRAVE_ACCENT) = { '\'', '"', A('\''),A('\''),A('"'), C('@') },
K(COMMA) = { ',', '<', A(','), A(','), A('<'), C('@') },
K(PERIOD) = { '.', '>', A('.'), A('.'), A('>'), C('@') },
K(SLASH) = { 59, 58, A(59), A(58), A(59), C('@') },
K(SLASH) = { ';', ':', A(';'), A(';'), A(':'), C('@') },
K(CAPS_LOCK) = { CALOCK, CALOCK, CALOCK, CALOCK, CALOCK, CALOCK },
K(F1) = { F1, SF1, AF1, AF1, ASF1, CF1 },
K(F2) = { F2, SF2, AF2, AF2, ASF2, CF2 },
@@ -94,10 +94,11 @@
K(KP_8) = { NUP, '8', AUP, AUP, A('8'), CUP },
K(KP_9) = { NPGUP, '9', APGUP, APGUP, A('9'), CPGUP },
K(KP_0) = { NINSRT, '0', AINSRT, AINSRT, A('0'), CINSRT },
K(KP_PERIOD) = { NDEL, '.', A(DEL), A(DEL), A('.'), DEL },
K(KP_PERIOD) = { NDEL, ',', A(DEL), A(DEL), A(','), DEL },
K(EUROPE_2) = { '\\', '|', A('\\'),A('|'), A('\\'),C('@') },
K(APPLICATION) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') },
K(KP_EQUAL) = { '?', 0, 0, 0, 0, 0 },
K(I10L_1) = { '/', '?', A('/'), A('/'), A('?'), C('@') },
K(EQUAL_SIGN) = { '.', '.', 0, 0, 0, 0 },
K(SYSREQ) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') },
K(LEFT_CTRL) = { LCTRL, LCTRL, LCTRL, LCTRL, LCTRL, LCTRL },
K(LEFT_SHIFT) = { LSHIFT, LSHIFT, LSHIFT, LSHIFT, LSHIFT, LSHIFT },

View File

@@ -100,11 +100,11 @@ void dup_inode(struct inode *i_node) {
}
int read_directory(struct inode *dir) {
#define MAX_ENTRIES 4096
#define MAX_ENTRIES 256 /* avoid using lots of stack.. */
/* Read all entries in a directory. */
size_t pos = 0, cur_entry = 0, cpt;
struct inode_dir_entry entries[MAX_ENTRIES];
int status = OK;
size_t pos = 0, saved_pos, cur_entry, num_entries, cpt;
struct inode_dir_entry entries[MAX_ENTRIES + 1];
int status;
if (dir->dir_contents)
return OK;
@@ -112,27 +112,88 @@ int read_directory(struct inode *dir) {
if (!S_ISDIR(dir->i_stat.st_mode))
return ENOTDIR;
for (cur_entry = 0; status == OK && cur_entry < MAX_ENTRIES; cur_entry++) {
memset(&entries[cur_entry], 0, sizeof(struct inode_dir_entry));
status = read_inode(&entries[cur_entry], &dir->extent, &pos);
if (status != OK)
break;
/*
* We do not know how many inode entries we will find, but we want to
* allocate an array of the right size for dir->dir_contents. First
* find out how many entries there are, and store up to MAX_ENTRIES of
* them into a temporary array on the stack. If there are more than
* MAX_ENTRIES entries, we have to do a second pass on the part of the
* directory that we did not manage to fit in the temporary array.
*
* The entire service needs massive structural improvement (and in
* particular, no dynamic memory allocation like this), but for now
* this is the simplest way to be fast for small directories while at
* the same time supporting seriously large directories.
*/
cur_entry = 0;
num_entries = 0;
while ((status = read_inode(&entries[cur_entry], &dir->extent,
&pos)) == OK) {
/* Dump the entry if it's not to be exported to userland. */
if (entries[cur_entry].i_node->skip) {
free_inode_dir_entry(&entries[cur_entry]);
continue;
}
if (cur_entry < MAX_ENTRIES) {
cur_entry++;
/*
* As long as more entries fit in the temporary array,
* update the saved position of the next entry. Once
* we hit the first entry that does not fit (if any),
* the updating stops and we will have the correct
* saved position.
*/
saved_pos = pos;
} else {
/*
* No room in the temporary array. Free the entry
* again. This is costly but only for those rare
* directories that have more than MAX_ENTRIES entries.
*/
free_inode_dir_entry(&entries[cur_entry]);
}
num_entries++;
}
/* Resize dynamic array to correct size */
dir->dir_contents = alloc_mem(sizeof(struct inode_dir_entry) * cur_entry);
memcpy(dir->dir_contents, entries, sizeof(struct inode_dir_entry) * cur_entry);
dir->dir_size = cur_entry;
/*
* Allocate a dynamic array of the correct size, and populate it with
* all the entries in the temporary array. For large directories, the
* temporary array will have partial results, in which case we have to
* do a second pass on the rest below.
*/
dir->dir_contents =
alloc_mem(sizeof(struct inode_dir_entry) * num_entries);
memcpy(dir->dir_contents, entries,
sizeof(struct inode_dir_entry) * cur_entry);
/*
* The second pass. This pass starts from the saved position and reads
* only the entries that did not fit in the temporary array. This time
* we can read straight into the actual destination array. We expect
* to find the same entries as during the first pass.
*/
while (cur_entry < num_entries) {
if (read_inode(&dir->dir_contents[cur_entry], &dir->extent,
&saved_pos) != OK)
panic("unexpected EOF or error rereading directory");
if (dir->dir_contents[cur_entry].i_node->skip) {
free_inode_dir_entry(&entries[cur_entry]);
continue;
}
cur_entry++;
}
dir->dir_size = num_entries;
/* The name pointer has to point to the new memory location. */
for (cpt = 0; cpt < cur_entry; cpt++) {
for (cpt = 0; cpt < num_entries; cpt++) {
if (dir->dir_contents[cpt].r_name == NULL)
dir->dir_contents[cpt].name =
dir->dir_contents[cpt].i_name;
@@ -202,6 +263,8 @@ int read_inode(struct inode_dir_entry *dir_entry, struct dir_extent *extent,
*offset % v_pri.logical_block_size_l;
}
memset(dir_entry, 0, sizeof(*dir_entry));
i_node = inode_cache_get(ino_nr);
if (i_node) {
/* Inode was already loaded, parse file names only. */

View File

@@ -60,7 +60,6 @@ static int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf)
if (root_record->data_length_l % vol_pri->logical_block_size_l)
extent.length++;
memset(&dir_entry, 0, sizeof(struct inode_dir_entry));
if (read_inode(&dir_entry, &extent, &dummy_offset) != OK) {
return EINVAL;
}

View File

@@ -38,6 +38,7 @@ void parse_susp_rock_ridge_plcl(struct rrii_dir_record *dir, u32_t block) {
lmfs_put_block(bp);
memset(&dummy_dir_entry, 0, sizeof(struct inode_dir_entry));
/* XXX what if this fails? */
read_inode(&dummy_dir_entry, &extent, &dummy_offset);
free(dummy_dir_entry.r_name);
dir->reparented_inode = dummy_dir_entry.i_node;

View File

@@ -1,7 +1,6 @@
#include "fs.h"
#include "inode.h"
#include "clean.h"
#include <assert.h>
/*===========================================================================*
* fs_sync *

View File

@@ -1,6 +1,5 @@
#include "fs.h"
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include "inode.h"

View File

@@ -5,11 +5,6 @@ PROG= kernel
BINDIR= /usr/sbin
MAN=
.if ${MACHINE_ARCH} == "earm" && ${MKLLVM:Uno} == "yes"
# BJG - problems with optimisation of the kernel by llvm
DBG=-O0
.endif
.include "arch/${MACHINE_ARCH}/Makefile.inc"
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \

View File

@@ -11,6 +11,7 @@
#include <machine/vm.h>
#include <machine/signal.h>
#include <arm/armreg.h>
#include <arm/vfpreg.h>
#include <minix/u64.h>
@@ -26,16 +27,36 @@
void * k_stacks;
#define VFP_COPROC 10
#define VFP_COPROC2 11
void fpu_init(void)
{
const char *model = NULL;
uint32_t cpu_media_and_vfp_features[2];
const uint32_t cpacr_vfp = CPACR_CPn(VFP_COPROC);
const uint32_t cpacr_vfp2 = CPACR_CPn(VFP_COPROC2);
/*
* We first need to enable access to the coprocessors.
*/
uint32_t cpacr = armreg_cpacr_read();
cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp);
cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2);
armreg_cpacr_write(cpacr);
isb();
/* Enable vfp/neon unit */
armreg_fpexc_write(VFP_FPEXC_EN);
}
void save_local_fpu(struct proc *pr, int retain)
{
}
void save_fpu(struct proc *pr)
void
save_fpu(struct proc *pr)
{
}

View File

@@ -109,6 +109,36 @@ static void pagefault( struct proc *pr,
return;
}
static void
data_abort(int is_nested, struct proc *pr, reg_t *saved_lr,
struct ex_s *ep, u32_t dfar, u32_t dfsr)
{
/* Extract fault status bit [0:3, 10] from DFSR */
u32_t fs = dfsr & 0x0F;
fs |= ((dfsr >> 6) & 0x10);
/* Translation and permission faults are handled as pagefaults. */
if (is_trans_fault(fs) || is_perm_fault(fs)) {
pagefault(pr, saved_lr, is_nested, dfar, dfsr);
} else if (!is_nested) {
/* A user process caused some other kind of data abort. */
int signum = SIGSEGV;
if (is_align_fault(fs)) {
signum = SIGBUS;
} else {
printf("KERNEL: unknown data abort by proc %d sending "
"SIGSEGV (dfar=0x%lx dfsr=0x%lx fs=0x%lx)\n",
proc_nr(pr), dfar, dfsr, fs);
}
cause_sig(proc_nr(pr), signum);
} else { /* is_nested */
printf("KERNEL: inkernel data abort - disaster (dfar=0x%lx "
"dfsr=0x%lx fs=0x%lx)\n", dfar, dfsr, fs);
inkernel_disaster(pr, saved_lr, ep, is_nested);
}
}
static void inkernel_disaster(struct proc *saved_proc,
reg_t *saved_lr, struct ex_s *ep,
int is_nested)
@@ -171,7 +201,7 @@ void exception_handler(int is_nested, reg_t *saved_lr, int vector)
}
if (vector == DATA_ABORT_VECTOR) {
pagefault(saved_proc, saved_lr, is_nested, read_dfar(), read_dfsr());
data_abort(is_nested, saved_proc, saved_lr, ep, read_dfar(), read_dfsr());
return;
}

View File

@@ -21,6 +21,16 @@
#define INTERRUPT_VECTOR 6
#define FAST_INTERRUPT_VECTOR 7
/* Data abort helper */
#define is_align_fault(fault_status) \
((fault_status) == FAULT_ALIGN_0)
#define is_trans_fault(fault_status) \
(((fault_status) == FAULT_TRANS_S) || ((fault_status) == FAULT_TRANS_P))
#define is_perm_fault(fault_status) \
(((fault_status) == FAULT_PERM_S) || ((fault_status) == FAULT_PERM_P))
/*
* defines how many bytes are reserved at the top of the kernel stack for global
* information like currently scheduled process or current cpu id

View File

@@ -876,11 +876,6 @@ When exiting MINIX running under DOS the Boot Monitor's
.B exit
command will return you to the DOS prompt. The Boot Monitor and MINIX
are together just a pretty big DOS program as far DOS is concerned.
.SH FILES
.TP 12
.B /usr/ast
Honorary home directory of Andrew S. Tanenbaum. Doubles as the place where
the default setup for a new user is found.
.SH "SEE ALSO"
.BR dosminix (8),
.BR monitor (8),

View File

@@ -13,7 +13,6 @@
#include <minix/callnr.h>
#include <minix/com.h>
#include <minix/ds.h>
#include <minix/type.h>
#include <minix/endpoint.h>
#include <minix/minlib.h>
#include <minix/type.h>

View File

@@ -8,10 +8,6 @@ SRCS= main.c alloc.c utility.c exit.c fork.c break.c \
mem_anon.c mem_directphys.c mem_anon_contig.c mem_shared.c \
mem_cache.c cache.c vfs.c mem_file.c fdref.c acl.c
.if ${MACHINE_ARCH} == "earm"
LDFLAGS+= -T ${.CURDIR}/arch/${MACHINE_ARCH}/vm.lds
.endif
.if ${MKPAE:Uno} != "no"
CPPFLAGS+= -DPAE=1
.endif

View File

@@ -1,249 +0,0 @@
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000);
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.dyn :
{
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
PROVIDE_HIDDEN (__rel_iplt_start = .);
*(.rel.iplt)
PROVIDE_HIDDEN (__rel_iplt_end = .);
PROVIDE_HIDDEN (__rela_iplt_start = .);
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
PROVIDE_HIDDEN (__rel_iplt_start = .);
PROVIDE_HIDDEN (__rel_iplt_end = .);
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
.rel.plt :
{
*(.rel.plt)
}
.rela.plt :
{
*(.rela.plt)
}
.init :
{
KEEP (*(.init))
} =0
.plt : { *(.plt) }
.iplt : { *(.iplt) }
.text :
{
*(.text.unlikely .text.*_unlikely)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
} =0
.fini :
{
KEEP (*(.fini))
} =0
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
PROVIDE_HIDDEN (__exidx_end = .);
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
.gcc_except_table.*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
/* XXX: align on page boundary */
/* . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));*/
. = ALIGN(4096);
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
/* XXX: no jcr, got, etc.
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
*/
.data :
{
__data_start = . ;
/* XXX: put pagetable data at beginning */
pagetable.o(.data)
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
/* XXX: 16KB align */
. = ALIGN(16384);
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
__bss_start = .;
__bss_start__ = .;
.bss :
{
/* XXX: put pagetable bss at beginning */
pagetable.o(.bss)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 32 / 8 : 1);
}
_bss_end__ = . ; __bss_end__ = . ;
. = ALIGN(32 / 8);
. = ALIGN(32 / 8);
__end__ = . ;
_end = .; PROVIDE (end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.stack 0x80000 :
{
_stack = .;
*(.stack)
}
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@@ -40,7 +40,7 @@ static struct pdm {
u32_t val;
phys_bytes phys;
u32_t *page_directories;
} pagedir_mappings[MAX_PAGEDIR_PDES];
} pagedir_mappings[MAX_PAGEDIR_PDES] __aligned(ARCH_PAGEDIR_SIZE);
static multiboot_module_t *kern_mb_mod = NULL;
static size_t kern_size = 0;
@@ -80,7 +80,7 @@ int missing_sparedirs = SPAREPAGEDIRS;
static struct {
void *pagedir;
phys_bytes phys;
} sparepagedirs[SPAREPAGEDIRS];
} sparepagedirs[SPAREPAGEDIRS] __aligned(ARCH_PAGEDIR_SIZE);
#define is_staticaddr(v) ((vir_bytes) (v) < VM_OWN_HEAPSTART)
@@ -109,7 +109,10 @@ static char static_sparepages[VM_PAGE_SIZE*STATIC_SPAREPAGES]
__aligned(VM_PAGE_SIZE);
#if defined(__arm__)
static char static_sparepagedirs[ARCH_PAGEDIR_SIZE*STATIC_SPAREPAGEDIRS + ARCH_PAGEDIR_SIZE] __aligned(ARCH_PAGEDIR_SIZE);
/* We need one ARCH_PAGEDIR_SIZE extra to be able to ensure the physical
* addresses are aligned on pagetables boundaries. Without this the MMU will
* fail to parse properly the L1 pagetables. */
static char static_sparepagedirs[ARCH_PAGEDIR_SIZE*(STATIC_SPAREPAGEDIRS+1)];
#endif
void pt_assert(pt_t *pt)
@@ -1091,9 +1094,6 @@ void pt_init(void)
int s, r, p;
phys_bytes phys;
vir_bytes sparepages_mem;
#if defined(__arm__)
vir_bytes sparepagedirs_mem;
#endif
static u32_t currentpagedir[ARCH_VM_DIR_ENTRIES];
int m = kernel_boot_info.kern_mod;
#if defined(__i386__)
@@ -1117,12 +1117,6 @@ void pt_init(void)
sparepages_mem = (vir_bytes) static_sparepages;
assert(!(sparepages_mem % VM_PAGE_SIZE));
#if defined(__arm__)
/* Get ourselves spare pagedirs. */
sparepagedirs_mem = (vir_bytes) static_sparepagedirs;
assert(!(sparepagedirs_mem % ARCH_PAGEDIR_SIZE));
#endif
/* Spare pages are used to allocate memory before VM has its own page
* table that things (i.e. arbitrary physical memory) can be mapped into.
* We get it by pre-allocating it in our bss (allocated and mapped in by
@@ -1132,20 +1126,40 @@ void pt_init(void)
#if defined(__arm__)
missing_sparedirs = 0;
assert(STATIC_SPAREPAGEDIRS <= SPAREPAGEDIRS);
for(s = 0; s < SPAREPAGEDIRS; s++) {
vir_bytes v = (sparepagedirs_mem + s*ARCH_PAGEDIR_SIZE);;
phys_bytes ph;
if((r=sys_umap(SELF, VM_D, (vir_bytes) v,
ARCH_PAGEDIR_SIZE, &ph)) != OK)
{
phys_bytes sparepagedirs_phys_mem;
uint32_t offset;
/* Get ourselves spare pagedirs. */
vir_bytes sparepagedirs_mem = (vir_bytes) static_sparepagedirs;
if ((r = sys_umap(SELF, VM_D, sparepagedirs_mem,
ARCH_PAGEDIR_SIZE * (STATIC_SPAREPAGEDIRS + 1),
&sparepagedirs_phys_mem)) != OK) {
panic("pt_init: sys_umap failed: %d", r);
if(s >= STATIC_SPAREPAGEDIRS) {
sparepagedirs[s].pagedir = NULL;
missing_sparedirs++;
continue;
}
sparepagedirs[s].pagedir = (void *) v;
sparepagedirs[s].phys = ph;
}
}
/* Align to ARCH_PAGEDIR_SIZE sparepagedirs_phys_mem &
* sparepagedirs_mem. */
offset = ARCH_PAGEDIR_SIZE -
(sparepagedirs_phys_mem % ARCH_PAGEDIR_SIZE);
sparepagedirs_phys_mem += offset;
sparepagedirs_mem += offset;
for(s = 0; s < SPAREPAGEDIRS; s++) {
vir_bytes v = (sparepagedirs_mem + s*ARCH_PAGEDIR_SIZE);
phys_bytes ph = (sparepagedirs_phys_mem + s*ARCH_PAGEDIR_SIZE);
#if 0
printf("sparepagedirs[%d] pagedir %p phys %p\n", s, v, ph);
#endif
if(s >= STATIC_SPAREPAGEDIRS) {
sparepagedirs[s].pagedir = NULL;
missing_sparedirs++;
continue;
}
sparepagedirs[s].pagedir = (void *) v;
sparepagedirs[s].phys = ph;
}
}
#endif
if(!(spare_pagequeue = reservedqueue_new(SPAREPAGES, 1, 1, 0)))

View File

@@ -126,6 +126,8 @@ PROGS+= test63 mod
OBJS.${o} += common.o
.endfor
.include "./arch/${MACHINE_ARCH}/Makefile.inc"
# LSC Make sure there is not leftover after a failed testrun
clean: .PHONY .MAKE
@rm -rf DIR*

View File

@@ -0,0 +1,7 @@
PROGS+= test_arm_segfault
PROGS+= test_arm_unaligned
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}
test_arm_segfault.o : test_arm_segfault.S
test_arm_unaligned.o : test_arm_unaligned.S

View File

@@ -0,0 +1,16 @@
.text
.global main
main:
push {lr}
ldr r0, =0xDEADBEE0 /* Hopefully this is not mapped... */
ldr r1, [r0]
ldr r0, =0x01010100 /* In case we survived, try something else */
ldr r1, [r0]
ldr r0, =msg
bl puts
mov r0, #0 /* test should check for non-zero exit code / signal */
pop {pc}
msg:
.ascii "ERROR - caused no segfault\n"

View File

@@ -0,0 +1,26 @@
.text
.global main
main:
push {lr}
mov r0, sp
/* This should work */
ldr r0, [sp]
/* Unalign it */
add r0, #2
/* Try a non-word aligned word-load, this may work if SCTRL.A == 0 */
ldr r1, [r0]
/* Load non-word aligned dword, should die even with SCTRL.A == 0 */
ldrd r2, r3, [r0]
ldr r0, =msg
bl puts
mov r0, #0 /* test should check for non-zero exit code / signal */
pop {pc}
msg:
.ascii "ERROR - caused no sigbus\n"

View File

View File

@@ -264,7 +264,7 @@ main(int argc, char *argv[])
/* Determine the size of the device if not specified as -b or proto. */
maxblocks = sizeup(argv[optind]);
if (bblocks != 0 && bblocks + fs_offset_blocks > maxblocks && !insertmode) {
errx(4, "Given size -b %d exeeds device capacity(%d)\n", bblocks, maxblocks);
errx(4, "Given size -b %d exceeds device capacity(%d)\n", bblocks, maxblocks);
}
if (argc - optind == 1 && bblocks == 0) {

View File

@@ -28,9 +28,6 @@ fi
: ${IMG=minix_arm_sd.img}
# ARM definitions:
: ${BUILDVARS=-V MKGCCCMDS=yes -V MKLLVM=no}
# These BUILDVARS are for building with LLVM:
#: ${BUILDVARS=-V MKLIBCXX=no -V MKKYUA=no -V MKATF=no -V MKLLVMCMDS=no}
: ${FAT_SIZE=$(( 10*(2**20) / 512))} # This is in sectors
# Beagleboard-xm
@@ -64,32 +61,8 @@ then
exit 1
fi
case $(uname -s) in
Darwin)
MKFS_VFAT_CMD=newfs_msdos
MKFS_VFAT_OPTS="-h 64 -u 32 -S 512 -s ${FAT_SIZE} -o 0"
;;
FreeBSD)
MKFS_VFAT_CMD=newfs_msdos
MKFS_VFAT_OPTS=
;;
*)
MKFS_VFAT_CMD=mkfs.vfat
MKFS_VFAT_OPTS=
;;
esac
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:${PATH}
for needed in mcopy dd ${MKFS_VFAT_CMD} git
do
if ! which $needed 2>&1 > /dev/null
then
echo "**Skipping image creation: missing tool '$needed'"
exit 1
fi
done
# we create a disk image of about 2 gig's
# for alignment reasons, prefer sizes which are multiples of 4096 bytes
: ${IMG_SIZE=$(( 2*(2**30) ))}
@@ -130,67 +103,9 @@ echo "Creating specification files..."
create_input_spec
create_protos "usr home"
#
# Create the FAT partition, which contains the bootloader files, kernel and modules
#
dd if=/dev/zero of=${WORK_DIR}/fat.img bs=512 count=1 seek=$(($FAT_SIZE -1)) 2>/dev/null
#
# Format the fat partition and put the bootloaders
# uEnv and the kernel command line in the FAT partition
#
${MKFS_VFAT_CMD} ${MKFS_VFAT_OPTS} ${WORK_DIR}/fat.img
#
# Download the stage 1 bootloader and u-boot
#
${RELEASETOOLSDIR}/fetch_u-boot.sh -o ${RELEASETOOLSDIR}/u-boot -n $U_BOOT_GIT_VERSION
cp ${RELEASETOOLSDIR}/u-boot/${U_BOOT_BIN_DIR}/MLO ${WORK_DIR}/
cp ${RELEASETOOLSDIR}/u-boot/${U_BOOT_BIN_DIR}/u-boot.img ${WORK_DIR}/
#
# Create a uEnv.txt file
# -n default to network boot
# -p add a prefix to the network booted files (e.g. xm/"
# -c set console e.g. tty02 or tty00
# -v set verbosity e.g. 0 to 3
#${RELEASETOOLSDIR}/gen_uEnv.txt.sh -c ${CONSOLE} -n -p bb/ > ${WORK_DIR}/uEnv.txt
${RELEASETOOLSDIR}/gen_uEnv.txt.sh -c ${CONSOLE} > ${WORK_DIR}/uEnv.txt
echo "Copying configuration kernel and boot modules"
mcopy -bsp -i ${WORK_DIR}/fat.img ${WORK_DIR}/$MLO ::MLO
mcopy -bsp -i ${WORK_DIR}/fat.img ${WORK_DIR}/$UBOOT ::u-boot.img
mcopy -bsp -i ${WORK_DIR}/fat.img ${WORK_DIR}/uEnv.txt ::uEnv.txt
#
# Do some last processing of the kernel and servers and then put them on the FAT
# partition.
#
${CROSS_PREFIX}objcopy ${OBJ}/minix/kernel/kernel -O binary ${OBJ}/kernel.bin
mcopy -bsp -i ${WORK_DIR}/fat.img ${OBJ}/kernel.bin ::kernel.bin
for f in servers/vm/vm servers/rs/rs servers/pm/pm servers/sched/sched \
servers/vfs/vfs servers/ds/ds servers/mib/mib fs/pfs/pfs fs/mfs/mfs \
../sbin/init/init
do
fn=`basename $f`.elf
cp ${OBJ}/minix/${f} ${OBJ}/${fn}
${CROSS_PREFIX}strip -s ${OBJ}/${fn}
mcopy -bsp -i ${WORK_DIR}/fat.img ${OBJ}/${fn} ::${fn}
done
for f in tty/tty/tty storage/memory/memory
do
fn=`basename $f`.elf
cp ${OBJ}/minix/drivers/${f} ${OBJ}/${fn}
${CROSS_PREFIX}strip -s ${OBJ}/${fn}
mcopy -bsp -i ${WORK_DIR}/fat.img ${OBJ}/${fn} ::${fn}
done
#
# For tftp booting
#
cp ${WORK_DIR}/uEnv.txt ${OBJ}/
# Clean image
if [ -f ${IMG} ] # IMG might be a block device
@@ -222,12 +137,63 @@ HOME_START=$((${USR_START} + ${_USR_SIZE}))
echo " * HOME"
_HOME_SIZE=$(${CROSS_TOOLS}/nbmkfs.mfs -d ${HOMESIZEARG} -I $((${HOME_START}*512)) ${IMG} ${WORK_DIR}/proto.home)
_HOME_SIZE=$(($_HOME_SIZE / 512))
echo " * BOOT"
rm -rf ${ROOT_DIR}/*
cp ${RELEASETOOLSDIR}/u-boot/${U_BOOT_BIN_DIR}/MLO ${ROOT_DIR}/
cp ${RELEASETOOLSDIR}/u-boot/${U_BOOT_BIN_DIR}/u-boot.img ${ROOT_DIR}/
# Create a uEnv.txt file
# -n default to network boot
# -p add a prefix to the network booted files (e.g. xm/"
# -c set console e.g. tty02 or tty00
# -v set verbosity e.g. 0 to 3
#${RELEASETOOLSDIR}/gen_uEnv.txt.sh -c ${CONSOLE} -n -p bb/ > ${WORK_DIR}/uEnv.txt
${RELEASETOOLSDIR}/gen_uEnv.txt.sh -c ${CONSOLE} > ${ROOT_DIR}/uEnv.txt
# Do some last processing of the kernel and servers and then put them on the FAT
# partition.
${CROSS_PREFIX}objcopy ${OBJ}/minix/kernel/kernel -O binary ${ROOT_DIR}/kernel.bin
for f in servers/vm/vm servers/rs/rs servers/pm/pm servers/sched/sched \
servers/vfs/vfs servers/ds/ds servers/mib/mib fs/pfs/pfs fs/mfs/mfs \
../sbin/init/init drivers/tty/tty/tty drivers/storage/memory/memory
do
fn=`basename $f`.elf
cp ${OBJ}/minix/${f} ${ROOT_DIR}/${fn}
${CROSS_PREFIX}strip -s ${ROOT_DIR}/${fn}
done
cat >${WORK_DIR}/boot.mtree <<EOF
. type=dir
./MLO type=file
./u-boot.img type=file
./uEnv.txt type=file
./kernel.bin type=file
./ds.elf type=file
./rs.elf type=file
./pm.elf type=file
./sched.elf type=file
./vfs.elf type=file
./memory.elf type=file
./tty.elf type=file
./mib.elf type=file
./vm.elf type=file
./pfs.elf type=file
./mfs.elf type=file
./init.elf type=file
EOF
#
# Create the FAT partition, which contains the bootloader files, kernel and modules
#
${CROSS_TOOLS}/nbmakefs -t msdos -s ${FAT_SIZE}b -o F=16,c=1 \
-F ${WORK_DIR}/boot.mtree ${WORK_DIR}/fat.img ${ROOT_DIR}
#
# Write the partition table using the natively compiled
# minix partition utility
#
${CROSS_TOOLS}/nbpartition -f -m ${IMG} ${FAT_START} "c:${FAT_SIZE}*" 81:${_ROOT_SIZE} 81:${_USR_SIZE} 81:${_HOME_SIZE}
${CROSS_TOOLS}/nbpartition -f -m ${IMG} ${FAT_START} \
"c:${FAT_SIZE}*" 81:${_ROOT_SIZE} 81:${_USR_SIZE} 81:${_HOME_SIZE}
#
# Merge the partitions into a single image.

View File

@@ -82,6 +82,11 @@ SMP_FLAGS += -DCONFIG_MAX_CPUS=${CONFIG_MAX_CPUS}
CPPFLAGS+= ${SMP_FLAGS}
# Disabled unaligned accesses on ARM
.if !empty(MACHINE_ARCH:Mearm*)
CFLAGS+= -mno-unaligned-access
.endif
__uname_s!= uname -s
.if ${__uname_s:Uunknown} == "Minix"
USETOOLS?= never
@@ -115,6 +120,11 @@ USETOOLS?= never
# LSC FIXME: RELEASEMACHINEDIR is set to evbarm, instead of evbearm-el
.if !empty(MACHINE:Mevbarm*)
RELEASEMACHINEDIR:= evbearm-el
# LSC: Clang uses floating point instruction to vectorize some operation, even
# at -O0, make sure it uses soft-float as the minix uKernel doesn't yet
# save / restore the hardware fpu context on ARM.
CFLAGS+= -mno-implicit-float -fno-vectorize
MKSOFTFLOAT=yes
.endif
.if ${HAVE_GCC:Dyes} == "yes" || \

View File

@@ -83,19 +83,20 @@ extern struct multiboot_header *Multiboot_Header;
/*
* Multiboot information structure.
*/
#define MULTIBOOT_INFO_MAGIC 0x2BADB002
#define MULTIBOOT_INFO_HAS_MEMORY 0x00000001
#define MULTIBOOT_INFO_MAGIC 0x2BADB002
#define MULTIBOOT_INFO_HAS_MEMORY 0x00000001
#define MULTIBOOT_INFO_HAS_BOOT_DEVICE 0x00000002
#define MULTIBOOT_INFO_HAS_CMDLINE 0x00000004
#define MULTIBOOT_INFO_HAS_CMDLINE 0x00000004
#define MULTIBOOT_INFO_HAS_MODS 0x00000008
#define MULTIBOOT_INFO_HAS_AOUT_SYMS 0x00000010
#define MULTIBOOT_INFO_HAS_ELF_SYMS 0x00000020
#define MULTIBOOT_INFO_HAS_ELF_SYMS 0x00000020
#define MULTIBOOT_INFO_HAS_MMAP 0x00000040
#define MULTIBOOT_INFO_HAS_DRIVES 0x00000080
#define MULTIBOOT_INFO_HAS_DRIVES 0x00000080
#define MULTIBOOT_INFO_HAS_CONFIG_TABLE 0x00000100
#define MULTIBOOT_INFO_HAS_LOADER_NAME 0x00000200
#define MULTIBOOT_INFO_HAS_APM_TABLE 0x00000400
#define MULTIBOOT_INFO_HAS_VBE 0x00000800
#define MULTIBOOT_INFO_HAS_VBE 0x00000800
#define MULTIBOOT_INFO_HAS_FRAMEBUFFER 0x00001000
#if defined(__minix) && !defined(__ASSEMBLY__) && (defined(_MINIX_SYSTEM) || defined(_STANDALONE))
@@ -144,11 +145,40 @@ struct multiboot_info {
void * unused_mi_apm_table;
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_VBE. */
void * unused_mi_vbe_control_info;
void * unused_mi_vbe_mode_info;
paddr_t unused_mi_vbe_interface_seg;
paddr_t unused_mi_vbe_interface_off;
uint32_t unused_mi_vbe_interface_len;
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint16_t vbe_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_FRAMEBUFFER. */
uint64_t framebuffer_addr;
uint32_t framebuffer_pitch;
uint32_t framebuffer_width;
uint32_t framebuffer_height;
uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
uint8_t framebuffer_type;
union
{
struct
{
uint32_t framebuffer_palette_addr;
uint16_t framebuffer_palette_num_colors;
};
struct
{
uint8_t framebuffer_red_field_position;
uint8_t framebuffer_red_mask_size;
uint8_t framebuffer_green_field_position;
uint8_t framebuffer_green_mask_size;
uint8_t framebuffer_blue_field_position;
uint8_t framebuffer_blue_mask_size;
};
};
};
/* --------------------------------------------------------------------- */

View File

@@ -617,7 +617,11 @@ pci_subclass_name(pcireg_t reg)
subclassp++;
}
return subclassp->name;
if (subclassp) {
return subclassp->name;
} else {
return NULL;
}
}
#endif /* defined(__minix) && defined(_PCI_SERVER) */

View File

@@ -0,0 +1,22 @@
# $NetBSD: Makefile.inc,v 1.21 2014/01/29 23:37:18 joerg Exp $
SRCS+= byte_swap_2.S byte_swap_4.S
SRCS+= ffs.S
SRCS+= memcmp.S memcpy.S memset.S memmove.S strcmp.S strncmp.S
.if !empty(MACHINE_ARCH:Mearm*)
SRCS+= unwind_stub.c
.endif
.if empty(MACHINE_ARCH:Mearmv7*)
CPUFLAGS.ffs.S+= -marm
.endif
CPUFLAGS.divide.S+= -marm
CPUFLAGS.memcmp.S+= -marm
CPUFLAGS.memcpy.S+= -marm
CPUFLAGS.memmove.S+= -marm
CPUFLAGS.memset.S+= -marm
.if empty(CPPFLAGS:M-D_STANDALONE)
CPUFLAGS.strcpy.S+= -marm
CPUFLAGS.strlcpy.S+= -marm
CPUFLAGS.strncpy.S+= -marm
.endif

View File

@@ -0,0 +1,48 @@
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: unwind_stub.c,v 1.2 2013/08/12 23:42:14 matt Exp $");
#if defined(__minix)
#include <ehabi.h>
#else
#include <arm/ehabi.h>
#endif /* defined(__minix) */
static _Unwind_Reason_Code __used
__aeabi_unwind_cpp_stub(_Unwind_State state, _Unwind_Control_Block *ucbp,
_Unwind_Context *context)
{
return _URC_FAILURE;
}
__weak_alias(__aeabi_unwind_cpp_pr0, __aeabi_unwind_cpp_stub)
__weak_alias(__aeabi_unwind_cpp_pr1, __aeabi_unwind_cpp_stub)
__weak_alias(__aeabi_unwind_cpp_pr2, __aeabi_unwind_cpp_stub)

View File

@@ -16,3 +16,9 @@ CPPFLAGS.libunwind.cxx+=-I${NETBSDSRCDIR}/sys/lib/libunwind
.if ${LIBC_MACHINE_CPU} == "arm"
AFLAGS.unwind_registers.S+= ${${ACTIVE_CC} == "clang":? -mfpu=vfp3 :}
.endif
.if defined(__MINIX)
.PATH: ${NETBSDSRCDIR}/sys/lib/libkern/arch/arm
SRCS+= unwind_stub.c
CPPFLAGS.unwind_stub.c+=-I${NETBSDSRCDIR}/sys/arch/arm/include
.endif # defined(__MINIX)