基于树莓派的嵌入式linux操作系统设计
目录
基于树莓派的嵌入式linux操作系统设计 1
一、设计目的和要求 1
First stage bootloader 1
二、设计思路与方法 6
三、实现的功能及说明 27
在此简单设计了GPIO的功能用于提示系统状态 28
四、使用 29
五、核心源程序代码和界面图 35
六、实现 37
七、心得体会 40
一、设计目的和要求
1.设计目的
树莓派 OS需要有自己的调度程序。如果实现一个调度程序,还必须处理定时器中断。定时器中断意味着操作系统应该支持一些驱动程序并提供系统调用以将它们暴露给用户应用程序。在此基础上编写驱动程序使之在屏幕上写入内容并从键盘读取用户输入的指令。此外,操作系统需要能够加载和执行用户程序,因此需要支持某种文件系统并能够理解某种可执行文件格式。
树莓派搭载了一枚ARM架构64位4核心SOC(BCM2835)主频为700MHZ,SOC为片上操作系统支持精简指令集,并且板载了512MB DDR2内存。该单板机系统支持SD卡Boot启动。在BCM2835启动时会通过Boot目录启动。树莓派启动分为以下步骤
First stage bootloader
树莓派上电后,SoC 中的 bootloader 首先被执行,其作用是挂载 SD 卡上的 FAT32 分区,从而加载下一阶段的 bootloader。这部分程序被固化在 SoC 的 ROM 中,用户无法修改。
Second stage bootloader (bootcode.bin)
这个阶段的 bootloader 会从 SD 卡上检索 GPU 固件,将固件写入 GPU,随后启动 GPU。
GPU firmware (start.elf)
本阶段中,GPU 启动后会检索附加配置文件(config.txt、fixup.dat),根据其内容设置 CPU 运行参数及内存分配情况,随后将用户代码加载至内存,启动 CPU。
User code (kernel8.img)
通常情况下,CPU 启动后便开始执行 kernel8.img 中的指令,初始化操作系统内核,在某些情况下,也可以被 U-BOOT 代替,由 U-BOOT 来加载内核。在树莓派 1 代中,User code 部分被保存在 kernel.img 文件中,2 代中,该文件更名为 kernel7.img,3 代中,该文件更名为 kernel8.img,本课程设计的全部工作,都在该文件上完成。
综上所述,树莓派上电后的初始化工作大多是在 GPU 中完成的(GPU 内的一颗 RSIC 核心用于完成这些操作)。目前树莓派的 GPU bootloader 仍未开源,只以二进制形式发布,因此本课程设计使用了官
方提供的raspberrypi/firmware官方仓库中的bootcode.bin 和 start.elf,直接复制到 SD 卡Boot目录。
树莓派刻录了官方镜像以后boot分区文件展示。我们自制的操作系统会编译成kernel.Img文件替代官方的kernel.img文件。
二、设计思路与方法
1.设计操作系统的基础依赖
本课程设计要完成多进程与内存管理,需要系统时钟定时器和中断。故设计了定时器和中断函数并设置寄存器。
1.1中断向量
- 树莓派Zero搭载的是BCM2835的处理器。BMC2835 ARM1176 是ARMv6版本的。在默认条件下,处理器加电后会自动加载SD卡中的kernel.img到内存0x8000处。
- ARM的中断向量是在地址0x00 - 0x20
- 0x00 复位 reset
- 0x04 未定义指令
- 0x08 软终端 SWI
- 0x0c 指令预取指
- 0x10 数据访问中止
- 0x14 保留
- 0x18 IRQ
- 0x1c FIQ
所以内核加载到内存做的第一件事应该是设置好中断向量。
ARM外设中断表:
Archive member included to satisfy reference by file (symbol) /usr/lib/gcc/arm-none-eabi/4.9.3/fpu/libgcc.a(_divsi3.o) ./object/Graphic.o (__aeabi_idiv) /usr/lib/gcc/arm-none-eabi/4.9.3/fpu/libgcc.a(_dvmd_tls.o) /usr/lib/gcc/arm-none-eabi/4.9.3/fpu/libgcc.a(_divsi3.o) (__aeabi_idiv0) /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/fpu/libg.a(lib_a-memcpy.o) ./object/input.o (memcpy) Allocating common symbols Common symbol size file GpuBufAddr 0x4 ./object/Graphic.o time_out_p 0x18 ./object/timer.o colorB 0x3 ./object/Graphic.o form1_handle 0x4 ./object/debug.o input_status 0x4 ./object/Graphic.o task_stack 0x4400 ./object/Graphic.o task_global 0x8 ./object/task.o rxhead 0x4 ./object/UART.o DesktopHandle 0x4 ./object/Graphic.o MousePic 0x1c ./object/Graphic.o timer_time_out_p 0x5 ./object/timer.o mcursor 0x300 ./object/Graphic.o colorGreen 0x3 ./object/Graphic.o colorWrite 0x3 ./object/Graphic.o task_ready_ll 0x804 ./object/Graphic.o task_ready 0x4 ./object/Graphic.o input_p 0x18 ./object/UART.o colorRed 0x3 ./object/Graphic.o MSG_list 0x4 ./object/Graphic.o input_buf_p 0x40 ./object/UART.o PicLayerTable 0x4 ./object/Graphic.o GpuInfoAddr 0x4 ./object/Graphic.o transparent 0x3 ./object/Graphic.o FreeMemoryTables_p 0x8014 ./object/memory.o MSG_list_ll 0x804 ./object/Graphic.o MouseHaldle 0x4 ./object/Graphic.o colorBule 0x3 ./object/Graphic.o os_timer_ctrl 0xc04 ./object/timer.o colorBlack 0x3 ./object/Graphic.o task_table 0x4c8 ./object/Graphic.o rxtail 0x4 ./object/UART.o task_info 0x154 ./object/Graphic.o rxbuffer 0x1000 ./object/UART.o colorF 0x3 ./object/Graphic.o MSG 0x200 ./object/Graphic.o Memory Configuration Name Origin Length Attributes *default* 0x0000000000000000 0xffffffffffffffff Linker script and memory map [!provide] PROVIDE (__executable_start, 0x8000) 0x0000000000008000 . = 0x8000 .interp *(.interp) .note.gnu.build-id *(.note.gnu.build-id) .hash *(.hash) .gnu.hash *(.gnu.hash) .dynsym *(.dynsym) .dynstr *(.dynstr) .gnu.version *(.gnu.version) .gnu.version_d *(.gnu.version_d) .gnu.version_r *(.gnu.version_r) .rel.init *(.rel.init) .rela.init *(.rela.init) .rel.text *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) .rela.text *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) .rel.fini *(.rel.fini) .rela.fini *(.rela.fini) .rel.rodata *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) .rela.rodata *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) .rel.data.rel.ro *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) .rela.data.rel.ro *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) .rel.data *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) .rela.data *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) .rel.tdata *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) .rela.tdata *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) .rel.tbss *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) .rela.tbss *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) .rel.ctors *(.rel.ctors) .rela.ctors *(.rela.ctors) .rel.dtors *(.rel.dtors) .rela.dtors *(.rela.dtors) .rel.got *(.rel.got) .rela.got *(.rela.got) .rel.bss *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) .rela.bss *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) .rel.iplt 0x0000000000008000 0x0 [!provide] PROVIDE (__rel_iplt_start, .) *(.rel.iplt) .rel.iplt 0x0000000000008000 0x0 ./object/Graphic.o [!provide] PROVIDE (__rel_iplt_end, .) .rela.iplt 0x0000000000008000 0x0 [!provide] PROVIDE (__rela_iplt_start, .) *(.rela.iplt) [!provide] PROVIDE (__rela_iplt_end, .) .rel.plt *(.rel.plt) .rela.plt *(.rela.plt) .init *(SORT(.init)) .plt *(.plt) .iplt 0x0000000000008000 0x0 *(.iplt) .iplt 0x0000000000008000 0x0 ./object/Graphic.o .text 0x0000000000008000 0xfceb0 *(.text.unlikely .text.*_unlikely .text.unlikely.*) *(.text.exit .text.exit.*) *(.text.startup .text.startup.*) .text.startup 0x0000000000008000 0xcc /tmp/cclqMRGF.o 0x0000000000008000 _start 0x0000000000008088 _get_stack_pointer 0x0000000000008094 _enable_interrupts 0x00000000000080a4 _disable_interrupts 0x00000000000080b4 reboot 0x00000000000080b8 PUT32 0x00000000000080c0 GET32 0x00000000000080c8 dummy *(.text.hot .text.hot.*) *(.text .stub .text.* .gnu.linkonce.t.*) .text 0x00000000000080cc 0x451c ./object/Graphic.o 0x00000000000080cc init_screen_layer 0x0000000000008360 init_screen 0x0000000000008548 DrawDot 0x0000000000008624 DrawDot_to_layer 0x00000000000086fc DrawLine 0x000000000000872c DrawBlock 0x00000000000087c4 DrawBlock_to_layer 0x000000000000886c DrawBlockByMemory 0x0000000000008888 drawCharacter 0x0000000000008b04 drawCharacter_to_layer 0x0000000000008de0 drawString 0x0000000000008e40 drawString_to_layer 0x0000000000008eb0 drawDec 0x0000000000008fac drawDec_to_layer 0x00000000000090b8 drawFlt 0x00000000000090e0 drawHex 0x000000000000923c drawHex_to_layer 0x00000000000093c4 drawBin 0x00000000000094a4 drawBin_to_layer 0x0000000000009590 drawStringF_to_layer 0x00000000000099a0 drawStringF 0x0000000000009d58 os_printf 0x000000000000a128 draw_to_screen 0x000000000000a268 draw_to_screen_rect 0x000000000000a410 PicLayerTable_init 0x000000000000a4c8 add_pic 0x000000000000a5e4 add_pic_to_layer 0x000000000000a6e4 rm_picture 0x000000000000a78c rm_from_layer 0x000000000000a954 get_LayerIndex_by_PicIndex 0x000000000000a9a4 get_PicIndex_by_LayerIndex 0x000000000000a9e4 set_pic_to_top 0x000000000000abbc set_picture_position 0x000000000000ace4 pic_layer_reflash_rect 0x000000000000aeb8 pic_layer_reflash 0x000000000000af90 is_inside 0x000000000000b074 inside_rect 0x000000000000bb40 move_pic_layer 0x000000000000c1c4 move_pic_layer_sub 0x000000000000c404 copy_bmp_to_piclayer .text 0x000000000000c5e8 0x103c ./object/linkedlist.o 0x000000000000c5e8 ll_init 0x000000000000c664 ll_add_to_head 0x000000000000c744 ll_add_to_tail 0x000000000000c834 ll_add_by_order 0x000000000000c9c4 ll_add_after_id 0x000000000000cb14 ll_remove_by_id 0x000000000000cbf8 ll_remove_head 0x000000000000cc30 ll_remove_tail 0x000000000000cc78 ll_get_next_id 0x000000000000cd20 ll_get_next_value 0x000000000000cddc ll_get_prior_id 0x000000000000ce84 ll_get_prior_value 0x000000000000cf40 ll_get_count 0x000000000000cf68 ll_get_head_id 0x000000000000cf90 ll_get_tail_id 0x000000000000cfb8 ll_get_max_id 0x000000000000cfe0 ll_get_min_id 0x000000000000d008 ll_get_value 0x000000000000d0b0 ll_get_free_id 0x000000000000d16c ll_reflash_head_and_tail 0x000000000000d1a4 ll_link 0x000000000000d25c ll_rm_link 0x000000000000d2e4 ll_get_max 0x000000000000d414 ll_get_min 0x000000000000d544 ll_set_value .text 0x000000000000d624 0x38 ./object/interrupt.o 0x000000000000d624 undifined_instruction_vector 0x000000000000d630 software_interrupt_vector 0x000000000000d63c prefetch_abort_vector 0x000000000000d648 data_abort_vector 0x000000000000d654 fast_interrupt_vector .text 0x000000000000d65c 0x135c ./object/task.o 0x000000000000d65c task_init 0x000000000000d738 task_idle 0x000000000000d744 task_create 0x000000000000d8d4 task_get_id 0x000000000000d9d4 task_run 0x000000000000dba0 task_schedule 0x000000000000dcac task_delete 0x000000000000e06c task_lock_schedule 0x000000000000e090 task_unlock_schedule 0x000000000000e0b4 task_wait 0x000000000000e0c8 task_wait_abort 0x000000000000e0dc task_suspend 0x000000000000e0f0 task_resume 0x000000000000e104 task_send_msg 0x000000000000e214 MSG_dispose 0x000000000000e3d8 task_recevie_msg 0x000000000000e49c task_recevie_msg_abort 0x000000000000e4b0 task_semaphore_cteate 0x000000000000e4c4 task_semaphore_wait 0x000000000000e4d8 task_semaphore_wait_abort 0x000000000000e4ec task_semaphore_post 0x000000000000e500 task_semaphore_delete 0x000000000000e514 task_manager .text 0x000000000000e9b8 0x4d8 ./object/gpio.o 0x000000000000e9b8 gpio_init 0x000000000000e9dc GPIO_SET_GPFSEL 0x000000000000ea94 bcm2835_peri_set_bits 0x000000000000eaf0 bcm2835_peri_write 0x000000000000eb28 bcm2835_peri_read 0x000000000000eb64 GPIO_SET_GPSET 0x000000000000ec10 GPIO_SET_GPCLR 0x000000000000ecbc GET_GPFSEL_ADDR 0x000000000000ed78 GET_GPSET_ADDR 0x000000000000edb8 GET_GPCLR_ADDR 0x000000000000edf8 blink_GPIO16 0x000000000000ee44 blink_GPIO19 .text 0x000000000000ee90 0xd04 ./object/memory.o 0x000000000000ee90 momory_init 0x000000000000ef28 total_free_memory_size 0x000000000000efac os_malloc 0x000000000000f198 os_free 0x000000000000fb18 os_memcpy .text 0x000000000000fb94 0x404 ./object/main.o 0x000000000000fb94 os_main 0x000000000000ff84 exit .text 0x000000000000ff98 0x9ec ./object/debug.o 0x000000000000ff98 deb_GPIO 0x000000000000ffbc deb_screen 0x0000000000010100 deb_os_printf 0x0000000000010144 deb_timer 0x0000000000010188 deb_timer_refalsh 0x000000000001034c deb_linedlist 0x000000000001043c deb_linedlist_reflash 0x000000000001059c deb_task 0x0000000000010614 task1 0x00000000000106a4 task2 0x0000000000010750 dbg_UART 0x0000000000010760 dbg_memory 0x000000000001082c dbg_input 0x00000000000108cc dbg_bmp 0x0000000000010974 dbg_form .text 0x0000000000010984 0x398 ./object/UART.o 0x0000000000010984 uart_init 0x0000000000010b3c uart_putc 0x0000000000010b88 UART_irq_handler .text 0x0000000000010d1c 0x218 ./object/GPU.o 0x0000000000010d1c init_GPU 0x0000000000010de4 GPU_SendMail 0x0000000000010e80 GPU_RecMail .text 0x0000000000010f34 0x210 ./object/fifo.o 0x0000000000010f34 fifo_init 0x0000000000010fb0 fifo_put 0x0000000000011074 fifo_get .text 0x0000000000011144 0x3bc ./object/input.o 0x0000000000011144 input_fifo_dispose 0x000000000001123c input_keyboard 0x0000000000011250 init_mouse_cursor 0x0000000000011444 input_mouse_init .text 0x0000000000011500 0x1050 ./object/form.o 0x0000000000011500 form1 0x0000000000012208 form1_dispose 0x00000000000124fc textbox 0x0000000000012518 button 0x0000000000012534 ctrlbox .text 0x0000000000012550 0x820 ./object/timer.o 0x0000000000012550 sleep 0x00000000000125e0 init_arm_timer 0x000000000001265c init_os_timer_ctrl 0x000000000001272c set_os_timer 0x0000000000012808 get_os_timer_id 0x000000000001288c os_timer_insert_pointer 0x0000000000012978 free_os_timer 0x00000000000129f4 os_timer_remove_pointer 0x0000000000012a70 os_timer_ctrl_reflash 0x0000000000012d38 time_out_msg .text 0x0000000000012d70 0x6c ./object/startup.o 0x0000000000012d70 _cstartup *fill* 0x0000000000012ddc 0x4 .text 0x0000000000012de0 0xf1d74 /tmp/ccdglB7y.o 0x0000000000012de0 font 0x00000000000135e0 bmp 0x0000000000013916 bg_bmp 0x00000000000fd5ee color_bmp .text 0x0000000000104b54 0x120 /tmp/cch1UAiB.o 0x0000000000104b54 _interrupt_vector_ .text 0x0000000000104c74 0x0 /tmp/ccyTCouD.o .text 0x0000000000104c74 0x0 /tmp/cclqMRGF.o .text 0x0000000000104c74 0x148 /usr/lib/gcc/arm-none-eabi/4.9.3/fpu/libgcc.a(_divsi3.o) 0x0000000000104c74 __aeabi_idiv 0x0000000000104c74 __divsi3 0x0000000000104d9c __aeabi_idivmod .text 0x0000000000104dbc 0x4 /usr/lib/gcc/arm-none-eabi/4.9.3/fpu/libgcc.a(_dvmd_tls.o) 0x0000000000104dbc __aeabi_ldiv0 0x0000000000104dbc __aeabi_idiv0 .text 0x0000000000104dc0 0x0 /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/fpu/libg.a(lib_a-memcpy.o) .text.memcpy 0x0000000000104dc0 0xf0 /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/fpu/libg.a(lib_a-memcpy.o) 0x0000000000104dc0 memcpy *(.gnu.warning) *(.glue_7t) .glue_7t 0x0000000000104eb0 0x0 linker stubs *(.glue_7) .glue_7 0x0000000000104eb0 0x0 linker stubs *(.vfp11_veneer) .vfp11_veneer 0x0000000000104eb0 0x0 linker stubs *(.v4_bx) .v4_bx 0x0000000000104eb0 0x0 linker stubs