How the Barebox boots up for Beaglebone Black? - bootloader

I want to know the step-by-step boot sequence of Barebox for Beaglebone Black.
which function will execute first to how it handover the control to Kernel?

I would recommend you to check this presentation first. Page 3 and 4 are showing boot sequence in picture.
If you want to get barebox binary for Beaglebone board, you will enable 'CONFIG_MACH_BEAGLEBONE'.
In file 'images/Makefile.am33xx' you find entry function named 'start_am33xx_beaglebone_sdram' for this config option (SDRAM)
pblx-$(CONFIG_MACH_BEAGLEBONE) += start_am33xx_beaglebone_sdram
FILE_barebox-am33xx-beaglebone.img = start_am33xx_beaglebone_sdram.pblx
am33xx-barebox-$(CONFIG_MACH_BEAGLEBONE) += barebox-am33xx-beaglebone.img
This entry function is the "first step" (low level HW init) defined in 'arch/arm/boards/beaglebone/lowlevel.c' file.
Then the call chain is like 'barebox_arm_entry' ('arch/arm/include/asm/barebox-arm.h') -> 'barebox_*_pbl_start' ('arch/arm/cpu/entry.c') -> ...
Then initcalls will be called
#define core_initcall(fn) __define_initcall("1",fn,1)
#define postcore_initcall(fn) __define_initcall("2",fn,2)
#define console_initcall(fn) __define_initcall("3",fn,3)
#define postconsole_initcall(fn) __define_initcall("4",fn,4)
#define mem_initcall(fn) __define_initcall("5",fn,5)
#define mmu_initcall(fn) __define_initcall("6",fn,6)
#define postmmu_initcall(fn) __define_initcall("7",fn,7)
#define coredevice_initcall(fn) __define_initcall("8",fn,8)
#define fs_initcall(fn) __define_initcall("9",fn,9)
#define device_initcall(fn) __define_initcall("10",fn,10)
#define crypto_initcall(fn) __define_initcall("11",fn,11)
#define of_populate_initcall(fn) __define_initcall("12",fn,12)
#define late_initcall(fn) __define_initcall("13",fn,13)
#define environment_initcall(fn) __define_initcall("14",fn,14)
#define postenvironment_initcall(fn) __define_initcall("15",fn,15)
See these definitions.
Last (environment) init calls will load environment and run 'init' script(s). With boot/bootm/.. barebox commands you can load 'zImage', 'dtb', 'initrd' and pass commandline arguments for Linux kernel.

Related

What does attributte section mean in UEFI memmap?

When I call memmap in the UEFI shell, I got two different attributes like the following:
Shell> memmap
Type Start End # Pages Attributes
Available 0000000080000000-00000000CFFFFFFF 0000000000050000 000000000000000E
Available 0000002000000000-000000237FFFFFFF 0000000000380000 000000000000000F
The problem is that I cannot use the second region of memory whose attribute marks as 000000000000000F. I've already registered that part of memory to my page table. But, my OS will panic when I convert a physical address from that region to a virtual address.
So, my problem is:
What does the attribute means?
How can I change the attribute so that I can use that part of memory?
The memmap command displays the memory map that is maintained by the UEFI environment by listing the contents of EFI_MEMORY_DESCRIPTOR for each memory region.
typedef struct {
UINT32 Type;
EFI_PHYSICAL_ADDRESS PhysicalStart;
EFI_VIRTUAL_ADDRESS VirtualStart;
UINT64 NumberOfPages;
UINT64 Attribute;
} EFI_MEMORY_DESCRIPTOR;
The Attribute field of a memory region describes the bit mask of capabilities for that memory region, and not necessarily the current settings for that memory region.
//*******************************************************
// Memory Attribute Definitions
//*******************************************************
// These types can be “ORed” together as needed.
#define EFI_MEMORY_UC 0x0000000000000001
#define EFI_MEMORY_WC 0x0000000000000002
#define EFI_MEMORY_WT 0x0000000000000004
#define EFI_MEMORY_WB 0x0000000000000008
#define EFI_MEMORY_UCE 0x0000000000000010
#define EFI_MEMORY_WP 0x0000000000001000
#define EFI_MEMORY_RP 0x0000000000002000
#define EFI_MEMORY_XP 0x0000000000004000
#define EFI_MEMORY_NV 0x0000000000008000
#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000
#define EFI_MEMORY_RO 0x0000000000020000
#define EFI_MEMORY_SP 0x0000000000040000
#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000
#define EFI_MEMORY_RUNTIME 0x8000000000000000
Full details about each of these attributes can be found in the UEFI Specification Section 7.2 under GetMemoryMap.
The only difference in attribute value between your two memory regions is EFI_MEMORY_UC, i.e. memory is not cacheable.

