I have a use-case where I want to reserve a configurable AREA of Flash for user-data at the end of the FLASH. I wan't the linker to produce an error (or at minimum a warning) if the code section overlap with the "user-data" area.
Here is what I have defined in my linker script:
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 160K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
SECTIONS
{
.text :
{
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
_etext = .;
} >FLASH
/* Reserved FLASH area for user data (r/w data in Flash) */
__flash_data_size__ = DEFINED(FLASH_DATA_SIZE) ? FLASH_DATA_SIZE : 0K;
.flash_data ORIGIN(FLASH) + LENGTH(FLASH) - __flash_data_size__ (NOLOAD) :
{
. = ALIGN(2048);
__flash_data_start__ = .;
. = . + __flash_data_size__;
__flash_data_end__ = .;
} >FLASH
}
When I define the symbol FLASH_DATA_SIZE I can see that the elf file contains a NOLOAD section at the end of the Flash as expected. However if the section overlaps with the code section (.text) I don't get any linker error.
Any idea why the linker does not complain about this?
Alternatively any other ideas how I can have a "compile time" configurable section of the Flash reserved for user data, which is checked against overlapping of code sections?
Thanks in advance,
Thomas
I managed to work out a solution that works and provided the errors I need with overlapping sections. I solved it, by creating another MEMORY region with configurable size. For those interested in the solution I have provided it below:
_FLASH_SIZE = 512K;
_FLASH_DATA_SIZE = (DEFINED(FLASH_DATA_SIZE) ? FLASH_DATA_SIZE : 0K);
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 160K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = _FLASH_SIZE - _FLASH_DATA_SIZE
FLASH_DATA (rw) : ORIGIN = 0x08000000 + _FLASH_SIZE - _FLASH_DATA_SIZE, LENGTH = _FLASH_DATA_SIZE
}
SECTIONS
{
.text :
{
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
_etext = .;
} >FLASH
.flash_data (NOLOAD) :
{
. = ALIGN(2048);
__flash_data_start__ = .;
. = . + _FLASH_DATA_SIZE;
__flash_data_end__ = .;
} >FLASH_DATA
}
Related
Thanks Mark, on resumption, now I get Z_DATA_ERROR
case STORED:
strm->msg = (char *)"invalid stored block lengths"; // got here - Anton
state->mode = BAD;
Just to see I understood your suggestions yesterday:
after inflateInit2()
// go to byte offset
ZSEEK64( , , streamCurrentPos, ZLIB_FILEFUNC_SEEK_SET)
if ( streamBits > 0 )
{
// get that byte
unz64local_getByte( , , &aByte)
// and shift down by the number of bits. This API doing it?
inflatePrime ( , streamBits, 8 - streamBits)
} else { no bits to insert }
inflateSetDictionary ()
And state of uncompression is saved like this:
typedef struct state_of_uncompression
{
ZPOS64_T streamCurrentPos; // from : unzGetCurrentFileZStreamPos64()
int streamBits; // from : stream.data_type & (~0x1C0), after clearing bits 8,7, and 6
Byte dictionary_buf[32768]; // from : inflateGetDictionary()
uInt dictLength; // from : inflateGetDictionary();
uint64_t output_wrt_offset // got this already.
} uncompression_state_info;
What? No.
inflatePrime ( , streamBits, 8 - streamBits) makes no sense. And you did nothing with the aByte you got.
It should be inflatePrime(strm, streamBits, aByte >> (8 - streamBits)).
I guess the question is pretty straight forward itself.
Is there any way of detecting the memory (or getting he memory map) and framebuffer (or Graphics Output Protocol) after using ExitBootServices in UEFI in 64-bit mode? If so then how and is there any documentation?
I know that after using ExitBootServices, you the the sole owner of the entire machine.
There are many ways of getting the memory map but they all take help of the bootloader. I want to get the memory map directly from the kernel. Many websites such as OSDev and github sources use bootloaders to get the memory map and framebuffer.
After using ExitBootServices, I'm left in 64-bit mode and the only page on OSDev wiki about getting the memory map works on 32-bit architecture.
I have no language preferences, it may be in C, assembly or whatever and please don't say that it's useless or complicated or difficult to do. I just want an answer.
First, (Probably in (U)EFI) U cannot call boot services which is the only way to get what you want, you can get the memory map & Frame Buffer before ExitBootServices() and pass them to the kernel, you're lucky cause I'm not always on this platform, I've a Hybrid Boot Mechanism with LEGACY BIOS & UEFI Support, and here is an example of how to do that (I'm working on EDK2 Which is the Official Implementation of EFI)
This is how you get the frame buffer from G.O.P ( UGA documentation is removed ):
FRAME_BUFFER_DESCRIPTOR* GraphicsOutputProtocolInitialize(){
// First, we need to query the firmware of all G.O.P Protocol Instances
// (Each instance may represent a GPU or a monitor, GOP features multiple-screens
// U have asked for a simple implementation so we will use only 1 frame buffer
EFI_STATUS status = 0;
EFI_HANDLE* HandleBuffer = NULL;
UINTN NumProtocolHandles = 0;
if(EFI_ERROR(gBS->LocateHandleBuffer(
ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL,
&NumProtocolHandles, &HandleBuffer
)) || !NumProtocolHandles) return NULL;
// Then u need to create a structure that you can pass to the kernel containing information about frame buffers
FRAME_BUFFER_DESCRIPTOR* FrameBuffer = NULL;
if(EFI_ERROR(gBS->AllocatePool(
EfiLoaderData, sizeof(FRAME_BUFFER_DESCRIPTOR), (void**)&FrameBuffer
))) ALLOCATION_PROBLEM;
ZeroMemory((void*)FrameBuffer, sizeof(FRAME_BUFFER_DESCRIPTOR));
EFI_GRAPHICS_OUTPUT_PROTOCOL* gop = NULL;
status = gBS->OpenProtocol(
HandleBuffer[0], // Get first Graphics Output Protocol Instance
&gEfiGraphicsOutputProtocolGuid,
(void**)&gop,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if(EFI_ERROR(status) || !gop)
{
return NULL;
}
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* ginfo = NULL;
UINTN info_size = 0;
// if mode is not yet set by firmware, then set first mode
if(status == EFI_NOT_STARTED || !gop->Mode){
status = gop->SetMode(gop, 0);
if(EFI_ERROR(status) || !gop->Mode->Mode)
{
return NULL;
}
}
// Now we will ask firmware for the current Video Mode
status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &ginfo);
if(status != EFI_SUCCESS || !ginfo){
return NULL;
}
// You can also list availaible video modes
for(UINTN i = 0;i<gop->Mode->MaxMode;i++) {
status = gop->QueryMode(gop, i, &info_size, &ginfo);
if(status != EFI_SUCCESS || !ginfo){
return NULL;
}
// To set the mode :
status = gop->SetMode(gop, i);
if(EFI_ERROR(status))
{
return NULL;
}
}
FrameBuffer->FrameBufferSize = gop->Mode->FrameBufferSize;
FrameBuffer->HorizontalResolution = gop->Mode->Info->HorizontalResolution;
FrameBuffer->VerticalResolution = gop->Mode->Info->VerticalResolution;
FrameBuffer->FrameBufferBase = (char*)gop->Mode->FrameBufferBase;
ZeroMemory((void*)FrameBuffer, sizeof(FRAME_BUFFER_DESCRIPTOR));
}
return FrameBuffer;
}
This is how you get the memory map :
On the first Call you will get the size of the memory map (Status must be EFI_BUFFER_TOO_SMALL)
Then you add 2 * descriptor size coz there is always 2 additional entries, then you allocate buffer for memory map
On the second call, you will get the actual memory map (Status must be EFI_SUCCESS)
Then u can list memory map entries normally
This is how u make a call to GetMemoryMap() :
EFI_MEMORY_DESCRIPTOR* memory_map = NULL;
UINTN map_size = 0, map_key = 0, descriptor_size = 0;
// Must return EFI_BUFFER_TOO_SMALL on First Call
// map_size will contain buffer size needed
EFI_STATUS s = SystemTable->BootServices->GetMemoryMap(&map_size,memory_map,&map_key,&descriptor_size,&descriptor_version);
map_size+=2*descriptor_size; // this padding must be added since there is 2 additionnal entries
However, u can always ask for a code sample, the previous code of (G.O.P) is just copy-pasted and modified to make it a little bit easier to understand, it is not compiled so it may contain some faults.
I am trying to understand in what language this file is written in? I would like to know but here authors did not specify the language.
https://github.com/status-im/status-react/blob/develop/nix/status-go/default.nix
{ lib, callPackage, mkShell, openjdk, androidPkgs }:
let
inherit (lib)
catAttrs concatStrings concatStringsSep fileContents makeBinPath
getConfig optional attrValues mapAttrs attrByPath;
# Metadata common to all builds of status-go
meta = {
description = "The Status Go module that consumes go-ethereum.";
license = lib.licenses.mpl20;
platforms = with lib.platforms; linux ++ darwin;
};
# Source can be changed with a local override from config
source = callPackage ./source.nix { };
# Params to be set at build time, important for About section and metrics
goBuildParams = {
GitCommit = source.rev;
Version = source.cleanVersion;
};
# These are necessary for status-go to show correct version
paramsLdFlags = attrValues (mapAttrs (name: value:
"-X github.com/status-im/status-go/params.${name}=${value}"
) goBuildParams);
goBuildLdFlags = paramsLdFlags ++ [
"-s" # -s disabled symbol table
"-w" # -w disables DWARF debugging information
];
goBuildFlags = [ "-v" ];
in rec {
mobile = callPackage ./mobile {
inherit meta source goBuildFlags goBuildLdFlags;
};
shell = mkShell {
inputsFrom = [ mobile.android mobile.ios ];
};
}
It the Nix expression language.
We have about 10 servers which an NFS partition is mounted on all of them. All hosts on Icinga displays that NFS partition, so when NFS partition threshold is reached 10 mail notifications are sent for that specific error.
The question is how can I remove NFS partition from different hosts.
For now default config is as below:
apply Service for (display_name => config in host.vars.snmp.disks) {
import "generic-service-faxir"
check_command = "snmp-storage-parameteric"
vars += config
if (vars.snmp_warn == ""){
vars.snmp_warn = "70"
}
if (vars.snmp_crit == ""){
vars.snmp_crit = "85"
}
//Converting capacity to percentage
if(vars.capacity != ""){
if(vars.capacity_warn != ""){
vars.snmp_warn = 100 * vars.capacity_warn / vars.capacity
}
if(vars.capacity_crit != ""){
vars.snmp_crit = 100 * vars.capacity_crit / vars.capacity
}
}
//ext2, ext3, and ext4 has 5% reserved for OS
if (host.vars.os == "Linux"){
vars.snmp_storage_reserved = 5
}
ignore where host.vars.os !in ["Linux", "Windows"]
}
EDIT1:
the command code is as below:
/**
* based on:
* snmp storage - Disk/Memory
* Url reference: http://nagios.manubulon.com/snmp_storage.html
*/
object CheckCommand "snmp-storage-parameteric" {
import "snmp-manubulon-command"
command = [ ManubulonPluginDir + "/check_snmp_storage.pl" ]
arguments += {
"-m" = "$snmp_storage_name$"
"-f" = {
set_if = "$snmp_perf$"
}
"-R" = "$snmp_storage_reserved$"
"-T" = "$snmp_storage_type$"
"-G" = ""
}
vars.snmp_storage_name = "^/$$"
vars.snmp_storage_type = "pu"
vars.snmp_warn = 80
vars.snmp_crit = 90
vars.snmp_perf = true
vars.snmp_storage_reserved=0
}
I haven't tried it, but you could look into the following command parameters:
match a name pattern - https://github.com/dnsmichi/manubulon-snmp/blob/master/plugins/check_snmp_storage.pl#L164
-m, --name=NAME
Name in description OID (can be mounpoints '/home' or 'Swap Space'...)
This is treated as a regexp : -m /var will match /var , /var/log, /opt/var ...
Test it before, because there are known bugs (ex : trailling /)
No trailing slash for mountpoints !
exclude specific volumes - https://github.com/dnsmichi/manubulon-snmp/blob/master/plugins/check_snmp_storage.pl#L180
-e, --exclude
Select all storages except the one(s) selected by -m
No action on storage type selection
select a storage type - https://github.com/dnsmichi/manubulon-snmp/blob/master/plugins/check_snmp_storage.pl#L169
"-q, --storagetype=[Other|Ram|VirtualMemory|FixedDisk|RemovableDisk|FloppyDisk
CompactDisk|RamDisk|FlashMemory|NetworkDisk]
Best is to test the various parameters on the command line and then add them to your CheckCommand and Service definition.
Fedora 19 {though I doubt that's relevant]
If I invoke the info command for a topic that doesn't actually have an info node, but does have a man page, info will apparently create a node named (*manpages*)<topic> from the man page -- on the fly.
I can neither find this feature documented anywhere, nor (obviously) a description of how it's done.
Can anyone point me to some documentation about this?
I have checked the GNU standalone info manual and GNU Info manual and found nothing but a small sign that this feature exists. In the description of option --all we can read this:
--all
-a
Find all files matching the given menu-item (a file or node name).
Three usage patterns are supported, as follows.
First, if --all is used together with --where, info prints the names
of all matching files found on standard output (including *manpages*
if relevant) and exits.
So I'm afraid the only documentation is the source code. In info.c you can find the following function. Look for the "Fall back to loading man page." comment.
/* Get the initial Info file, either by following menus from "(dir)Top",
or what the user specifed with values in filename. */
static char *
get_initial_file (char *filename, int *argc, char ***argv, char **error)
{
char *initial_file = 0; /* First file loaded by Info. */
REFERENCE *entry;
/* If there are any more arguments, the initial file is the
dir entry given by the first one. */
if (!filename && (*argv)[0])
{
/* If they say info -O info, we want to show them the invocation node
for standalone info; there's nothing useful in info.texi. */
if (goto_invocation_p && (*argv)[0]
&& mbscasecmp ((*argv)[0], "info") == 0)
(*argv)[0] = "info-stnd";
entry = lookup_dir_entry ((*argv)[0], 0);
if (entry)
{
initial_file = info_find_fullpath (entry->filename, 0);
if (initial_file)
{
(*argv)++; /* Advance past first remaining argument. */
(*argc)--;
/* Store full path, so that we find the already loaded file in
info_find_file, and show the full path if --where is used. */
entry->filename = initial_file;
add_pointer_to_array (info_copy_reference (entry),
ref_index, ref_list, ref_slots, 2);
return initial_file;
}
}
}
/* User used "--file". */
if (filename)
{
initial_file = info_find_fullpath (filename, 0);
if (!initial_file)
{
if (filesys_error_number)
*error = filesys_error_string (filename, filesys_error_number);
}
else
return initial_file;
}
/* File name lookup. */
if (!filename && (*argv)[0])
{
/* Try finding a file with this name, in case
it exists, but wasn't listed in dir. */
initial_file = info_find_fullpath ((*argv)[0], 0);
if (initial_file)
{
(*argv)++; /* Advance past first remaining argument. */
(*argc)--;
return initial_file;
}
else
asprintf (error, _("No menu item `%s' in node `%s'."),
(*argv)[0], "(dir)Top");
}
/* Fall back to loading man page. */
if (filename || (*argv)[0])
{
NODE *man_node;
debug (3, ("falling back to manpage node"));
man_node = get_manpage_node (filename ? filename : (*argv)[0]);
if (man_node)
{
add_pointer_to_array
(info_new_reference (MANPAGE_FILE_BUFFER_NAME,
filename ? filename : (*argv)[0]),
ref_index, ref_list, ref_slots, 2);
initial_file = MANPAGE_FILE_BUFFER_NAME;
return initial_file;
}
}
/* Inexact dir lookup. */
if (!filename && (*argv)[0])
{
entry = lookup_dir_entry ((*argv)[0], 1);
if (entry)
{
(*argv)++; /* Advance past first remaining argument. */
(*argc)--;
/* Clear error message. */
free (*error);
*error = 0;
initial_file = info_find_fullpath (entry->filename, 0);
/* Store full path, so that we find the already loaded file in
info_find_file, and show the full path if --where is used. */
entry->filename = initial_file;
add_pointer_to_array (info_copy_reference (entry),
ref_index, ref_list, ref_slots, 2);
return initial_file;
}
}
/* Otherwise, we want the dir node. The only node to be displayed
or output will be "Top". */
return 0;
}
man.h contains the definition of MANPAGE_FILE_BUFFER_NAME:
#define MANPAGE_FILE_BUFFER_NAME "*manpages*"
info is a command like man, you can test the command : info make but info Read documentation in Info format.