OSDev: OS fails when I deinit physical memory regions - operating-system

I am currently running into problems. So, I am making my own OS, and currently have no problems except for one.
I don't know if it's with my linker script or what, but for some reason, when I attempt to deinit a region of physical memory, QEMU simply doesn't show anything on the screen.
But, as soon as I comment the function out, it works just fine. I tried packing the binary file full of random junk as well, OS still works fine, everything displays in QEMU. I tried doing hefty function calling for things that the OS doesn't even support yet, still runs. But, for some reason, when I call my function to de-init a region of used physical memory, the whole thing just crashes and doesn't work.
I am only including the linker script below, I will link my github page to the OS project for anyone to skim through it and possible help out. This is seriously super annoying.
SECTIONS {
.text 0x1F00 :
{
*(kernel_entry);
*(.text*);
}
.idt BLOCK(.) : ALIGN(.)
{
_idt = .;
. = . * 0x100;
}
.rodata :
{
*(.rodata*);
}
.bss :
{
*(.bss*);
}
end = .;
}
I did roll my own Bootloader as well. The github layout goes as so:
All bootloader content is in folder Bootloader, all kernel content(including linker script) is in folder Kernel.
GitHub page

Related

linker script and changing the flash address

I would like to ask the following a question: im using stm32g0xx microcontroller and i want to change the flash address in linker script automatically and not be forced to changed manually every time i want to generate an apllication image to let it run from diffrent address. what im doing i wrote an application and i wrote it to tow different address"0x08001000 and 0x08004800" to have the apility to switch to other application incase one of them is updated or damaged. it worked fine but i need by every image to change the flash address manually and i would like to ask if it is possible to changed somewhere else out of the linker script like startup.s?
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
FLASH (rx) : ORIGIN = 0x8001000, LENGTH = 32K
}
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
FLASH (rx) : ORIGIN = 0x8004800, LENGTH = 32K
}
You can create two linker files and compile two times, each time with a different linker script and a different output binary. You will obtain the two necessary binaries. To integrate it on your project, it depends on your way of working (STM IDE, standalone Makefile...) which you did not mention.
As a side note, you should modify the LENGTH on your linker scripts, it will prevent the linker to place data where you have another application.
Your first application starts at 4KB (0x1000), and the second start at 18KB (0x4800), the lenght of the first application should be 18-4 = 16KB and the second LENGTH should be 32-18 = 14KB (if the FLASH total size is 32KB).
You can write two different linker script and apply one or the other in your building enviroment (with the -T linker flag) or you can use a variable for your ORIGIN and pass it with -Wl,--defsym=<VAR_NAME>=<VAR_VALUE>

I get an Error when setting PCROP STM32H7 (STM32H743)

Goal
I'm trying to set a PCROP area on my STM32H743VI microcontroller, but I'm getting the error code HAL_FLASH_ERROR_OB_CHANGE when executing HAL_FLASH_OB_Launch() and my PCROP area is not set.
The relevant part of the code I'm using should be the following sections
My code
#include "stm32h7xx_hal.h"
FLASH_OBProgramInitTypeDef OBInit;
HAL_FLASHEx_OBGetConfig(&OBInit);
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
// program OB
OBInit.OptionType = OPTIONBYTE_PCROP;
OBInit.PCROPStartAddr = 0x8030000;
OBInit.PCROPEndAddr = 0x8031000;
OBInit.PCROPConfig = OB_PCROP_RDP_ERASE;
OBInit.Banks = FLASH_BANK_1; // (1, 2 oder BOTH)
HAL_FLASHEx_OBProgram(&OBInit);
/* write Option Bytes */
if (HAL_FLASH_OB_Launch() != HAL_OK) {
// Error handling
while (1)
{
}
}
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
The code is mostly inspired by the youtube video "Security Part3 - STM32 Security features - 07 - PCROP lab" (by STMicroelectronics) and the working code I have to change RDP level.
Setup
My secret function is in the expected address range, I did that by adding the memory area in the Flash.Id File
MEMORY
{
[...]
PCROP (x) : ORIGIN = 0x08030000, LENGTH = 16K
}
and putting the function file into the section accordingly
SECTIONS
{
[...]
.PCROPed :
{
. = ALIGN(4);
*led_blinking.o (.text .text*)
. = ALIGN(4);
} > PCROP
[...]
}
I set the flag -mslow-flash-data for the file I'm keeping my secret function in. I did this without really understanding why, following the tutorial in the video (see above).
What I tried
I debugged my program with my J-Trace Debugger and it seems like I'm doing the Option byte modification sequence described in the STM32H743/753 reference manual (p. 159) succesfully.
Securing an entire Flashpage (start 0x080020000, end 0x0803FFFF) didn't work either, even though I did not expect it to make a difference.
I also tried the other option for PCROPConfig, namely the OB_PCROP_RDP_NOT_ERASE option.
HAL_FLASHEx_OBProgram(&OBInit) works as intended and the ObInit Configuration is set correctly into the _FLASH->PRAR_PRG1 register. For my code the content of the register is 0x80880080
I did disconnect and reconnect the microcontroller from power and debugger in case I did not POR correctly.
I checked the errata sheet, but there is no errata which would be applicable to my problem.
EDIT
I changed the area which is protected by PCROP in the My code section.
I did this, since my code is generally functional and I found out it's not a good idea to protect an area in the first flash page!
Hmm, the code looks good so far.
Are you sure PCROP is disabled before setting it again?
Check if PRAR_CUR1 is not set from somewhere else. PCROP will raise a failure when trying to set although it is set.

