娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年11月05日(星期二)

正在發生

2021年11月05日 | 基于s3c2440的簡易bootloader實現

發布者:RainbowMelody 來源: eefocus關鍵字:s3c2440  bootloader 手機看文章 掃描二維碼
隨時隨地手機看文章

一、目的

編寫一個能夠加載并啟動OS內核的bootloader

 

二、思路

第一階段:

(1)arm920t的異常向量表有兩種存放方式,一種是低端存放(從0x00000000處開始存放),另一種是高端存放(從0xfff000000處開始存放)。選擇低端存放,建立異常向量表。

(2)s3c2440的看門狗在上電啟動時默認是開啟的,所有要先把看門狗關了先。免得代碼運行還沒完成就強制復位。

(3)屏蔽掉所有中斷。

(4)初始化時鐘。

(5)初始化內存。

(6)清零bss段。

(7)設置好各個模式下的棧空間。

(8)重定位代碼,使得代碼的運行地址與鏈接地址相對應,之后就可以直接使用絕對地址。

(9)使用絕對跳轉指令跳轉到第二階段,用c語言來實現。

第二階段:

(1)初始化串口0,一方面方便我們的調試,一方面也為內核啟動時打印信息做好初始化。

(2)初始化nand flash,需要把nand flash里的內核鏡像拷貝到內存。

(3)把內核鏡像拷貝到內存指定位置。

(4)設置好傳遞給內核的參數,并放置在約定的位置。

(5)跳轉到內核起始地址處開始啟動內核。

完畢。

 

三、流程圖設計

 

四、代碼樹結構

 

(1)drivers里的src目錄放置與外圍設備相關配置的編程文件,inc目錄放置相關頭文件。對應的makefile放在drivers目錄里。

①drivers/Makefile

 

