Difficulty understanding how to translate between a virutal address and physical address - c

I had a lab today that I could not complete because I cannot understand the basic process to going from a virtual address to a physical address. My understanding so far is that virtual memory is kept in a page table, it consists of pages(which contain the address and an indication if it's present or not), and that to get the physical address you need to offset by 12 bits and to make the 4 higher order bits an index(?) That's really where I get confused.
This is my code currently, it's not cohesive, but it generally shows what I understand so far. I would really appreciate any help with my understanding of this process, it seems strangely straight forward and simple, I don't know what isn't clicking for me.
`
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
struct Map{
unsigned int frame_Num : 3;
unsigned int valid : 1;
};
struct Map PageTable[16];
void createPageTable(){
PageTable[0].frame_Num = 0x2;
PageTable[0].valid = 1;
PageTable[1].frame_Num = 0x1;
PageTable[1].valid = 1;
PageTable[2].frame_Num = 0x6;
PageTable[2].valid = 1;
PageTable[3].frame_Num = 0x0;
PageTable[3].valid = 0;
PageTable[4].frame_Num = 0x4;
PageTable[4].valid = 1;
PageTable[5].frame_Num = 0x3;
PageTable[5].valid = 1;
PageTable[6].frame_Num = 0x0;
PageTable[6].valid = 0;
PageTable[7].frame_Num = 0x0;
PageTable[7].valid = 0;
PageTable[8].frame_Num = 0x0;
PageTable[8].valid = 0;
PageTable[9].frame_Num = 0x5;
PageTable[9].valid = 1;
PageTable[10].frame_Num = 0x0;
PageTable[10].valid = 0;
PageTable[11].frame_Num = 0x7;
PageTable[11].valid = 1;
PageTable[12].frame_Num = 0x0;
PageTable[12].valid = 0;
PageTable[13].frame_Num = 0x0;
PageTable[13].valid = 0;
PageTable[14].frame_Num = 0x0;
PageTable[14].valid = 0;
PageTable[15].frame_Num = 0x0;
PageTable[15].valid = 0;
}
int translateToPhysicalAddress(int virtualAddress){
//int offset = 12;
//int physicalAddress = offset<<virtualAddress;
//printf("0x%x\n", physicalAddress);
}
int main(){
createPageTable();
//translateToPhysicalAddress(5);
return 0;
}
`
I had people keep explaining it to me with the same wording as I described before, Ive tried googling things, going over my prof slides, etc. I was out for a week which does not help, but I just don't understand the basic process.

Related

What am I doing wrong with this for loop in C?

I'm trying to implement the below code in a for loop, to avoid needing to have every XOR term written out separately.
unsigned int check_0 = P0^en[2]^en[4]^en[6]^en[8]^en[10]^en[12]^en[14]^en[16]^en[18]^en[20]^en[22]^en[24]^en[26]^en[28]^en[30];
This is what I've written, but it doesn't work. Can someone please let me know what I'm doing wrong?
unsigned int check_0z = P0;
unsigned int check_0 = 0;
int i = 2;
for (i = 2; i > 30; i += 2){
check_0 = check_0z^en[i];
check_0z = check_0;
}

U-Boot: Unexpected problems porting code

I want to extend the u-boot SPL code with some fuzzy extractor logic by adding code into {u-boot_sources}/arch/arm/cpu/armv7/omap-common/hwinit-common.c. U-boot shall be used on a PandaBoard ES (omap4460 SoC).
Thus, first I successfully implemented the code on my x86 pc and I am porting it to the ARM-based PandaBoard. The complete code can be found here (as a side note the "main" function is s_init()):
http://pastebin.com/iaz13Yn9
However, I am expecting dozens of unexptected effects, which results in either stopping during the execution of the code, stopping u-boot after reading u-boot.img or not sending output (and thus not booting) at all.
For example, I want to call two functions (computeSyndrome, decodeErrors) inside a for-loop, which is part of another function golayDecode.
For my first problem please ignore the code below the multiline comment starting with /* >>>> These lines of code below totally break u-boot. Also only the function computeSyndrome in conjunction with the calling function golayDecode is important.
The issue: If comment out both functions computeSyndrome and decodeErrors everything works fine and the OS (Android) is booting. However, if computeSyndrome is not commented out and thus gets processed, u-boot stucks after displaying reading u-boot.img.
The funny thing about it: even if I replace computeSyndrome with a bogus function which does not but iterating a values or displaying stuff, u-boot stucks as well.
Furthermore, if I remove the multiline comment furhter below to also include the residual code, u-boot doesn't display ony character. (1*)
I am a beginner regarding microprocessor programming but I can not figure out a possible error in these 12 lines of the computeSyndrome function or the general behaviour of u-boot at all. (2*)
Does anyone have a clue what I am missing?
Thanks,
P.
1* I am using minicom to display the output of u-boot, which I receive over serial-usb-converter.
2* I am using the following compiler flags to make sure there are no errors at compile time: -Wall -Wstrict-prototypes -Wdisabled-optimization -W -pedantic
void golayDecode(volatile int x[12], volatile int y[12], volatile unsigned int golayEncodedSecret[30], volatile unsigned int s, volatile unsigned char repetitionDecodedSecretBits[360]){
printf("\n[I] - Performing Golay decoding\r\n");
volatile unsigned char secret[22] = {0};
volatile unsigned char currentByte = 0, tmpByte = 0;
volatile unsigned int golayDecodedSecret[30] ={0};
volatile int twelveBitCounter = 0;//, j = 0, k = 0, q = 0, aux = 0, found = 0, bitCounter = 0, i_2 = 7, currentSecretEncByte = 0x00;
volatile int c_hat[2] = {0}, e[2] = {0};
e[0] = s;
e[1] = 0;
for(twelveBitCounter = 0; twelveBitCounter < 30; twelveBitCounter+=2){
printf("Computing syndrome and decoding errors for bytes %03x & %03x\n", golayEncodedSecret[twelveBitCounter], golayEncodedSecret[twelveBitCounter+1]);
computeSyndrome(golayEncodedSecret[twelveBitCounter], golayEncodedSecret[twelveBitCounter+1], x, y, s);
decodeErrors(golayEncodedSecret[i], golayEncodedSecret[i+1], x, y, s);
}
printf("\n[D] - Reconstructing secret bytes\r\n");
/* >>>> These lines of code below totally break u-boot
for(i = 0; i < 30; i+=2){
currentSecretEncByte = golayDecodedSecret[i];
volatile int j = 11;
// Access each source bit
for(; 0<=j; j--){
volatile int currentSourceBit = (currentSecretEncByte >> j) & 0x01;
repetitionDecodedSecretBits[bitCounter] = currentSourceBit;
bitCounter++;
}
}
k = 0;
for(i = 0; i<176; i++){
tmpByte = repetitionDecodedSecretBits[i] << i_2;
currentByte = currentByte | tmpByte;
i_2--;
if(i_2==0){ // We collected 8 bits and created a byte
secret[k] = currentByte;
i_2 = 7;
tmpByte = 0x00;
currentByte = 0x00;
k++;
}
}
SHA256_CTX ctx;
unsigned char hash[32];
printf("\n[I] - Generating secret key K\n");
sha256_init(&ctx);
sha256_update(&ctx,secret,strlen((const char*)secret));
sha256_final(&ctx,hash);
printf("\n[I] - This is our secret key K\n\t==================================\n\t");
print_hash(hash);
printf("\t==================================\n");
*/
}
/* Function for syndrome computation */
void computeSyndrome(int r0, int r1, volatile int x[12], volatile int y[12], volatile unsigned int s){
unsigned int syndromeBitCounter, syndromeMatrixCounter, syndromeAux;
s = 0;
for(syndromeMatrixCounter=0; syndromeMatrixCounter<12; syndromeMatrixCounter++){
syndromeAux = 0;
for(syndromeBitCounter=0; syndromeBitCounter<12; syndromeBitCounter++){
syndromeAux = syndromeAux^((x[syndromeMatrixCounter]&r0)>>syndromeBitCounter &0x01);
}
for(syndromeBitCounter=0; syndromeBitCounter<12; syndromeBitCounter++){
syndromeAux = syndromeAux^((y[syndromeMatrixCounter]&r1)>>syndromeBitCounter &0x01);
}
s = (s<<1)^syndromeAux;
}
}
/* Funcion to recover original byte */
void decodeErrors(int r0, int r1, volatile int x[12], volatile int y[12], volatile unsigned int s){
//printf("\n[D] - Starting to decode errors for %3x | %3x\n", r0, r1);
volatile unsigned int c_hat[2] = {0xaa}, e[2] = {0xaa};
volatile unsigned int q;
unsigned int i, j, aux, found;
//printf("Step 2\n");
if(weight(s)<=3){
e[0] = s;
e[1] = 0;
}else{
/******* STEP 3 */
//printf("Step 3\n");
i = 0;
found = 0;
do{
if (weight(s^y[i]) <=2){
e[0] = s^y[i];
e[1] = x[i];
found = 1;
printf("\ntest 2\n");
}
i++;
}while ((i<12) && (!found));
if (( i==12 ) && (!found)){
/******* STEP 4 */
//printf("Step 4\n");
q = 0;
for (j=0; j<12; j++){
aux = 0;
for (i=0; i<12; i++)
aux = aux ^ ( (y[j]&s)>>i & 0x01 );
q = (q<<1) ^ aux;
}
/******* STEP 5 */
//printf("Step 5\n");
if (weight(q) <=3){
e[0] = 0;
e[1] = q;
}else{
/******* STEP 6 */
//printf("Step 6\n");
i = 0;
found = 0;
do{
if (weight(q^y[i]) <=2){
e[0] = x[i];
e[1] = q^y[i];
found = 1;
}
i++;
}while((i<12) && (!found));
if ((i==12) && (!found)){
/******* STEP 7 */
printf("\n[E] - uncorrectable error pattern! (%3x | %3x)\n", r0, r1);
/* You can raise a flag here, or output the vector as is */
//exit(1);
}
}
}
}
c_hat[0] = r0^e[0];
c_hat[1] = r1^e[1];
//printf("\t\tEstimated codeword = %x%x\n", c_hat[0], c_hat[1]);
}
Indeed, the code was a little bit too complex to be executed at this point of boot time. At this time there is ne real CRT and I only have a minimal stack.
Thus, I moved the code to board_init_f() which is still part of the SPL. It gave more stable results and my algorithm now works as expected.