Why is my CE app refusing to run?

I've been maintaining a Windows CE app for some time now (over a year) and have produced new versions of it from time to time, copying them to the handheld device[s] and running the new versions there.
Today, though, I created a new Windows CE app for the first time. It is a very simple utility.
To create it in VS 2008, I selected a C# "Smart Device Project" template, added a few controls and a bit of code, and built it.
Here are some of the options I selected:
I copied the .exe produced via building the project to the handheld device's Program Files folder:
...but it won't run. Is it in the wrong location? Does it need some ancillary files copied over? Is there some other sort of setup I need to do to get it to run? Or what?
UPDATE
Since there's not much of it, I'm pasting ALL the code below in case somebody thinks my code could be the problem:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace PrinterCommanderCE
{
public partial class PrinterCommanderForm : Form
{
public PrinterCommanderForm()
{
InitializeComponent();
}
private void btnSendCommands_Click(object sender, EventArgs e)
{
SendPrinterCommands();
}
private void SendPrinterCommands()
{
bool successfulSend = false;
const string quote = "\"";
string keepPrinterOn = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}off{0}", quote);
string shutPrinterOff = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}on{0}", quote);
string advanceToBlackBar = string.Format("! U1 setvar {0}media.sense_mode{0} {0}bar{0}", quote);
string advanceToGap = string.Format("! U1 setvar {0}media.sense_mode{0} {0}gap{0}", quote);
if (radbtnBar.Checked)
{
successfulSend = SendCommandToPrinter(advanceToBlackBar);
}
else if (radbtnGap.Checked)
{
successfulSend = SendCommandToPrinter(advanceToGap);
}
if (successfulSend)
{
MessageBox.Show("label type command successfully sent");
}
else
{
MessageBox.Show("label type command NOT successfully sent");
}
if (ckbxPreventShutoff.Checked)
{
successfulSend = SendCommandToPrinter(keepPrinterOn);
}
else
{
successfulSend = SendCommandToPrinter(shutPrinterOff);
}
if (successfulSend)
{
MessageBox.Show("print shutoff command successfully sent");
}
else
{
MessageBox.Show("print shutoff command NOT successfully sent");
}
}
private bool SendCommandToPrinter(string cmd)
{
bool success = false;
try
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close();
success = true;
}
catch
{
success = false;
}
return success;
}
}
}
UPDATE 2
Based on this, I added a global exception handler to the app so that Program.cs is now:
namespace PrinterCommanderCE
{
static class Program
{
[MTAThread]
static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);
Application.Run(new PrinterCommanderForm());
}
static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
MessageBox.Show(string.Format("GlobalExceptionHandler caught : {0}", e.Message));
}
}
}
Yet running the new build shows nothing - it just "flashes" momentarily with about as much verbosity as Lee Harvey Oswald after Jack Ruby's friendly visit.
UPDATE 3
Could the problem be related to this, and if so, how to solve it?
The circumstance that both my updated version of an existing app AND this brand new and simple app refuse to run indicate there is something fundamentally flawed somewhere in the coding, building, or deployment process.
UPDATE 4
As this is a minimal utility, the reason it (and my legacy, much more involved) app are not working may have something to do with the project properties, how it's being built, a needed file not being copied over, or...???
NOTE: The desktop icon is "generic" (looks like a blank white form); this perhaps indicates a problem, but is it indicative of something awry or is it a minor (aesthetics-only) problem?
UPDATE 5
In Project > Properties..., Platform is set to "Active (Any CPU)" and Platform target the same ("Active (Any CPU)")
I have read that this is wrong, that it should be "x86", but there is no "x86" option available - Any CPU is the only one...?!?
UPDATE 6
In Project > Properties... > Devices, the "Deploy the latest version of the .NET Compact Framework (including Service Packs)" is checked. Is this as it should be?
UPDATE 7
Okay, here's the really strange part of all this:
I have two CF/CE apps that I need to run on these Motorola/Symbol 3090 and 3190 handheld devices.
One is this simple utility discussed above. I find that it actually does run on one of the devices (the 3190, FWIW). So it runs on one device, but not on the other.
HOWEVER, the other (legacy) .exe is the opposite - it runs on the 3090 (where the utility will not even start up), but not on the 3190.
So the utility's needs are met by the 3190, and the legacy util's needs are met by the 3090. However, the NEW version of the legacy app does not run on either device!
I am baffled; I feel as Casey Stengel must have when speaking once of his three catchers: "I got one that can throw but can't catch, one that can catch but can't throw, and one who can hit but can't do either."
UPDATE 8
The 3190 has a newer version of the CF installed; it seems that both the new and the old apps should run on the new device with the newer CE, but they don't - only the one built against/for the new framework does...
UPDATE 9
Here is what the 3090 looks like:
UPDATE 10
So I have two exes, one that runs on the devices (both of them now), and the other that will run on neither of the devices. The two exesw seem almost identical. I compared them with three tools: Red Gates' .NET Reflector; JetBrains' dotPeek, and Dependency Walker.
Here is what I found:
Dependency Walker
Both seem to have the same errors about missing dependencies (I didn't have them in the same folder with their dependent assemblies is probably the problem there)
.NET Reflector
The nonworking file has this entry that the working file does not:
[assembly: Debuggable(0x107)]
Is this the problem and, if so, how can I change it?
JetBrains dotPeek
The References in the working copy of the exe are all version 1.0.50000.0
The non-working exe has an identical list of References, and the same version number.
There is this difference, though:
For the working .exe, dotPeek says, "1.4.0.15, msil, Pocket PC v3.5"
For the non-working .exe, dotPeek says, "1.4.0.15, msil, .Net Framework v4.5"
Is this the problem and, if so, how can I change the non-working .exe to match the working one?
This last is disconcerting, primarily because I see no place in the non-working (newer) version of the project where a "4.5" string exists. Where could dotPeek be getting that information?
UPDATE 11
I do know now that the problem is somewhere between these two MessageBox.Show()s, because the first one I see, but not the second:
public static int Main(string [] args)
{
try
{
// A home-brewed exception handler (named ExceptionHandler()) is already defined, but I'm adding a global one
// for UNHANDLED exceptions (ExceptionHandler() is explicitly called throughout the code in catch blocks).
MessageBox.Show("made it into Main method"); // TODO: Remove after testing <= this one is seen
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);
string name = Assembly.GetExecutingAssembly().GetName().Name;
IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name);
long error = GetLastError();
if (error == ERROR_ALREADY_EXISTS)
{
ReleaseMutex(mutexHandle);
IntPtr hWnd = FindWindow("#NETCF_AGL_BASE_",null);
if ((int) hWnd > 0)
{
SetForegroundWindow(hWnd);
}
return 0;
}
ReleaseMutex(mutexHandle);
DeviceInfo devIn = DeviceInfo.GetInstance();
Wifi.DisableWifi();
// Instantiate a new instance of Form1.
frmCentral f1 = new frmCentral();
f1.Height = devIn.GetScreenHeight();
f1.Text = DPRU.GetFormTitle("DPRU HHS", "", "");
MessageBox.Show("made it before Application.Run() in Main method"); // TODO: Remove after testing <= this one is NOT seen
Application.Run(f1);
devIn.Close();
Application.Exit();
return 0;
}
catch(Exception ex)
{
DPRU.ExceptionHandler(ex, "Main");
return 0;
}
} // Main() method
UPDATE 12
More specifically, I've got infinite looping going on somehow; By mashing the "Ent" pill on the handheld device (that's what the button looks like - a "lozenge") - it sounds like gerbils tap-dancing (as debugging MessageBox.Show()s in two methods pop up and are dismissed over and over ad infinitum ad (literally) nauseum).
If an application does not start it is mostly missing something. As you compiled for WindowsCE and CF3.5, the Compact Framework 3.5 runimes have to be installed on the WindowsCE device.
Normally Compact Framework is part of Windows CE images, at least version 1.0, but who knows for your test device? If at least one CF is installed, an app requiring a newer CF version will show that on start by a message stating about the missed version. So either no CF is on your device, or something is goind real wrong.
You can run \Windows\cgacutil.exe to check the CF version installed on the device. The tool will show the version of installed CF.
You can debug using a TCP/IP connection or ActiveSync connection. See remote debuggung elsewhere in stackoverflow, I wrote a long aanswer about remote debug via TCP/IP. Or does your device neither have USB and WLAN or ENET?
Update: Here is the answer for remote debug via tcp/ip: VS2008 remotely connect to Win Mobile 6.1 Device This will also enable the remote deployment "In Project > Properties... > Devices, the "Deploy the latest version of the .NET Compact Framework (including Service Packs)" is checked. Is this as it should be?"
Are the earlier apps you wrote also written .NET? Compact framework does not care about the processor architecture, only the CF runtimes have to match the processor. So you do not need an x86 target as if you write a native C/C++ SmartDevice project.
To your comments:
a) CF1.0 is installed on the device.
b) the exe built on the colleagues computer seems to be built for CF1 and therefor runs OK.
c) your exe is built for CF 3.5 and does not run as there is no CF3.5 runtime on the device.
d) most CF exe files are very small as long as they do not include large resources or ...
Conclusion so far: Install the CF3.5 runtime onto the device: http://msdn.microsoft.com/en-us/library/bb788171%28v=vs.90%29.aspx.
To run the legacy app on both devices, the referenced Motorola or other 3rd party runtimes must also be installed. I stringly recommand to setup your environment so you can use ActiveSync/WMDC for development, deployment and debugging of the device. If you are unable look for some more experienced colleague.
Can you try to run it inside the debugger and check where it fails?
Can you place a breakpoint right at the beginning of Program.main and check if it's reached?
Debug output may also give you some interesting hints.

