Summary of uClinux kernel porting on ARMSYS

Publisher:Qilin520Latest update time:2021-07-08 Source: eefocusKeywords:uClinux Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Brief description


A summary of "How to build uClinux kernel transplantation on ARMSYS development board with S3C44B0X as core", including the analysis of Bootloader function and the key contents modified for S3C44B0X development board based on uClinux2.4.24 release kernel.


2. Bootloader


2.1 Bootloader Overview


BootLoader is a program that runs before the operating system kernel runs. Through this program, we can initialize the hardware devices and establish a mapping of the memory space, so as to bring the system's hardware and software environment to a suitable state, so as to prepare the correct environment for the final call to the operating system kernel. Therefore, the prerequisite for correctly establishing the transplantation of uClinux is to have a Bootloader that is easy to use and matches uClinux.


The ARMSYS development board provides such a uClinux-specific Bootloader, which is burned at address 0x0 of the system and runs every time it is powered on. It can correctly complete the initialization of the hardware system and the booting of uClinux.


In theory, uClinux does not necessarily need a bootloader independent of the kernel when booting. However, designing the bootloader separately from the kernel can make the software architecture clearer, and also help to flexibly support multiple boot modes and implement some useful auxiliary functions.


The main tasks of the Bootloader provided by ARMSYS can be summarized as follows:


1. Hardware initialization;


2. Download new kernel image and file system image from the host;


3. Burn NorFlash and Nandflash;


4. Load the uClinux kernel image and start running;


5. Provide a human-machine operation interface on the serial hyperterminal.


2.2 Storage space distribution


The Bootloader uses the default storage space distribution address to load the uClinux kernel and file system, and guide the operation of uClinux correctly. In the ARMSYS Bootloader, the default storage space distribution is as follows:


Content start address storage medium


Bootloader program space 0x00000000 Flash


Compressed kernel image 0x00010000Flash


ROM file system image 0x000e0000Flash


Kernel running address 0x0c008000SDRAM


Compressed kernel decompression address 0x0c100000 SDRAM


File system loaded 0x0c700000SDRAM


The allocation method of this storage space is not fixed and can be changed by modifying the relevant code in the Bootloader.


2.3Bootloader Working


The complete Bootloader boot process can be described as follows:


Hardware initialization phase 1


◎Hardware initialization;


◎Copy the secondary interrupt exception vector table;


◎Initialize various processor modes;


◎Copy RO and RW, clear ZI (jump to C code entry function).


Hardware initialization phase 2


◎Initialize the hardware devices used in this stage;


◎Establish human-machine interface;


◎Implement image file download and burning tools;


◎Implement the tool for loading and running image files.


The following describes each of the above steps one by one, and explains the content related to uClinux in detail.


2.3.1 Hardware Initialization


After the board is powered on or reset, the program starts to execute from the ResetExceptionVector at address 0x0, so it is necessary to place the first instruction of the Bootloader here: bResetHandler, jump to the ResetHandler label to perform the first stage of hardware initialization, the main contents are: turn off the WatchdogTimer, turn off the interrupt, initialize the PLL and clock, and initialize the memory controller. It is more important to calculate the output frequency of the PLL correctly, and set it to 64MHz in ARMSYS; this is actually the main working frequency of the processor, and this time parameter will also be used in the second stage to calculate the refresh count value of the SDRAM and the baud rate of the UART and other parameters.


2.3.2 Establishing the Secondary Exception Interrupt Vector Table


The Exception Vector Table is one of the key points where the Bootloader and the uClinux kernel connect. Even if the uClinux kernel has taken control of the processor and is running, once an interrupt occurs, the processor will automatically jump to a table entry in the first-level exception interrupt vector table starting from address 0x0 (depending on the interrupt type) to read instructions and run.


When writing the Bootloader, the first-level exception interrupt vector table at address 0x0 simply contains a jump instruction to the second-level exception interrupt vector table. In this way, the event can be correctly handed over to the uClinux interrupt handler for processing. For the uClinux kernel, it establishes its own second-level exception interrupt vector table at the base address 0xc000000 in the RAM space. Therefore, the first-level exception interrupt vector table of the Bootloader is as follows:


bResetHandler;ResetHandler


ldrpc,=0x0c000004;UndefinedInstructionHandler


ldrpc,=0x0c000008;SoftwareInterruptHandler


ldrpc,=0x0c00000c;PrefetchAbortHandler


ldrpc,=0x0c000010;DataAbortHandler