Weird results from multiplying uint16_t variable with a number

I have a very simple piece of C code that gives me weird result. I'm developing a simple wireless sensor network application for Micaz motes. It seems to have ATmega128L 8 bit AVR microprocessors. I'm using AVR studio to write and compile the code.
uint16_t myvariable;
uint16_t myresult;
myresult = myvariable*256;
When myvariable is 3, I found myresult was always reset to 512. Just wondering why it works like this. My guess is, the mixture of such a literal number 256 and uint16_t magically causes the problem. But I don't know why. Could anybody give a detailed explanation on this? Appreciate for any help!
More detailed source code is as follows.
static uint16_t myvariable[2];
static uint8_t AckMsg[32];
uint16_t myresult[MAX_SENDERS];
void protocol()
{
if(thisnodeid != 5){ // sender nodes
while (1)
{
if(AckReceived && !MsgSent) {
// If ACK received and a new message not sent yet,
// send a new message on sending node.
}
else if(!AckReceived && MsgSent)
{
lib_radio_receive_timed(16, 32, AckMsg, 120);
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
// Bug!!!, variable overflowed.
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
}
}
}
}
What I really want to figure out is, how the compiler compiles following line of code, because I know it's this line of code causes the bug. Thanks in advance for any information!
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
When myvariable[1]=3, myvariable[0]=0, I always get myresult[] = 512. Looks 768 is always reset to 512. Just don't know why.
I tried this code without any problem on a standard system:
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define MAX_SENDERS 10
static uint16_t myvariable[2];
static uint8_t AckMsg[32];
uint16_t myresult[MAX_SENDERS];
main()
{
AckMsg[0] = 0;
AckMsg[1] = 3;
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
myresult[0] = 256*myvariable[1] + myvariable[0];
printf("%d", (int)myresult[0]);
}
So to debug you code, you should try to replace the lines :
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
// Bug!!!, variable overflowed.
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
by :
uint16_t tmp;
myvariable[0] = AckMsg[0];
myvariable[1] = AckMsg[1];
tmp = 256*myvariable[1] + myvariable[0];
myresult[thisnodeid] = 256*myvariable[1] + myvariable[0];
printf("%d %d\n", (int)(AckMsg[0]), (int)(AckMsg[1]));
printf("%d %d\n", (int)(thisnodeid), (int)(MAX_SENDERS));
printf("%d %d\n", (int)(myvariable[0]), (int)(myvariable[1]));
printf("%d %d\n", (int)(tmp), (int)(myresult[thisnodeid]));
This may bring useful information on the origin of the problem.
If you cannot print something in you debugger, you can try the following thing:
uint16_t i = 0;
uint16_t n = 255;
myresult[thisnodeid] += myvariable[1];
while (i != n) {
myresult[thisnodeid] += myvariable[1];
i += 1;
}
myresult[thisnodeid] += myvariable[0];
It will be slow but it may allow you to detect where the overlow is actually happening, because the only variable that will be greater than 255 is myresult.