PIC24 Firmware Bootloader doesn't start loaded program

I know this might not be the best place for this question but I tried the Microchip forum and didn't haven't gotten a response yet. I am working trying to get an HID bootloader project working on a prototype board that I build using a PIC24FJ64GB002. I modified the example HID Bootloader project to work with my board and I modified the example HID Mouse project to work with my board as well. When I program my device with the bootloader code it runs fine and the Microchip Bootloader Windows Program finds the device and displays "Device attached.". But when I try to load the hex file of the Mouse program onto my device it says it completes successfully but the mouse program never runs. I am not sure if I am using the correct linker scripts. Has anyone done this and know what linker scripts I should be using for the bootloader project and the loadable project?
I was able to get a breadboarded PIC24FJ64GB002 working with the Microchip HID bootloader and the Microchip HID mouse app.
The key things to do are use the the correct linker script for the bootloader and the app.
Bootloader Linker changes:
MEMORY
{
...
program (xr) : ORIGIN = 0x400, LENGTH = 0x1000
app_ivt : ORIGIN = 0x1400, LENGTH = 0xC0
...
}
__CODE_BASE = 0x400;
App linker changes:
MEMORY
{
...
app_ivt : ORIGIN = 0x1400, LENGTH = 0xC0
program (xr) : ORIGIN = 0x14C0, LENGTH = 0x96E8
...
}
__CODE_BASE = 0x200;
After you load the application via the bootloader, you must reset the device.
The following code at the beginning of main() in the bootloader is what causes the bootloader to jump to the application.
mInitSwitch2();
if((sw2==1) && ((RCON & 0x83) != 0))
{
__asm__("goto 0x1400");
}