b.


ldrpc,=0x0c000018;IRQHandler


ldrpc,=0x0c00001c;FIQHandler


LTORG


If you don't need to respond to interrupts during the entire process of Bootloader execution, the above settings can meet the requirements. However, our ARMSYS provides a USB downloader that requires interrupts, so the Bootloader must configure its own secondary exception interrupt vector table at the same address (0xc000000) to be compatible with uClinux. This table is stored in FlashMemory in advance, and the Bootloader copies it to RAM address 0x0C000000 during the boot process to store the vector table:


;IRQ==theprogramputthisphraseto0xc000000


ExceptionHanlderBegin


b.


ldrpc,MyHandleUndef;HandlerUndef


ldrpc,MyHandleSWI;HandlerSWI


ldrpc,MyHandlePabort;HandlerPabort


ldrpc,MyHandleDabort;HandlerDAbort


b. ;HandlerReserved


ldrpc,MyHandleIRQ;HandlerIRQ


ldrpc,MyHandleFIQ;HandlerFIQ


MyHandleUndefDCDHandleUndef;reserveaword(32bit)


MyHandleSWIDCDHandleSWI


MyHandlePabortDCDHandlePabort


MyHandleDabortDCDHandleDabort


MyHandleIRQDCDHandleIRQ


MyHandleFIQDCDHandleFIQ


ExceptionHanlderEnd


Create a secondary vector table:


;****************************************************


;*SetupIRQhandler*


;****************************************************


ldrr0,=(_IRQ_BASEADDRESS+0x100)


ldrr2,=_IRQ_BASEADDRESS


addr3, r0, #0x100


0


CMPr0,r3


STRCCr2,[r0],#4;cc:Carryclear;saveR2toR0address,R0=R0+4.


BCC%B0


ldrr1,=_IRQ_BASEADDRESS


ldrr0,=ExceptionHanlderBegin;ifthereisn't'subspc,lr,#4'at0x18,0x1c


ldrr3,=ExceptionHandlerEnd


0


CMPr0,r3;putthevectortableat_IRQ_BASEADDRESS(0xc000000)


LDRCCr2, [r0], #4


STRCCr2,[r1],#4


BCC%B0


ldrr1,=DIsrIRQ;puttheIRQjudgeprogramat_IRQ_BASEADDRESS+0x80(0xc000080)


ldrr0,=IsrIRQ;ifthereisn't'subspc,lr,#4'at0x18,0x1c


ldrr3,=IsrIRQEnd


0


CMPr0,r3


LDRCCr2, [r0], #4


STRCCr2,[r1],#4


BCC%B0


ldrr1,=MyHandleIRQ;MyHandleIRQpointtoDIsrIRQ


ldrr0,=ExceptionHanlderBegin


ldrr4,=_IRQ_BASEADDRESS;


subr0,r1,r0


addr0, r0, r4


ldrr1,=DIsrIRQ


strr1, [r0]


Define Handlexxx:


^(_IRQ_BASEADDRESS)


HandleReset#4


HandleUndef#4


HandleSWI#4


HandlePabort#4


HandleDabort#4


HandleReserved#4


HandleIRQ#4


HandleFIQ#4


^(_IRQ_BASEADDRESS+0x80)


DIsrIRQ#4


;IntVectorTable


^(_IRQ_BASEADDRESS+0x100)


HandleADC#4


HandleRTC#4


HandleUTXD1#4


HandleUTXD0#4


HandleSIO#4


HandleIIC#4


HandleURXD1#4


HandleURXD0#4


HandleTIMER5#4


HandleTIMER4#4


HandleTIMER3#4


HandleTIMER2#4


HandleTIMER1#4


HandleTIMER0#4


HandleUERR01#4


HandleWDT#4


HandleBDMA1#4


HandleBDMA0#4


HandleZDMA1#4


HandleZDMA0#4


HandleTICK#4


HandleEINT4567#4


HandleEINT3#4


HandleEINT2#4


HandleEINT1#4


HandleEINT0#4


The advantage of reconstructing the abnormal interrupt vector to SDRAM is that the address of the interrupt handler can be assigned arbitrarily in other functional programs. To this end, we define in the 44b.h file:


/*ISR*/


#definepISR_RESET(*(unsigned*)(_IRQ_BASEADDRESS+0x0))


#definepISR_UNDEF(*(unsigned*)(_IRQ_BASEADDRESS+0x4))


#definepISR_SWI(*(unsigned*)(_IRQ_BASEADDRESS+0x8))