Difference between two C snippets

I am at a loss to explain why these two C snippets do not behave the same way. I am trying to serialize two structs, eh and ah, as a single buffer of bytes (uint8_t). The first code block works, the second does not. I can't figure out the difference. If anyone can explain it to me it would be greatly appreciated.
Block 1:
uint8_t arp_reply_buf[sizeof(eh) + sizeof(ah)];
uint8_t *eh_ptr = (uint8_t*)&eh;
for (int i = 0; i < sizeof(eh); i++)
{
arp_reply_buf[i] = eh_ptr[i];
}
uint8_t *ah_ptr = (uint8_t*)&ah;
int index = 0;
for (int i = sizeof(eh); i < (sizeof(eh) + sizeof(ah)); i++)
{
arp_reply_buf[i] = ah_ptr[index++];
}
Block 2:
uint8_t arp_reply_buf[sizeof(eh) + sizeof(ah)];
arp_reply_buf[0] = *(uint8_t *)&eh;
arp_reply_buf[sizeof(eh)] = *(uint8_t *)&ah;
In the second example you only set the values in two indexes:
arp_reply_buf[0]:
arp_reply_buf[0] = *(uint8_t *)&eh;
arp_reply_buf[sizeof(eh)]:
arp_reply_buf[sizeof(eh)] = *(uint8_t *)&ah;