Lua: require() not working on iPhone

I am working on a shooting game on iPhone and I need lua for scripting levels, enemies, and etc.
So I wrote a bullet script like this:
-- circular_bullet.lua
local time_between_bullets = 0.2;
...
function InitializeCircularBullet(objectName)
...
end
and an enemy script:
-- level1_D2.lua
require("circular_bullet.lua");
...
But it turned out that the enemy script can't "require" the bullet script.
I tried to look into lua library, and found out that in loadlib.c :
static int ll_require (lua_State *L) {
...
if (lua_isfunction(L, -1)) /* did it find module? */
break; /* module loaded sucessfully */
else if (lua_isstring(L, -1)) /* loader returned error message? */
lua_concat(L, 2); /* accumulate it */
else
lua_pop(L, 1);
...
}
It would enter the "else if" branch, which means some error happened, but I have no idea how to read that error message.
If I comment out the "require" line, the enemy "level1_D2" would work as intend without shooting bullet. I also did try copy the whole circular_bullet.lua into level1_D2.lua, and it worked, so the problem must be the require statement.
Those two files are under root directory of the package. (I don't know how to make them in different directory, thus I had found out that Diner Dash kept its scripts in different directory.)
However the two files are not in the same group in my Xcode project. I tried putting them in same group but nothing happened.
Anyone knows what the problem is? Thanks a lot!
Finally I got the answer!!!
the lua require function searches "./scrips" directory for require files, so I got to put those script in the directory!
Yet I still don't know how to change that searching path, but it did work.
I've got a snippet here which might help you to change that path:
// Initialize library path
lua_pushstring(L,"package");
lua_gettable(L, LUA_GLOBALSINDEX);
string path = string(Globals::GetPathPrefix())+"?.lua";
lua_pushstring(L, "path");
lua_pushstring(L, path.c_str());
lua_settable(L, -3);
lua_pop(L,1);
I also had this when I was new to Lua. I don't know this also appears on iPhone, but on Windows I had to remove the '.lua' So just remove the extension.