#把src目錄下的所有.c文件的字符串替換成.o字符串
TARGET := $(patsubst %.c,%.o,$(notdir $(wildcard ./src/*.c)) )
TARGET += $(patsubst %.S,%.o,$(notdir $(wildcard ./src/*.S)) )

all:$(TARGET)
 echo "$(TARGET) 編譯完成"

GPATH=$(PWD)
vpath %.c ./src
vpath %.S ./src

%.o:%.c
 $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

%.o:%.S
 $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

clean:
 rm -f *.o

 

②drivers/inc

 

nand.h

 

#ifndef _NAND_H
#define _NAND_H

/**
*提取出頁內列號,塊內頁號,塊號
*/
#define dnand_addr2ColAddr(addr) (addr & 0x7FF)
#define dnand_addr2RowAddr(addr) (( addr & 0xFC00 ) >> 11)
#define dnand_addr2BlockAddr(addr) (addr >> 17)

//初始化NAND Flash , 時鐘頻率改變了這個一定要記得改
#define dnand_init()
   do{
    NFCONT = 0x73;
    NFCONF = (3<<12) | (1<<8) | (1<<4);
   }while(0)
//復位
void fnand_reset(void);
//等待NAND Flash就緒 
#define dnand_waitReady() while(!(NFSTAT & 0x1))
//發出片選信號 
#define dnand_enable() (NFCONT &= ~(1<<1))
//取消片選信號
#define dnand_disable() (NFCONT |= (1<<1))
//發出命令 
#define dnand_writeCmd(cmd) (NFCMMD = cmd)
//讀數據
#define dnand_readData() (*(volatile unsigned char *)&NFDATA)
//寫數據
#define dnand_writeData(data) *(volatile unsigned char *)&NFDATA = data
//寫地址
#define dnand_writeAddr(addr) 
                        do{ NFADDR = addr & 0xff;
     NFADDR = (addr >> 8) & 0x0f;
     NFADDR = (addr >> 11) & 0xff;
     NFADDR = (addr >> 19) & 0xff;
    }while(0)
    
//擦除塊
unsigned char fnand_eraseBlocks(unsigned int startBlockNum , unsigned int blockCount);
//從nand閃存里的sourAddr地址處讀取size大小的數據到內存destAddr處。    
void fnand_readOfSize(unsigned char *destAddr , unsigned int sourAddr , unsigned int size);
//。從內存sourAddr處讀取size大小的數據到nand閃存里的destAddr地址處 
unsigned char fnand_writeOfSize(unsigned char *sourAddr , unsigned int destAddr , unsigned int size);   
#endif

 

uart0.h

 

#ifndef UART0_H
#define UART0_H


#define TXD0_READY  (0x01<<1)
#define UBRDIV0_VAL     (101250000UL/(115200*16)-1)


/**********初始化uart0中斷的配置***********/
void uart0_init(void);

/*******把string消息通過uart0發送出去******/
void uart0_sent_msg(char *string);
void uart0_sent_byte(char byte);
/*打印hex數據*/
void uart0_sent_hex_word(unsigned int val);

#endif

 

 

③drivers/src

 

nand.c

#include "nand.h"
#include "s3c2440.h"

 

/**
* 復位 
*/
void fnand_reset(void)
{
 dnand_enable();
 dnand_writeCmd(0xff);  // 復位命令
 dnand_waitReady();
 dnand_disable();
}

/**
*塊擦除函數
*/
unsigned char fnand_eraseBlocks(unsigned int startBlockNum , unsigned int blockCount)
{
 unsigned int i;
 
 dnand_enable(); 
 
 for( i = 0 ; i < blockCount ; i++ ){
  //發送擦除命令
  dnand_writeCmd( 0x60 );
  dnand_writeAddr( startBlockNum << 6 ); 
  dnand_writeCmd(0xD0); 
  
  dnand_waitReady(); 
  
  //讀取狀態
  dnand_writeCmd( 0x70 );
  if ( ( dnand_readData() & 0x01 ) ){
   
   return 1;  
  }
  
  startBlockNum += 1;  
 }
 
 dnand_disable();
 return 0; 
}

void fnand_readOfSize(unsigned char *destAddr , unsigned int sourAddr , unsigned int size)
{
 unsigned int j , col;

 
 col =  sourAddr & 0x7FF ;       //該地址可能不是從頁的0地址開始讀 ,所以要先取出列地址

 dnand_enable();
 
 for( j = 0 ; j < size ; ){

  //發出read命令
  dnand_writeCmd( 0x00 );
  dnand_writeAddr( sourAddr );
  dnand_writeCmd( 0x30 );
  dnand_waitReady( );

  //開始讀一頁數據到destAddr里 ,
  for( ; (col < 2048)&&(j   *destAddr++ = dnand_readData();
   j++;
   sourAddr++;
  }
  col = 0;  
 }
 
 dnand_disable(); 
}
/**
*從內存的sourAddr處寫入pageCount頁數據到nand flash的destAddr地址處
*/
unsigned char fnand_writeOfSize(unsigned char *sourAddr , unsigned int destAddr , unsigned int size)
{
 unsigned int col, j;
 unsigned int startBlockNum , blockCount ,pageCount;
 col =  destAddr & 0x7FF ;       
        pageCount = size/2048 + ( (col)? 1 : 0 ) ;
 
 startBlockNum = dnand_addr2BlockAddr( destAddr ) ;
 blockCount = ( dnand_addr2RowAddr( destAddr ) + pageCount ) >> 6 ;
 if ( ( dnand_addr2RowAddr( destAddr ) + pageCount ) & 0x3F ){
  blockCount++; 
 }

 if ( fnand_eraseBlocks( startBlockNum , blockCount ) ){
  return 1; 
 } 
 dnand_enable(); 
 for( j = 0 ; j < size ; ){
  //發出read命令
  dnand_writeCmd( 0x80 );
  dnand_writeAddr( destAddr );
 
  //開始寫一頁數據到destAddr里
  for( ; (col < 2048)&&(j < size) ; col++ ){   
   dnand_writeData( *sourAddr++ );
   destAddr++;
   j++;
  }
  col = 0;
    
  dnand_writeCmd( 0x10 ); 
  dnand_waitReady(); 
  //發送讀取狀態命令
  dnand_writeCmd( 0x70 ); 
  if ( ( dnand_readData() & 0x01 ) ){
   return 1;  
  }
 }
 dnand_disable();
 return 0;      
}

 

uart0.c

 

#include "Uart0.h"
#include "s3c2440.h"

/*
****************************************
初始化uart0中斷的配置
****************************************
*/
void uart0_init(void)
{
        GPHCON |= 0xa0;
        GPHUP  |= 0x0f;
        ULCON0 = 0x03;  //普通模式,禁止奇偶校驗,1個結束位,8-bit字長
        UBRDIV0 = UBRDIV0_VAL; //波特率選擇115200,所以UBRDIV0=54
        UCON0 = 0x005;  //時鐘源=PCLK
                        //Rx,Tx水平觸發,禁止接收超時中斷,禁止接收錯誤狀態中斷,
                        //不使用回路模式,不發送break信號
                        //中斷方式發送接收數據到緩沖寄存器       
}

/*
*****************************************************
*uart0發送消息
***************************************************
*/

void uart0_sent_msg(char *string)

 do {    
         while( !(UTRSTAT0&TXD0_READY) ); 
         UTXH0 = *string++;
         
 }while(*string != '

主站蜘蛛池模板: 得荣县| 庆安县| 三穗县| 沙洋县| 五常市| 运城市| 嘉义市| 孟村| 新泰市| 东乌珠穆沁旗| 正宁县| 宾阳县| 万载县| 泌阳县| 商都县| 泰顺县| 洪湖市| 浠水县| 刚察县| 大渡口区| 达尔| 新营市| 扎囊县| 锡林郭勒盟| 新丰县| 比如县| 甘德县| 北辰区| 陈巴尔虎旗| 柘荣县| 雅安市| 万山特区| 电白县| 资源县| 庆云县| 长沙市| 徐闻县| 奉化市| 伊春市| 阿拉善左旗| 射洪县|