2.1 Different BSP's
2.2 Processor specific issues
2.2.1 Power PC
2.2.2 I960
2.2.3 MIPS
2.2.4 ARM
2.3 Bootstrap
2.4 Adding component to your VxWorks configuration
2.5 VME problems
2.6 VxWorks environment
2.6.1 usrSerial.c
2.6.2 prj_vxworks.tcl
2.7 PCI problems
Index
Q: Where can I find documentation on how to build a BSP?
A: More information on device drivers is available in the Tornado BSP
developers kit(only available for Tornado 1.x). It covers several types
at a high level, such as serial, network, scsi etc.
The Vxworks Network programmers guide also does a little coverage of BSD
style device drivers.
The Network Protocol Toolkit Users Guide is also a pretty good source of
information about network drivers. It is available online at the wrs
website.
A really good source if information is the souce code that comes with
BSPs that you purchase from WRS. I have used their examples in
conjunction with the available docs and this forum to create a couple of
drivers for chips that were unsupported.
(From: John Beauford, qjb005@email.mot.com)
Q: What is the definition of a BSP?
A: I have encountered this sort of question many times before, and there are (as usual) two answers, depending on your specific requirements:
The very basic (i.el. minimal) definition of BSP is startup code,
initialization and a set of drivers that are required by VxWorks and its
bundled development environment. I.e. everything one needs to begin
developing applications on teh board using the full breath of Tornado
environment. This would include board hardware init, times, serial
drivers, and if the board has either an ethernet or a standard storage
(i.e. SCSI or IDE) interfaces, throw them in too, to enable the budnled
TCP/IP stack and Dos file system.
In that particular definition, custom or even common I.O interfaces
don't count because VxWorks has no use for them, and does not even define
the API for their drivers. VxWorks BSP test suite can not test these
extra I/O either.
An alternative approach would assume that your application will not be
running on this particular board forever, and there would be a need to
port the application to different boards, then you should define an
extended set of I/O interfaces for this type of application, clearly
define an API for drivers and implement them as part of the BSP, and
then, when needs come, one would enable your application on a new
platform simply by implementing the extended BSP. A digital camera would
be a good example where an extended BSP should be conisdered, if you are
writing a digital camera application that is expected to be used in
numerous camera models.
(From: Leonid Rosenboim)
If you have made changes to a BSP please send them to me (Johan Borkhuis), so I can add them to this page.
Q: I added memory to my board and now I get an error when I load the file. I increased the size from 32Mb to 64 Mb.
A: This is a problem of the Power PC architecture.
The problem is that memLib is allocating memory on a first-fit basis
during a walk of memory from high-memory to low memory. So your newly
ld'd .o image is being located in high memory. Your vxWorks kernel, on
the other hand is located in low memory. The distance between them is
more than 32 Mbytes. The encoding used by the code emitted by your
compiler for function calls is a "relative jump" encoding rather than a
jump to an absolute address. The relative jump encoding only has 26
effective bits of address, thus giving you an effective range of 32Mbytes
of "jumpability".
On your 64Mbyte setup, the distance from your newly ld'd .o and the
vxWorks kernel is > 32 Mbytes, and thus relative jumps don't work. The
dynamic linker is complaining above about this fact.
When you compile your code withg the flag -mlongcall (see the gcc manual
for information about this) a 32 bit jump address will be used.
(From: Bob Schulman, bob@seaweed.com)
Another solution is to define only 32 Mb and after loading all the modules adding the remaining 32Mb to the system using the command:
memAddToPool(sysMemTop(),0x2000000)
This adds the upper 32MB to available memory, thus ending up with a 64MB
system. The drawback is that no more code can be downloaded unless a
reboot is done, but that's just a minor inconvenience.
(From: Robert G Fenske Jr, fenske@rocke.electro.swri.edu)
Q: When I run VxWorks from a "ROM"-ed version it runs a lot slower than when it runs from a RAM version loaded over the network.
A: The proble is caused by the fact that the initialisation is different
for a "rom" and a "ram" version.
The "rom" version does (later on) enable ICACHE and DCACHE, but
examining the HID0 register, I saw some bit differences eventually (when
my appl. runs):
"ROM version" (using romInit.s and bootInit.c):
"RAM version" (using sysAlib.s):
The SIED and BHTE bit being set strongly improve the PPC performance (of
course). Setting these bits in ROM version resulted in same performance
figures as for RAM version.
(From: Bert Pleijsier (pleysier@nlr.nl) and John Fusco)
Q: I am using PPC860 / 850 BSP on a custom board and I receive the
following error message "uninitialized interrupt" from time to time.
The offending interrupt is a Level 7 interrupt. (Interrupt #15 in
VxWorks.) As Level 7 interrupt is mask off, so I assume it is not a
hardware problem. It seems to be a software problem because Level 7
interrupt is the default encoding in SIVEC register. The code in
ppc860Intr.c seems to be OK.
A: We had a similar problem with the PPC860SAR when we enabled the
D-cache - turned out it was the CPM Error interrupt.
We fixed it by changing a couple of lines in init.s in the bootrom...
/* Initialise instruction support control register (ICTRL) */ lis r5,HIADJ(0x00000007) /* was 0x00000006 */ addi r5,r5,LO(0x00000007) /* was 0x00000006 */ mtspr ICTRL,r5
I understand that this disables the placing of certain debug information
on the bus.
(From: Will Fookes, will@noSpam.wfookes.co.uk)
Q: How can I measure the time a function takes to execute?
A: Here's my favorite time measuring routine on a PPC using the timebase, with a precision of 60 nsec, assuming the decrementer is running at 16.666666 MHz.
#define TIMEBASE_HZ 16666666 #define TIMEBASE_PERIOD (1.0 / TIMEBASE_HZ) double double_time(void) { UINT32 tbu, tbl; vxTimeBaseGet(&tbu, &tbl); /* Get 64-bit value */ return (tbu * 4294967296.0 + tbl) * TIMEBASE_PERIOD; }
It simply returns the time in seconds; for example:
void benchmark(void) { double ts, te; ts = double_time(); my_code(); te = double_time(); printf("Elapsed time = %f sec\n", te - ts); printf(" = %f usec\n", (te - ts) * 1.0e6); }
If you're measuring a very short interval, in order to get accurate
results, you may want to surround the benchmark with
il=intLock()...intUnlock(il), assuming my_code() allows it.
You could also avoid using doubles without too much trouble, but doubles
happen to be an ideal type for manipulating time values on this kind of
processor.
(From: Curt McDowell, csm@broadcom.com)
Q: I have a problem with the PPC860 FEC code to get the ethernet controller working.
A: I recently found a problem with the VxWorks FEC code. Motorola changed
the 860T Ethernet chip interface between the B5 and the D3 version and
this required a modification to the VxWorks code. I believe I made
changes to both the syslib.c and the FEC driver code to get the D3 chip
to work. Take a look on the Motorola web site for a migration document
for the 860T.
(From: Keith Galloway, kgalloway@cinci.rr.com)
Q: How is the stack for Power organised?
A: Here's something I wrote up for the PPC604,
then modified for the PPC860. The stack frames under vxWorks/GNU are the
same.
(From: Vic Sperry, sperry.family@gte.net)
Q: Is there a high-speed clock available?
A: As you're using a PowerPC, vxLib.h defines an undocumented function (actually given in arch/ppc/vxPpcLib.h)
IMPORT void vxTimeBaseGet (UINT32 * pTbu, UINT32 * pTbl);
This gives you access to the CPU's timebase register, which counts at
some multiple of your bus clock rate, and I think that will meet for your
requirements. This counter might get reset on every system clock tick,
but I've not checked that.
(From: Andrew Johnson, anj@aps.anl.gov)
Q: Function cacheArchInvalidate does not comply to EABI specifications.
A: Please take a look at the following output, which I obtained by doing
arppc x F:\TORNADO\target\lib\libPPC604gnuvx.a cacheALib.o objdumpppc -Sr cachealib.o
in my $WIND_BASE/target/lib directory.
;// 000000c8 <cacheArchInvalidate> add r5,r5,r4 ;// 000000cc <cacheArchInvalidate+4> rlwinm r4,r4,0,0,26 ;// 000000d4 <invChk+4> beq cr3,000000e8 <invDat> ;// 000000d8 <invChk+8> cmpwi r3,0 ;// 000000dc <invChk+c> bne 0000014c <cacheArchError> ;// 000000e0 <invIns> icbi r0,r4 ;// 000000e4 <invIns+4> b 000000ec <invBottom> ;// 000000e8 <invDat> dcbi r0,r4 ;// 000000ec <invBottom> addi r4,r4,32 ;// 000000f0 <invBottom+4> cmplw r4,r5 ;// 000000f4 <invBottom+8> bge 0000016c <cacheArchOK> ;// 000000f8 <invBottom+c> beq cr3,000000e8 <invDat> ;// 000000fc <invBottom+10> b 000000e0 <invIns>
Now, according to the EABI spec., condition code register fields 2, 3 and
4 are non-volatile, and any routine that wants to use them must save them
on entry and restore them on exit. The cacheArchInvalidate routine above
clearly does no such thing. [I've also checked the code path through
cacheInvalidate that leads here, and it neither saves nor uses cr3].
This bug only shows itself up under very limited circumstances. To the
best of my knowledge, the cr fields are only used for longterm storage
when you have the optimizer turned on, and perhaps only at high levels.
Use of the -g
flag (and probably -fvolatile
too, though I haven't checked) kills this optimization.
When you do get bitten by this one, though, it's going to be nasty. The
apparent symptom is liable to be something such as an if .. else
statement branching the wrong way, where the test in the condition is an
expression that's used repeatedly in the enclosing function. Something
like
void somefunction(lots of args) { if (some condition) do something; else do something else; ... more code..... if (same condition as before) do something; else do something else; ... more code, including some that does IO or for other reasons invalidates the cache ....... if (same condition again) do something; else do something else; }
..and you find that the third if (..) sometimes takes the opposite
decision to the first two, despite there being no code in between that
could alter the values of the variables on which the condition depends.
The answer is simple enough. Here's a little bit of assembler code that
hotpatches your OS to make the code above use cr6 in place of cr3. It
checks that all the instructions it is about to patch are where they
should be, and won't do anything if it doesn't recognize the hex values
corresponding to the instructions. You might want to remove the comments
if you aren't using the c preprocessor on your .S files, and you might
need to convert crX and rX into plain X.
// int FixOSProblem(void) // 0 = fixed, 1 = not able to fix - code didn't match pattern. .globl FixOSProblem FixOSProblem: b .go .insns: .insnc8: add r5,r5,r4 .insncc: rlwinm r4,r4,0,0,26 // change me .insnd0: cmpwi cr3,r3,1 // and me .insnd4: beq cr3,.insne8 .insnd8: cmpwi r3,0 .insndc: bne .insn14c .insne0: icbi r0,r4 .insne4: b .insnec .insne8: dcbi r0,r4 .insnec: addi r4,r4,32 .insnf0: cmplw r4,r5 .insnf4: bge .insn16c // and me .insnf8: beq cr3,.insne8 .insnfc: b .insne0 .insn14c: ori r0,r0,r0 .insn16c: ori r0,r0,r0 .repls: .replc8: add r5,r5,r4 .replcc: rlwinm r4,r4,0,0,26 // change me .repld0: cmpwi cr6,r3,1 // and me .repld4: beq cr6,.reple8 .repld8: cmpwi r3,0 .repldc: bne .repl14c .reple0: icbi r0,r4 .reple4: b .replec .reple8: dcbi r0,r4 .replec: addi r4,r4,32 .replf0: cmplw r4,r5 .replf4: bge .repl16c // and me .replf8: beq cr6,.reple8 .replfc: b .reple0 .repl14c: ori 0,r0,r0 .repl16c: ori r0,r0,r0 // first verify the insns are as we expect. .go: lis r3,cacheArchInvalidate@ha addi r3,r3,cacheArchInvalidate@l lis r4,.insns@ha addi r4,r4,.insns@l lis r5,.repls@ha addi r5,r5,.repls@l lwz r6,.insnd0-.insns(r3) lwz r7,.insnd0-.insns(r4) xor. r6,r6,r7 bne cr0,.err lwz r6,.insnd4-.insns(r3) lwz r7,.insnd4-.insns(r4) xor. r6,r6,r7 bne cr0,.err lwz r6,.insnf8-.insns(r3) lwz r7,.insnf8-.insns(r4) xor. r6,r6,r7 bne cr0,.err lwz r6,.repld4-.repls(r5) stw r6,.repld4-.repls(r3) lwz r6,.replf8-.repls(r5) stw r6,.replf8-.repls(r3) lwz r6,.repld0-.repls(r5) stw r6,.repld0-.repls(r3) // flush d cache back to mem li r4,.repld4-.repls li r5,.replf8-.repls li r6,.repld0-.repls // make no assumptions about cache lines // just flush all 3 modified insns dcbst r6,r3 dcbst r4,r3 dcbst r5,r3 // wait for mem to update sync // invalidate I cache icbi r6,r3 icbi r4,r3 icbi r5,r3 // and context sync to ensure I cache invalidation completes. isync xor r3,r3,r3 // return success blr .err: li r3,1 // return failure blr
(From: Dave Korn)
Q: Broadcasts (ARP requests) do not work anymore after upgrading from T2.0 to T2.0.2
A: The BC_REJ (Broadcast Frame Reject) bit of R_CNRTL (ReceiveControl
Register) of the of the FEC (Fast Ethernet controller) was set, by
default, to 1. So, incoming Ethernet broadcast frames are rejected by the
controller. So, any protocol (like ARP) does not work, thus ping will
also not operate.
By clearing this bit, the problem has been resolved.
You can find the description of R_CNTRL register in the MPC860T Fast
Ethernet Controller manual at Motorola site.
(From: Martin Roth, bmr006@email.mot.com)
Q: Why is the system clock on the PPC not accurate?
A: I have tested the accuracy of the system clock on 82xx processor with
66 Mhz bus clock, 198 Mhz core, 166 Mhz CPM clocks.
The Time Base and the decrementer counter (DEC) registers clock is 66
Mhz/4 = 16.5 Mhz.
I have tested the accuracy of the system clock and I am sure that the
below line in sysClkRateSet() function
decCountVal = sysDecClkFrequency / ticksPerSecond;
should be replaced to
decCountVal = (sysDecClkFrequency / ticksPerSecond) - 1;
The reason is very simple: the PPC core issues an interrupt when the DEC
register bit 0 changes from 0 to 1 (becomes negative). If the DEC is
loaded with decCountVal, the period till the interrupt occurs is
decCountVal+1 (remember the interrupt occurs when DEC is -1). So we have
to load the DEC with decCountVal-1.
To be more precise to get a better approximation when there is a remainder
the fix should be:
decCountVal = ( (sysDecClkFrequency + ticksPerSecond/2 ) / ticksPerSecond) - 1;
I have tested the system after setting the system clock to 100 ticks per seconds and then to 1000 ticks per second. I have compared the taskDelay(1 hour) with the values in the Time Base register and the result were as follows:
The above two result just prove that there is an accumulation software error!!!.
After performing the above suggested change, the difference was as follows:
Below is the code of the test:
void testSysClock(void) { printf("Start system clock accuaracy test\n"); testSysClockAccuracy(100); /* Test at 100 Hz system clock */ testSysClockAccuracy(1000); /* Test at 1000 Hz system clock */ } void testSysClockAccuracy(int rate) { UINT32 tbu, tbl, i; printf("SysClkRate=%d\n", rate); sysClkRateSet(rate); taskDelay(2); vxTimeBaseSet(0,0); /* set the TBH and TBL registers to 0 */ taskDelay(rate*3600); /* suspend for 1 hour */ vxTimeBaseGet(&tbu,&tbl); /* read the TBH and TBL again */ for(i=0; i < 3600;i++) /* Count down 3600 second from TBL and TBH (16500000 units for for 1 second) */ { /* <TBL TBH> -= 3600*16500000; */ if (tbl < 16500000) { tbu--; /* borrow */ } tbl -= 16500000; } printf("tbu diff =%x (%d) , tbl diff =%x (%d)", tbu, tbu,tbl, tbl); /* print out the difference in TBL and TBH units */ }
(From: Martin Roth, bmr006@email.mot.com)
Q: Is there a compiler option or other method to compile under GNU for i960 byte aligned structures (PACKED)? I have try the -mno-code-align, -mno-strict-align, i960 compiler options. They did not help.
A: Fred Roeber wrote the following in the newsgroup:
I had similar problems with an i960 device driver. I spent some time
going through the compiler code and manuals. This document is something I put together back then that
I think might help.
(From: Fred Roeber, froeber@bbn.com)
Q: When I compile I get a lot of "... uses different e_flags ..." messages. What do these messages mean?
A: Just received from Windriver support the following note regarding
e_flags and MIPS.
(From: Xjasartist@yahoo.com)
The message "uses different e_flags ... fields than previous modules ..." can occur for MIPS and PowerPC architectures. It should not cause any problems for MIPS processors most of the time. If you look in the release notes for your MIPS BSP, you may find a comment something like:
There are several types of warnings generated by compiler. These are harmless.
During compilation of vxWorks image:uses different e_flags (0x0) fields than previous modules (0x10000001)
For the case of MIPS, what's happening is that each ELF object module keeps track of which OMF affecting flags were used or specified anywhere in the original source file. Inside the linker, there is a function which copies the appropriate flags from the original object module to the one which is being created. For MIPS, the function is mips_elf_merge_private_bfd_data(). If two different files have different sets of flags, this might be a sign of a problem, so when the compiler finds this condition it prints the warning message above.
Usually when this error message comes up with MIPS, it is from one of two different flags.
First is 0x1, which specifies that somewhere in the code a .noreorder directive was given. For MIPS, the name of this flag is EF_MIPS_NOREORDER. There should not be any problems related to this flag differing between the original object modules and the final module.
Second is 0x10000000, which is E_MIPS_ARCH_2. What this means is that some modules were compiled to use the ARCH 2 functionality. When you are using an ARCH 2 or ARCH 3 processor, this should also not be a problem.
The MIPS specific flags are:
/* Processor specific flags for the ELF header e_flags field. */ /* At least one .noreorder directive appears in the source. */ #define EF_MIPS_NOREORDER 0x00000001 /* File contains position independent code. */ #define EF_MIPS_PIC 0x00000002 /* Code in file uses the standard calling sequence for calling position independent code. */ #define EF_MIPS_CPIC 0x00000004 /* Four bit MIPS architecture field. */ #define EF_MIPS_ARCH 0xf0000000 /* -mips1 code. */ #define E_MIPS_ARCH_1 0x00000000 /* -mips2 code. */ #define E_MIPS_ARCH_2 0x10000000 /* -mips3 code. */ #define E_MIPS_ARCH_3 0x20000000
In case you have the GNU source and want to find out more about this from there, this can be found in the file .../include/elf/mips.h below the top level GNU source directory.
For PowerPC, the same error message may come up from the function ppc_elf_merge_private_bfd_data(). If this happens then the basic cause of the problem is the same as for MIPS, namely that the ELF output e_flags are different from the input flags. However, at this time our records do not contain indications about the differences in e_flags which actually occur, or even indications that this condition has ever occurred for PowerPC at all. Also, the PPC processor specific flags do not give any indication of similar conditions to the NOREORDER condition mentioned for MIPS above. If you find this error message when using PowerPC, please contact Wind River support.
Q: I am getting the following error: "unresolved symbol ___fixunsdfsi". But I never declare and use this symbol.
A: ___fixunsdfsi converts double to unsigned int. For some (unkown)
reason both ___fixunsdfsi and ___fixunssfsi (single to uint) are absent
from the vxworks image.
The following (untested) arm assembler probably does the job!
#define SGN_BIT 0x80000000 /* sign bit */ #define MNT_SZ 20 /* mantissa bits in first word */ ___fixunsdfsi: movs r12,r0,asr #MNT_SZ /* get sign and exponent */ movmi r12,#0 /* convert -ve to zero */ /* extract top 32 bits of mantissa */ mov r0,r0,lsl #31 - MNT_SZ mov r1,r1,lsr #MNT_SZ + 1 orr r0,r0,r1 orr r0,r0,#SGN_BIT /* add hidden bit */ sub r12,r12,#0x400 rsbs r12,r12,#0x1e /* unbiassed and negated */ bmi 10$ mov r0,r0,lsr r12 mov pc,lr 10$: /* overflow */ mvn r0,#0 mov pc,lr
I wrote the above as part of a full set of fp routines in order to get
acceptable performance on a strongArm system. This routine isn't used, so
hasn't been built.
It is probably several orders of magnitude shorter than the one that
gets generated from the gnu C FP library sources used for the ARM fp
routines.
(From: David Laight, dsl@tadpole.co.uk)
Q: Information on implementing PCMCIA on StrongARM.
A: Implementing the pcmcia on the SA1110/SA1111 is painful to say the
least. We have that hardware combination with 2 pcmcia sockets.
PCIC.C/TCIC.c are the driver files, you need to write a similar file for
the SA-1111. This is the hardware specific file. I found the pcic and
tcic to be much more complicated than the SA-1111, so my driver file was
simpler.
Once the driver is implemented and working then you define an pcmcia
adapter for the card, which references the functions in your driver.
pcmciaLib.c, cisLib.c, pccardLib.c these are the higher level functions
for the pcmcia, they had to be modified in various places to accomodate
the hardware. I ended up making a local copy of all the files to work on.
Here are some of the issues encountered. I don't know if you'll have the
same problems or not. BTW, this is just a high level pass at the
information, the devil is in the details.
This is just the tip of the iceberg but I hope it gets you started. I'm
still struggling with getting it to work smoothly and reliable. I found
the book "PCMCIA Developer's guide" to be useful.
(From: Ann Davis, adavis@lightchip.com)
Q: How do I change the value of the counter during boot?
A: Change the value of the define TIMEOUT in bootConfig.c to the right value, recompile the bootstrap and load this bootstrap in your target.
Q: How can I change the boot parameters without a physcial serial to my target to change these at boot time?
A: Use the command "bootChange" from the target shell or host shell using
Telnet or Rlogin.
(From: Pete Kockritz (petekz@my-deja.com)
Q: I get the message "Error in boot line:". Why is this message generated and how can I get rid of it?
A: The message is generated when bootStringToStruct() doesn't return a
pointer to EOS. That happens when something in the bootline is not
understood correctly and the processing terminates before the whole line
has been read. What follows the message should be the bootline string
with a ^ symbol under the part that was misunderstood... If you are
getting garbage then that is probably the cause of the error ;-)
(From: john_94501@my-deja.com)
Q: When I try to boot my PC target using vxload I boot DOS without any config.sys or autoexec.bat. But still I get the error "Not enough memory to load". How can I get more memory available?
A: The line
shell=a:\vxworks\vxload.com a:\vxworks\bootrom
in "config.sys" saves free memory because "command.com" will not be
loaded.
(From: Eric Lucazeau (elucazeau@my-deja.com))
Q: When I try to start an VxWorks image from T1 it runs, but when I try to start the image compiled under T2 the system freezes.
A: The problem was a file called "sysalib.s" in our vxWorks configuration
BSP. It contains the first entrypoint for vxWorks.
When we have compiled the image an warning was shown in the last line
like this
"could not find _sysinit, set it to default 0x10000"
After we added the file to the vxWorks build, it works fine.
(From: "Achim Zimmer" (hzimmer@dica.de))
Q: Is it possible to boot from a compressed VxWorks image on a file system?
A: Yes, that is possible. It can be done if you have enough RAM available.
Take a look at the attached routine bootLoadModuleInflate() in bootLoadModInfl.c, intended to go in all/bootConfig.c. It presents the same interface as bootLoadModule(), except the file descriptor that it takes is that of a deflated file.
Code such as the following code can be used to automatically call bootLoadModuleInflate() instead of bootLoadModule() when the boot file name ends with a certain extension. Then you can boot either way.
#define DEFLATED_EXT ".D" #define DEFLATED_EXT_LEN (sizeof (DEFLATED_EXT) - 1) #define DEFLATED_FILE(fileName) \ (strlen(fileName) >= DEFLATED_EXT_LEN && \ strcmp((fileName) + strlen(fileName) - DEFLATED_EXT_LEN, \ DEFLATED_EXT) == 0) /* * Support loading deflated or regular files. */ if (DEFLATED_FILE(fileName)) { if (bootLoadModuleInflate(fd, pEntry) != OK) goto readErr; } else { if (bootLoadModule (fd, pEntry) != OK) goto readErr; }
Also, a Makefile rule like the following will help create the required deflated file more easily.
DEFLATE = ${WIND_BASE}/host/${WIND_HOST_TYPE}/bin/deflate VX_BINARY = vxWorks.st ${VX_BINARY}.D: ${VX_BINARY} @echo "Deflating ${VX_BINARY} ==> ${VX_BINARY}.D ...." ${DEFLATE} < ${VX_BINARY} > ${VX_BINARY}.D
(From: Curt McDowell (csm@broadcom.com))
Q: When I boot my target over an FTP connection the kernel is loaded in a couple of seconds, but then the symbol table takes a much more time. Why does the second phase take so much more time than the first part.
A: The FTP client binds a port and lets vxWorks assign the port number.
VxWorks always assigns port numbers incrementing from 1024. So first the
boot ROM uses port 1024 to load the image. Then vxWorks resets itself,
causing it to use port 1024 again for the first file transfer after boot.
Unfortunately, some servers don't let you re-use the same port number for
up to several minutes. The port is kept unusable in the TIMED_WAIT state.
The problem may also occur if you reboot a system twice in a row because
the boot ROM tries to use port 1024 repeatedly.
One fix is to call bind() a bunch of times in a loop during early init.
This wastes port numbers. The loop count may be chosen pseudo-randomly,
but then you may occasionally still have the problem. It is better to
store the loop count in NVRAM and increment it by 16 or something every
boot, modulo some number.
Since doing this I have had no problems using any server. Here's my
version of the routine sysBindFix(). It should be called after
usrNetInit() in usrConfig.c for the kernel, and also from a convenient
place in the boot ROM, such as before netLoad(). My implementation is
appended below.
#include "netinet/in.h" /* for sysBindFix() */ #include "sockLib.h" /* for sysBindFix() */ /***************************************************************************** * * Each time VxWorks is rebooted, it starts assigning system-assigned * port numbers beginning at 1024. Thus, if vxWorks is rebooted two or * more times in succession, the same port number will be re-used. * * This behavior causes problems when vxWorks is being booted from a * remote FTP server (particularly one running Solaris), because port * 1024 goes into a TIME_WAIT state on the server and cannot be reused * until it times out, typically in 2-4 minutes. * * This hack reduces the likelyhood of this happening by "wasting" * a different number of system-assigned port numbers for each boot. */ void sysBindFix(void) { UINT8 N; sysNvRamGet((char *) &N, 1, NV_OFF_BINDFIX); N -= 16; sysNvRamSet((char *) &N, 1, NV_OFF_BINDFIX); /* This is quite fast even when N=255 */ while (N--) { int s; struct sockaddr_in saddr; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = 0; saddr.sin_family = AF_INET; s = socket(AF_INET, SOCK_STREAM, 0); bind(s, (struct sockaddr *) &saddr, sizeof(saddr)); close(s); } }
(From: Curt McDowell, csm@broadcom.com)
If the host is Solaris that you are booting from you can set TIMED_WAIT to its minimum value, as root using 'ndd':
ndd -set /dev/tcp tcp_close_wait_interval 1000
ndd -set /dev/tcp tcp_time_wait_interval 1000
This will make the boot load and symbol table operate normal.
I put a script in /etc/rc2.d to automate this on each reboot:
#!/sbin/sh # for Solaris 2.7 # refer to ndd man page case "$1" in 'start') if [ -f /usr/sbin/ndd ]; then echo 'shortening tcp_close_wait_interval to 1000' /usr/sbin/ndd -set /dev/tcp/ tcp_close_wait_interval 1000 fi ;; 'stop') ;; *) echo "Usage: $0 { start | stop }" exit 1 ;; esac exit 0
(From: Jeff Szczepanski, jszczep1@rochester.rr.com and Bob Irwin bobi@systemsinterface.com)
There is also a possible solution on the Vxworks side - make sure that
when the machine reboots, it does not reuse the same port numbers again.
This happens on fast reboots as well as switches between boot and memory
(vxWorks) images. A simple way to go about is to add code into
useNetwork.c, that creates a couple of additional sockets and binds them
to dunamic ports.
(From: Leonid Rosenboim, leonid@bitband.com)
Q: When I startup my target and want to download my VxWorks image using an FTP session, and my ftp daemon is not yet available I have to manually restart my target or use the bootprompt to start my system. How can I avoid this?
A: You could try to increase the boot timeout, but that would also be the
case when your FTP deamon machine is available.
Another option is to modify the boot process. Now, when the boot fails
the bootprompt apears. Modify it in such a way that the countdown starts
again. This means that after 10 seconds a new FTP action is started, and
if this fails 10 seconds later another is started.
Be sure to have the bootloader react to a key however. The bootprompt
should apear when you press a key, so you can still modify the boot
parameters.
Q: Is it possible to make a "multi-boot"?
A: Yes, VxWorks is quite capable of multi-booting. However, not without
some work on your part and then reburning the boot ROMs (or rebuilding
the boot image if you're using BOOTP).
What you have to do is to modify the bootConfig.c file in the area of
the routine called the bootCmdLoop.
You will need to define an alternate bootline and store it somewhere.
You'll find an example in <Your BSP>/config.h. It should look
something like this:
#define DEFAULT_BOOT_LINE \ "ei(0,0)host:/usr/vw/config/mv162/vxWorks h=90.0.0.3 e=90.0.0.50 u=target" #define ALTERNATE_BOOT_LINE1 \ "scsi=0,0(0,0)intructor:/u/team7/vxWorks h=192.168.32.50 e=192.168.32.17 u=team7 tn=vx7 s=/sd0/startup.cmd o=ei" #define ALTERNATE_BOOT_LINE2 \ "ei(0,0)intructor:/u/team7/vxWorks h=192.168.32.50 e=192.168.32.17 u=team7 tn=vx7 s=/u/team7/startup.cmd"
Then, in bootConfig.c add the following global:
char secondChance = 2;
Then, in bootConfig.c (bootCmdLoop) you would add something like this:
/* start autoboot, unless no-autoboot specified */ bootStringToStruct (BOOT_LINE_ADRS, ¶ms); sysFlags = params.flags; if (!(sysStartType & BOOT_NO_AUTOBOOT) && !(sysFlags & SYSFLG_NO_AUTOBOOT)) { int timeout = TIMEOUT; if ((sysStartType & BOOT_QUICK_AUTOBOOT) || (sysFlags & SYSFLG_QUICK_AUTOBOOT)) { timeout = 1; } key = autoboot (timeout); /* doesn't return if successful */ } else { int timeout = TIMEOUT; /* we only get here if the autoboot above fails */ switch (secondChance) { case 2 : strcpy (BOOT_LINE_ADRS, ALTERNATE_BOOT_LINE2); secondChance--; key = autoboot (timeout); /* doesn't return if successful */ break; case 1 : timeout = TIMEOUT; strcpy (BOOT_LINE_ADRS, ALTERNATE_BOOT_LINE1); secondChance--; key = autoboot (timeout); /* doesn't return if successful */ break; } } /* If we're here, either we aren't auto-booting, or we got an error * auto-booting, or the auto-booting was stopped. */
Make sure that the boot lines are configured properly and that all of the
devices that you are trying to boot from are known to both the
bootConfig.c (bootROM) and the usrNetwork.c and usrLoadSym.c code if
you're using the two step boot process (load the O/S then the symbol
table). You will have to rebuild the bootROM image for this to work.
This code snippet actually supports booting from 3 different devices as
"failsoft" devices. It trys the default NVRAM bootline, then
ALTERNATE_BOOT_LINE2 then ALTERNATE_BOOT_LINE1. I've even had this
default to dialing up via SLIP/PPP and booting via modem -- the ultimate
phone home ;-) -- if all else fails.
(From: Mike Anderson, mike@chipware.com)
Q: When I use a compressed VxWorks image a timeout resets my target before my VxWorks becomes active. Is it possible te reset the watchdog during the inflate?
A: You can modify and rebuild the inflate function to include a function
to reset the watchdog. The sources can be found at: http://www.info-zip.org/pub/infozip/zlib/
(Bill Pringlemeir, spam_account@sympatico.ca)
Q: How do I create a boot-disk?
A: Creating Bootable Floppy from Boot-ROM:
- Open DOS window.
- From DOS window execute
tornado\host\x86-win32\bin\torvars
(it will fix environment vars).- From the location of your boot-rom file (tornado\target\config\ BSP-dir\bootrom_uncmp) type
mkboot a: bootrom_uncmp
. The mkboot utility will create a bootable floppy disk
Creating Bootable Hard Disk from Boot-ROM:
- 1st stage will be to prepare a Hard Disk that will be suitable for VxWorks environment.
- Prepare a Floppy Disk with DOS6.2, FDISK & FORMAT files on it.
- Turn off your PC, remove your HD and place VxWorks HD instead.
- Boot your PC from DOS 6.2 Floppy Disk.
- Run FDISK Create FAT16 2Gbyte partition and set it to be the active partition.
- Exit from FDISK, reboot from the Floppy Disk and format the HD by using the FORMAT command from the Floppy Disk.
- Turn Off your PC, reconnect your original HD, and add VxWorks HD as a secondary HD (for example as disk D).
- Turn ON your PC (Windows NT should be activated).
- Open DOS window.
- From DOS window execute
tornado\host\x86-win32\bin\torvars
(it will fix environment vars).- From the location of your boot-rom file (tornado\target\config\ BSP-dir\bootrom_uncmp) copy bootrom_uncmp to file name bootrom.dat.
- Type
vxsys d:
(assuming VxWorks HD is mapped as disk D). The vxsys.com installs a bootstrap loader that will be used to load bootrom.sys file.- Type
vxcopy bootrom.dat d:bootrom.sys
. vxcopy copys and converts the bootrom_uncmp file to the required format.
(From: Ezra Koper, ezra_k@arelnet.com)
Q: When booting using the wu_ftpd shipped with RedHat 6.2 the booting hangs during the download.
A: The system does not hang, if you wait until the connection times-out
you will see that the system boots.
Some more research turned up a plausible explanation of the problem on
the wu ftp web site (the Red Hat Linux ftp server) and the fix was pretty
simple.
Basically, the ftp server has been made more RFC "insistent" and this
caused the VxWorks boot code to break (it also broke Lynx, Midnight
Commander and various other programs so WRS were not alone!).
The patch is to close the data connection immediately after the read
returns EOF (ie the other end has signalled a close). This is consistent
with the FTP RFC 959.
The patch should be safe (the data connection is no longer used), and it
works for me with the ftp daemon (wu ftpd) on Linux Red Hat 6.0, 6.2, as
well as the ftp supplied fom WRS for Windows - wftpd version 2.03.
So, in bootConfig.c, in the 2 places where the connection is terminated
(normal case and error case). Move the close(fd) up after the read. That
is:
/* Empty the Data Socket before close. PC FTP server hangs otherwise */ while ((read (fd, command, sizeof (command))) > 0); /* Close data connection now close (fd);
See http://www.wu-ftpd.org/broken-clients.html
for more info.
(From: paulvroberts@my-deja.com)
Q: What does the "hostname" field in the boot-parameters mean?
A: The host name field in the boot line refers to the card/machine that
has the host inet address. This hostname will appear on your 'devs' list
so that you can access the host machine through the target.
There's another field called target name that used for the name of the
card/machine that the image is running on.
Look in Section 13 of the VxWorks Networks Programmer's Guide for an
explanation of all the fields.
(From: Christian Gan, cgan@iders.ca)
Q: I boot from my Disk On Chip, but now I get unresolved symbols when I try to access a symbol.
A: First you have to generate the symbol table. When you include this
with your image you have to copy this (much larger) VxWorks file to your
target. When you create a seperate symbol file you must put the
vxworks.sym (the symbol table ) in the same site of the vxworks image.
vxworks.sym is created when you build the vxworks image.
(From: ilavin@alumnos.uva.es)
Q: After copying the file BOOTROM.SYS to a disk my PC-board does not
start. It only shows VxLd ....... [etc]
.
A: Verify that the file BOOTROM.SYS is not fragmented from MS-DOS's point
of view. You can verify this with chkdsk C:\bootrom.sys
(assuming your flash disk has drive letter C).
There will be a line at the end of the output, that tells you whether it
is or not.
If it is fragmented, VxLd loads garbage from disk into memory, 'cause it
only searches for the start of BOOTROM.SYS and reads the following
physical sectors into memory. It's completely random if the system just
hangs or crashes immediately.
(From: Werner Schiendl, ws-news@gmx.at)
Q: How can I create a bootable harddisk?
A: To boot from Hard disk follow the procedure below.
->usrAtaCOnfig(0,0,"/ata") (For accessing the hard disk) ->mkbootAta(0,0,"bootrom_uncmp") (For making the hard disk bootable) ->ataDrv ->usrAtaConfig(0,0,"/ata0/dos") (It mounts a dos file system on the hard disk and names it as "/ata0/dos")
To create a new file on the hard disk call,
->fd=creat("/ata0/dos/f1",0) ->write(fd, "My First file",20) ->close(fd)
I have just recollected, there may be minor changes.
(From: srikanth, srik_ram@hotmail.com)
Q: How to step to step boot vxworks via serial
A: Following are the steps to be followed:
#define DEFAULT_BOOT_LINE "tsfs(0,0) host:vxWorks" /* For tsfs Boot */ #undef CONSOLE_TTY #define CONSOLE_TTY NONE #undef WDB_TTY_CHANNEL #define WDB_TTY_CHANNEL 0/1 (depends on the UART's (UART1 = 0 /UART2 = 1)in the target Board) #undef WDB_COMM_TYPE #define WDB_COMM_TYPE WDB_COMM_SERIAL #define INCLUDE_TSFS_BOOT #define INCLUDE_TSFS_BOOT_VIO_CONSOLE #undef WDB_TTY_BAUD #define WDB_TTY_BAUD 57600 /* End of tsfs boot */ ********************************************************************
Q: How do I add a new component to my configuration?
A: The component structure is defined in the .cdf files, so study these first. Before you start to add your component you should answer 3 questions:
The following actions should be taken after you answered these questions:
For an example look here: Add memDrv as a component
NOTE: there is probably a better way to define new components using extra tools. I don't have these tools so I had to find another way to include my new components.
Q: How do I implement VME Bus Auto ID on the MVME-2604 Power PC. The BSP states it supports the VME-64 standard.
A: Andrew Fraser wrote some notes about this. This can be found here: vmeAutoId.html
Q: Is it possible to configure vxWorks so that it makes use of external VME memory as part of the local memory?
A: Your VME-memory should be accessible via standard VME-setup, if not
change your sysPhysMemDesc[] in sysLib.c and / or your VME-settings
parameters. On boot you may add your memory by a call to memAddToPool().
I would recommend to insert this call in function sysHwInit2() in
sysLib.c.
(From: "Michael Lawnick, Lawnick@softec.de)
Q: Another card on the VME bus is generating a bus error. How can I avoid that my SW will be stoppen by this error?
A: I was able to make my own version of VxMemProbe that's a lot faster and recovers from bus errors. Here's what worked for me:
jmp_buf myEnv; void mySigHandler(int sigNum) { longjmp(myEnv, ERROR); } // Call this once before calling the Probe() routine below. void myByteProbeInit() { struct sigaction newSig, oldSig; newSig.sa_handler = mySigHandler; newSig.sa_mask = 0; newSig.sa_flags = 0; sigaction(SIGBUS, &newSig, &oldSig); sigaction(SIGSEGV, &newSig, &oldSig); } STATUS myByteProbe(char *addr, int mode, char *data) { if(setjmp(myEnv) == 0) { if(mode == READ) *data = *addr; else *addr = *data; } else return (ERROR); }
(From: Mark A. Naivar, mnaivar@alvie-mail.lanl.gov)
Q: When I define more than 10 serial lines I only get 10 serial lines.
A: There is an error in usrSerial.c, in the function itos. In this function there is the following line:
val = val - (val %= 10);
This should be changed into:
val = (val - (val % 10))/10;
Q: When I create a new bootable project all items in the VxWorks tab are marked as "not installed". How can I get these back?
A: This is caused by the fact that an extra library has been defined in
your BSP Makefile (LIB_EXTRA = ...). The project is generated only with
the first library to look for the objects needed for the BSP.
It is possible to change this. The file where the project is generated
is prj_vxWorks.tcl. This file can be found in
host/resource/tcl/app-config-Project. In this file the following
changes must be made:
*** prj_vxWorks.tcl-old Mon Jan 24 12:08:26 2000 --- prj_vxWorks.tcl Mon Aug 7 14:33:51 2000 *** 895,905 **** set wcc [file tail $bspDir] wccCreate $hProj $wcc wccCdfPathSet $hProj $cdfPath foreach lib [bspMakeGet LIBS] { ! if {[string match *lib[bspMakeGet CPU]*.a $lib]} { ! set mxrLibs [file tail $lib] ! break ! } } if {![info exists mxrLibs]} { set mxrLibs lib[bspMakeGet CPU][bspMakeGet TOOL]vx.a --- 895,905 ---- set wcc [file tail $bspDir] wccCreate $hProj $wcc wccCdfPathSet $hProj $cdfPath + set mxrLibs "" foreach lib [bspMakeGet LIBS] { ! if {[string match *lib[bspMakeGet CPU]*.a $lib]} { ! lappend mxrLibs [file tail $lib] ! } } if {![info exists mxrLibs]} { set mxrLibs lib[bspMakeGet CPU][bspMakeGet TOOL]vx.a
Q: Information about PCI configuration.
A: From James Marshall (james_marshall@agilent.com):
I've just broken through into a clearing in the jungle of PCI
Configuration & VxWorks on various PC platforms including CompactPCI.
Some things I found useful on the journey:
The VxWorks PCI show routines aren't included from Project - you need to edit config.h in your (locally-copied) BSP and define INCLUDE_SHOW_ROUTINES. Unfortunately, this is very coarse-grained and pulls in several other unrelated show routines. I guess you could always write a .cdf file to add it to Project.
In your driver you would use PCI routines from sysLib [pcPentium]: pciFindDevice() to get the config address (bus,device,function) for each instance of your device, then read the appropriate BAR(s) to get their address(es). I guess your master/slave window stuff mentioned in WTN-49 comes in at that point.
Note that the PCI Auto Config Library (src/drv/pci/pciAutoConfigLib.c) mentioned in WTN-49 isn't supported on x86 targets because the PCI BIOS (a callable part of the BIOS) is expected to do all PCI configuration before the OS boots. This is why the default setting for PCI_CFG_TYPE on x86 targets is PCI_CFG_NONE.
The above is no longer true for all BSP's. For example, the CPV5350 BSP
does support PCI_AUTOCONF. If you enable it then the BSP will
re-configure the bus, overriding what the BIOS did.
(From: Chris Brand)
2.1 | A | Where can I find documentation on how to build a BSP? |
B | What is the definition of a BSP? | |
2.2.1 | A | I added memory to my board and now I get an error when I load the file. I increased the size from 32Mb to 64 Mb. |
B | When I run VxWorks from a "ROM"-ed version it runs a lot slower than when it runs from a RAM version loaded over the network. | |
C | I am using PPC860 / 850 BSP on a custom board and I receive the following error message "uninitialized interrupt" from time to time. | |
D | How can I measure the time a function takes to execute? | |
E | I have a problem with the PPC860 FEC code to get the ethernet controller working. | |
F | How is the stack for Power organised? | |
G | Is there a high-speed clock available? | |
H | Function cacheArchInvalidate does not comply to EABI specifications. | |
I | Broadcasts (ARP requests) do not work anymore after upgrading from T2.0 to T2.0.2 | |
J | Why is the system clock on the PPC not accurate? | |
2.2.2 | A | Is there a compiler option or other method to compile under GNU for i960 byte aligned structures (PACKED)? |
2.2.3 | A | When I compile I get a lot of "... uses different e_flags ..." messages. What do these messages mean? |
2.2.4 | A | Why am I getting the "unresolved symbol ___fixunsdfsi" error? |
B | Information on implementing PCMCIA on StrongARM. | |
2.3 | A | How do I change the value of the counter during boot? |
B | How can I change the boot parameters without a physcial serial to my target to change these at boot time? | |
C | I get the message "Error in boot line:". Why is this message generated and how can I get rid of it? | |
D | When I try to boot my PC target using vxload I boot DOS without any config.sys or autoexec.bat. But still I get the error "Not enough memory to load". How can I get more memory available? | |
E | When I try to start an VxWorks image from T1 it runs, but when I try to start the image compiled under T2 the system freezes. | |
F | Is it possible to boot from a compressed VxWorks image on a file system? | |
G | When I boot my target over an FTP connection the kernel is loaded in a couple of seconds, but then the symbol table takes a much more time. Why does the second phase take so much more time than the first part. | |
H | When I startup my target and want to download my VxWorks image using an FTP session, and my ftp daemon is not yet available I have to manually restart my target or use the bootprompt to start my system. How can I avoid this? | |
I | Is it possible to make a "multi-boot"? | |
J | When I use a compressed VxWorks image a timeout resets my target before my VxWorks becomes active. Is it possible te reset the watchdog during the inflate? | |
K | How do I create a boot-disk? | |
L | When booting using the wu_ftpd shipped with RedHat 6.2 the booting hangs during the download. | |
M | What does the "hostname" field in the boot-parameters mean? | |
N | I boot from my Disk On Chip, but now I get unresolved symbols when I try to access a symbol. | |
O | After copying the file BOOTROM.SYS to a disk my PC-board does not start. | |
P | How can I create a bootable harddisk? | |
Q | How to step to step boot vxworks via serial | |
2.4 | A | How do I add a new component to my configuration? |
2.5 | A | How do I implement VME Bus Auto ID on the MVME-2604 Power PC. The BSP states it supports the VME-64 standard. |
B | Is it possible to configure vxWorks so that it makes use of external VME memory as part of the local memory? | |
C | Another card on the VME bus is generating a bus error. How can I avoid that my SW will be stoppen by this error? | |
2.6.1 | A | When I define more than 10 serial lines I only get 10 serial lines. |
2.6.2 | A | When I create a new bootable project all items in the VxWorks tab are marked as "not installed". How can I get these back? |
2.7 | A | Information about PCI configuration. |
|