Unable to see the plugin compiled in the custom wireshark run?

I am following the foo example given in the wireshark documentation.
I am able to build the foo code plugin. I am using wireshark 3.0.1 version. In the workroot folder, I have updated the target - PLUGIN_SRC_DIRS - plugins/epan/foo just before gryphon.
I can see that my code builds because I got some compilation error which I was able to fix it.
My foo code lives inside the plugins/epan folder.
I am running custom wireshark - sudo ./run/wireshark
There is a surprise here that I can't see even gryphon protocol field in the running wireshark. So in order to test this, I am typing foo or gryphon in that display filter and it turns red and it say foo is neither a protocol nor a protocol field. I am using Ubuntu 16.04 LTS to build it. The build goes fine.
Here is packet-foo.c
#include "config.h"
#include <epan/packet.h>
#include "packet-foo.h"
static int proto_foo = -1;
static int dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_);
void
proto_register_foo(void)
{
proto_foo = proto_register_protocol (
"FOO Protocol", /* name */
"FOO", /* short name */
"foo" /* abbrev */
);
}
void
proto_reg_handoff_foo(void)
{
static dissector_handle_t foo_handle;
foo_handle = create_dissector_handle(dissect_foo, proto_foo);
dissector_add_uint("udp.port", FOO_PORT, foo_handle);
}
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_)
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
/* Clear out stuff in the info column */
col_clear(pinfo->cinfo,COL_INFO);
return tvb_captured_length(tvb);
}
Here is the packet-foo.h
#define FOO_PORT 1234
The CMakeLists.txt is here, this is actually a copy of gryphon.
So, I am wondering if gryphon wasn't recognised that means foo won't be recognised too. So, this file might be a source of problem.
include(WiresharkPlugin)
# Plugin name and version info (major minor micro extra)
set_module_info(foo 0 0 4 0)
set(DISSECTOR_SRC
packet-foo.c
)
set(PLUGIN_FILES
plugin.c
${DISSECTOR_SRC}
)
set_source_files_properties(
${PLUGIN_FILES}
PROPERTIES
COMPILE_FLAGS "${WERROR_COMMON_FLAGS}"
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
register_plugin_files(plugin.c
plugin
${DISSECTOR_SRC}
)
add_plugin_library(foo epan)
target_link_libraries(foo epan)
install_plugin(foo epan)
file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
CHECKAPI(
NAME
foo
SWITCHES
-g abort -g termoutput -build
SOURCES
${DISSECTOR_SRC}
${DISSECTOR_HEADERS}
)
Merely changing the plugin isn't sufficient.
You need to modify the top make file so that foo is actually installed.
vim CMakeListsCustom.txt.example
Firstly, uncomment - line number 16
plugins/epan/foo
Since your foo lives inside plugins/epan/foo
Now, rename this example to
mv CMakeListsCustom.txt.example CMakeListsCustom.txt
vim CMakeLists.txt
Insert a line number around 1408-
plugins/epan/foo
After that, do make
and then sudo make install
Here is the working copy -
https://github.com/joshis1/WiresharkDissectorFoo

error when compiling kernel with some new features

I am trying to compile kernel version 4.1 with some patches (adding some features to the GRO). I come from a hardware background and relatively new to network stack. I wish to know how to solve this problem or at least pointers to understand why it occurs.
This is what I did
# my temp location
mdkir kern
cd kern
# cloned the juggler and linux 4.1 tree
git clone https://github.com/gengyl08/juggler.git
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.1.tar.gz
tar -xvf linux-4.1.tar.gz
# copied just the essential files that were diffferent
cp juggler/linux-4.1/include/linux/netdevice.h linux-4.1/include/linux/netdevice.h
cp juggler/linux-4.1/include/linux/skbuff.h linux-4.1/include/linux/skbuff.h
cp juggler/linux-4.1/net/core/dev.c linux-4.1/net/core/dev.c
cp juggler/linux-4.1/net/core/net-sysfs.c linux-4.1/net/core/net-sysfs.c
cp juggler/linux-4.1/net/core/skbuff.c linux-4.1/net/core/skbuff.c
cp juggler/linux-4.1/net/ipv4/af_inet.c linux-4.1/net/ipv4/af_inet.c
cp juggler/linux-4.1/net/ipv4/tcp_offload.c linux-4.1/net/ipv4/tcp_offload.c
cd linux-4.1
make menuconfig # generated the default .config file
# building the kernel
time make
When I try to compile them, I get the following error
drivers/net/ethernet/agere/et131x.c: In function ‘nic_send_packet.constprop.43’:
include/linux/compiler.h:412:20: error: call to ‘__compiletime_assert_2439’ declared with attribute error: BUILD_BUG
prefix ## suffix(); \
^
include/linux/compiler.h:417:2: note: in expansion of macro ‘__compiletime_assert’
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler.h:429:2: note: in expansion of macro ‘_compiletime_assert’
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/bug.h:50:37: note: in expansion of macro ‘compiletime_assert’
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^
include/linux/bug.h:74:2: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
^
drivers/net/ethernet/agere/et131x.c:2439:2: note: in expansion of macro ‘BUILD_BUG_ON’
BUILD_BUG_ON(MAX_SKB_FRAGS + 1 > 23);
^
make[4]: *** [drivers/net/ethernet/agere/et131x.o] Error 1
make[3]: *** [drivers/net/ethernet/agere] Error 2
make[2]: *** [drivers/net/ethernet] Error 2
make[1]: *** [drivers/net] Error 2
make: *** [drivers] Error 2
real 22m3.067s
user 21m4.028s
sys 1m6.724s
It looks like MAX_SKB_FRAGS is too big and ethernet driver doesn't like it.
From drivers/net/ethernet/agere/et131x.c:
/* Part of the optimizations of this send routine restrict us to
* sending 24 fragments at a pass. In practice we should never see
* more than 5 fragments.
*/
/* nr_frags should be no more than 18. */
BUILD_BUG_ON(MAX_SKB_FRAGS + 1 > 23);
From the patches you're using:
linux-3.18.5/include/linux/skbuff.h:
#if (65536/PAGE_SIZE + 1) < 16
#define MAX_SKB_FRAGS 16UL
#else
#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)
#endif
linux-4.1/include/linux/skbuff.h:
#if (65536/PAGE_SIZE + 1) < 45
#define MAX_SKB_FRAGS 45UL
#else
#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)
#endif
Note the difference.
I haven't analyzed this code, but from a very first look I see some inconsistency there.
Replacing 45 back to 16 should do the trick. Of course, there might be a reason why the patch author picked a higher value.

When I really should call refresh function in module curses in Ruby

When I really should call refresh function manually in module Curses in Ruby? I think that it's unclear in the docs.
Thanks in advance.
The refresh method points out to the external function refresh():
static VALUE
curses_refresh(VALUE obj)
{
curses_stdscr();
refresh();
return Qnil;
}
And you can see the documentation of that refresh() method in the curs_refresh manual:
The refresh and wrefresh routines (or wnoutrefresh and doupdate) must
be called to get actual output to the terminal, as other routines mere‐
ly manipulate data structures. The routine wrefresh copies the named
window to the physical terminal screen, taking into account what is al‐
ready there to do optimizations. The refresh routine is the same, us‐
ing stdscr as the default window. Unless leaveok has been enabled, the
physical cursor of the terminal is left at the location of the cursor
for that window.
In modern Linux you can see the declaration of that function or macros in /usr/include/ncurses.h or /usr/include/curses.h. Example:
extern NCURSES_EXPORT(int) refresh (void); /* generated */
#define refresh() wrefresh(stdscr)
And this is the part of Ruby's curses.c that refers to the header files:
#if defined(HAVE_NCURSES_H)
# include <ncurses.h>
#elif defined(HAVE_NCURSES_CURSES_H)
# include <ncurses/curses.h>
#elif defined(HAVE_CURSES_COLR_CURSES_H)
# ifdef HAVE_STDARG_PROTOTYPES
# include <stdarg.h>
# else
# include <varargs.h>
# endif
# include <curses_colr/curses.h>
#else
# include <curses.h>
...
# endif
#endif

FFTW R2C two-dimensional size parameters

I cannot get what size parameters are for fftwf_plan_dft_r2c_2d
Input: a N rows by M cols matrix
Output: a N rows by floor(M/2) + 1 cols matrix ?
Are parameters input or output size?
Tried to give input size. This is what GDB sais
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1676.0x768]
0x637eed72 in n1fv_8 () from C:\devfiles\bin\libfftw3f-3.dll
(gdb) backtrace
#0 0x637eed72 in n1fv_8 () from C:\devfiles\bin\libfftw3f-3.dll
#1 0x7c91a000 in ntdll!RtlpUnWaitCriticalSection ()
from C:\WINDOWS\system32\ntdll.dll
No other thread uses fftw at the time.
The context:
Herbs::MatrixStorage<float> spectrum_in(frame_a.nRowsGet(),frame_a.nColsGet());
Herbs::MatrixStorage<std::complex<float>>
spectrum_out(frame_a.nRowsGet(),frame_a.nColsGet()/2+1);
Check for heap corruption issued by possible alllocation mistakes in MatrixStorage class . The rows in the matrix is one large block. rowGet returns the pointer to the given row.
memset(spectrum_in.rowGet(0),0
,sizeof(float)*spectrum_in.nRowsGet()*spectrum_in.nColsGet());
memset(spectrum_out.rowGet(0),0
,sizeof(float)*spectrum_out.nRowsGet()*spectrum_out.nColsGet());
heapdump(); //Heap seams to be fine after these
Causes sigsevg
FFT::PlanFloat_2dR2C plan(spectrum_in,spectrum_out);
The plan constructor does the following
plan=FFT::PlanFloat_2dR2C::PlanFloat_2dR2C(Herbs::MatrixStorage<InputType>& buffer_in
,Herbs::MatrixStorage<OutputType>& buffer_out)
{
plan=fftwf_plan_dft_r2c_2d
(
buffer_in.nRowsGet()
,buffer_in.nColsGet()
,buffer_in.rowGet(0)
,(fftwf_complex*)buffer_out.rowGet(0)
,FFTW_MEASURE
);
}
EDIT:
I used a precompiled DLL instead. GCC may produce bad code on 32-bit Windows (From release notes):
Removed an archaic stack-alignment hack that was failing with gcc-4.7/i386. Added stack-alignment hack necessary for gcc on Windows/i386. We will regret this in ten years (see previous change).
EDIT 2:
The dll became bad due to wrong options given to the configure script. The documentation is now updated.
You are correct. For an NxM float or double input you should allocate Nx(M/2+1) fftwf_complex or fftw_complex output.
The parameters are the input size. For example,
#include "fftw3.h"
#define Width 1024
#define Height 768
int main(){
float input[Width*Height];
fftwf_complex *fft = new fftwf_complex[((Width/2)+1)*Height];
fftwf_plan fplan = fftwf_plan_dft_r2c_2d(Height, Width,
(float*)input, fft, FFTW_ESTIMATE);
fftwf_execute(fplan);
fftwf_destroy_plan(fplan);
}
See Chapter 4.3 Basic Interface of the FFTW User Manual

Resources