#definepISR_PABORT(*(unsigned*)(_IRQ_BASEADDRESS+0xc))


#definepISR_DABORT(*(unsigned*)(_IRQ_BASEADDRESS+0x10))


#definepISR_RESERVED(*(unsigned*)(_IRQ_BASEADDRESS+0x14))


#definepISR_IRQ(*(unsigned*)(_IRQ_BASEADDRESS+0x18))


#definepISR_FIQ(*(unsigned*)(_IRQ_BASEADDRESS+0x1c))


#definepISR_ADC(*(unsigned*)(_IRQ_BASEADDRESS+0x100))//0x20))


#definepISR_RTC(*(unsigned*)(_IRQ_BASEADDRESS+0x104))//0x24))


#definepISR_UTXD1(*(unsigned*)(_IRQ_BASEADDRESS+0x108))//0x28))


#definepISR_UTXD0(*(unsigned*)(_IRQ_BASEADDRESS+0x10c))//0x2c))


#definepISR_SIO(*(unsigned*)(_IRQ_BASEADDRESS+0x110))//0x30))


#definepISR_IIC(*(unsigned*)(_IRQ_BASEADDRESS+0x114))//0x34))


#definepISR_URXD1(*(unsigned*)(_IRQ_BASEADDRESS+0x118))//0x38))


#definepISR_URXD0(*(unsigned*)(_IRQ_BASEADDRESS+0x11c))//0x3c))


#definepISR_TIMER5(*(unsigned*)(_IRQ_BASEADDRESS+0x120))//0x40))


#definepISR_TIMER4(*(unsigned*)(_IRQ_BASEADDRESS+0x124))//0x44))


#definepISR_TIMER3(*(unsigned*)(_IRQ_BASEADDRESS+0x128))//0x48))


#definepISR_TIMER2(*(unsigned*)(_IRQ_BASEADDRESS+0x12c))//0x4c))


#definepISR_TIMER1(*(unsigned*)(_IRQ_BASEADDRESS+0x130))//0x50))


#definepISR_TIMER0(*(unsigned*)(_IRQ_BASEADDRESS+0x134))//0x54))


#definepISR_UERR01(*(unsigned*)(_IRQ_BASEADDRESS+0x138))//0x58))


#definepISR_WDT(*(unsigned*)(_IRQ_BASEADDRESS+0x13c))//0x5c))


#definepISR_BDMA1(*(unsigned*)(_IRQ_BASEADDRESS+0x140))//0x60))


#definepISR_BDMA0(*(unsigned*)(_IRQ_BASEADDRESS+0x144))//0x64))


#definepISR_ZDMA1(*(unsigned*)(_IRQ_BASEADDRESS+0x148))//0x68))


#definepISR_ZDMA0(*(unsigned*)(_IRQ_BASEADDRESS+0x14c))//0x6c))


#definepISR_TICK(*(unsigned*)(_IRQ_BASEADDRESS+0x150))//0x70))


#definepISR_EINT4567(*(unsigned*)(_IRQ_BASEADDRESS+0x154))//0x74))


#definepISR_EINT3(*(unsigned*)(_IRQ_BASEADDRESS+0x158))//0x78))


#definepISR_EINT2(*(unsigned*)(_IRQ_BASEADDRESS+0x15c))//0x7c))


#definepISR_EINT1(*(unsigned*)(_IRQ_BASEADDRESS+0x160))//0x80))


#definepISR_EINT0(*(unsigned*)(_IRQ_BASEADDRESS+0x164))//0x84))


For example, if we want to use the Exint4567 interrupt, after defining the interrupt handler Meint4567Isr(), only one statement is needed:


pISR_EINT4567=(int)MEint4567Isr;


This will allow the program to correctly jump to the handler we wrote after an interrupt occurs.


Keywords:uClinux Reference address:Summary of uClinux kernel porting on ARMSYS

Previous article:A Hardware Implementation of a Concentrator Based on ARM
Next article:WLAN Email Mobile Terminal Based on ARM2410

Recommended ReadingLatest update time:2024-11-15 17:01

Design of storage system based on S3C4510B microprocessor and uClinux
1 Introduction For developers of embedded systems, a deep understanding of the addressing principles of their storage systems and effective management of storage systems are of great significance for correctly and efficiently designing the hardware and underlying software programming of embedded systems. Currently, th
[Microcontroller]
Design of storage system based on S3C4510B microprocessor and uClinux
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号