Problem with FFTW2 routine in C

I'm currently working with the FFTW2 (Fastest Fourier Transform in the West) library, and after writing a successful routine in Fortran, I am moving on to C. However, I'm having some trouble with data assigning when I try to input the data to transform (ie, the values of sin(x)). Currently, my code is:
#include <stdio.h>
#include <fftw.h>
#include <math.h>
#include <complex.h>
void compute_fft(){
int i;
const int n[8];
fftw_complex in[8];
fftwnd_plan p;
in[0]->re = 0;
in[1]->re = (sqrt(2)/2);
in[2]->re = 1;
in[3]->re = (sqrt(2)/2);
in[4]->re = 0;
in[5]->re = -(sqrt(2)/2);
in[6]->re = -1;
in[7]->re = -(sqrt(2)/2);
for(i = 0; i < 8; i++){
(in[i])->im = 0;
}
p = fftwnd_create_plan(8, n, FFTW_FORWARD, FFTW_ESIMATE | FFTW_IN_PLACE);
fftwnd_one(p, &in[0], NULL);
fftwnd_destroy_plan(p);
printf("Sin\n");
for(i = 0; i < 8; i++){
printf("%d\n", n[i]);
}
}
I've been using this http://fftw.org/fftw2_doc/ link for documentation/tutorial purposes, and currently my error is "invalid type argument of a->a (have afftw_complexa)", and the 'a' characters on either side of the -> and fftw_complex have carats above them. I'm using basically the same pattern that worked when I wrote this in Fortran, and I seem to be following the tutorial, it's really just this assignment here that I am messing up the syntax on. For the record, the compiler I am using is nvcc, if it makes a difference (I previously tried gcc). If anyone here has every used FFTW2 in C before, could you help correct my mistake? Thank you!
It might be because of your array "in" which is a array of fftw_complex so instead of using in[0]->re = 0 you should use it as in[0].re = 0. Unless fftw_complex is again typedefined to some array.
fftw_complex in[8];
in[0].re = 0;
in[1].re = (sqrt(2)/2);
in[2].re = 1;
in[3].re = (sqrt(2)/2);
in[4].re = 0;
in[5].re = -(sqrt(2)/2);
in[6].re = -1;
in[7].re = -(sqrt(2)/2);
Since ffwt_complex is an double[2] being the first dimension([0]) for the real data and the second ([1]) for the imaginary data, a safe solution is:
in[0][0] = 0;
in[1][0] = (sqrt(2)/2);
in[2][0] = 1;
in[3][0] = (sqrt(2)/2);
in[4][0] = 0;
in[5][0] = -(sqrt(2)/2);
in[6][0] = -1;
in[7][0] = -(sqrt(2)/2);
for(i = 0; i < 8; i++){
in[i][1] = 0;
}

Resources