INIT_LIST_HEAD无法初始化链表指针
2012-05-19 19:35
183 查看
解决了函数调用多时系统无响应的问题,现在来解决初始化 buddy 链表头时卡在INIT_LIST_HEAD 宏的问题,把难啃的骨头留在后边,最后再腾出功夫来看中断无法初始化是怎么回事。
函数卡在INIT_LIST_HEAD 宏,无法初始化全局链表数组,该数组的每个元素分别是一组同阶的buddy链表的链表头。数组为全局变量,存储在bss段。既然无法修改bss的内容,尝试在函数内部定义一个连表节点变量,将该变量的两个指针成员指向自身,结果是成功的。查看变量的地址,靠近内存最高端的栈里,这是因为arm的堆栈是满递减结构,从顶向下增长的。再回头看数组的地址:0x00000420,在前4K,这个地址是CPU内部STEPSTONE使用的,那么要解决这个问题就要修改bss段的链接地址了,将其避开前4K地址。做法是将链接脚本中bss段从kernel段上边拿到下边,原链接脚本:
/********************************************************************
*
* @ File Name : link.lds
* @ Date : 2012-03-24
* @ Author : gaofeilong <gaofeilonglcu@163.com>
*
* @ Description: link scripts, determin all section layout
*
* *****************************************************************/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.bootloader :
{
start.o(.text .rodata* .data)
init.o(.text .rodata* .data)
serial.o(.text .rodata* .data)
nand.o(.text .rodata* .data)
}
. = ALIGN(4);
__bss_start = .;
.bss : {*(.bss) }
. = ALIGN(4);
__bss_end = .;
. = ALIGN(4);
.kernel 0x30000000 : AT(0x1000) {*(.text .rodata* .data .bss) }
}
修改后的链接文件:
/********************************************************************
*
* @ File Name : link.lds
* @ Date : 2012-03-24
* @ Author : gaofeilong <gaofeilonglcu@163.com>
*
* @ Description: link scripts, determin all section layout
*
* *****************************************************************/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.bootloader :
{
start.o(.text .rodata* .data)
init.o(.text .rodata* .data)
serial.o(.text .rodata* .data)
nand.o(.text .rodata* .data)
}
. = ALIGN(4);
.kernel 0x30000000 : AT(0x1000) {*(.text .rodata* .data .bss) }
. = ALIGN(4);
__bss_start = .;
.bss : {*(.bss) }
. = ALIGN(4);
__bss_end = .;
}
编译报警:warning: section `.kernel' type changed to PROGBITS,这是看到kernel段中也有bss信息,应该是和下边的bss段信息重叠了,删除kernel中的bss,最后的样子:
/********************************************************************
*
* @ File Name : link.lds
* @ Date : 2012-03-24
* @ Author : gaofeilong <gaofeilonglcu@163.com>
*
* @ Description: link scripts, determin all section layout
*
* *****************************************************************/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.bootloader :
{
start.o(.text .rodata* .data)
init.o(.text .rodata* .data)
serial.o(.text .rodata* .data)
nand.o(.text .rodata* .data)
}
. = ALIGN(4);
.kernel 0x30000000 : AT(0x1000) {*(.text .rodata* .data) }
.= ALIGN(4);
__bss_start = .;
.bss : {*(.bss) }
. = ALIGN(4);
__bss_end = .;
}
再编译,OK通过。
烧到板子上运行,结果正常,能够初始化链表头数组了。
函数卡在INIT_LIST_HEAD 宏,无法初始化全局链表数组,该数组的每个元素分别是一组同阶的buddy链表的链表头。数组为全局变量,存储在bss段。既然无法修改bss的内容,尝试在函数内部定义一个连表节点变量,将该变量的两个指针成员指向自身,结果是成功的。查看变量的地址,靠近内存最高端的栈里,这是因为arm的堆栈是满递减结构,从顶向下增长的。再回头看数组的地址:0x00000420,在前4K,这个地址是CPU内部STEPSTONE使用的,那么要解决这个问题就要修改bss段的链接地址了,将其避开前4K地址。做法是将链接脚本中bss段从kernel段上边拿到下边,原链接脚本:
/********************************************************************
*
* @ File Name : link.lds
* @ Date : 2012-03-24
* @ Author : gaofeilong <gaofeilonglcu@163.com>
*
* @ Description: link scripts, determin all section layout
*
* *****************************************************************/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.bootloader :
{
start.o(.text .rodata* .data)
init.o(.text .rodata* .data)
serial.o(.text .rodata* .data)
nand.o(.text .rodata* .data)
}
. = ALIGN(4);
__bss_start = .;
.bss : {*(.bss) }
. = ALIGN(4);
__bss_end = .;
. = ALIGN(4);
.kernel 0x30000000 : AT(0x1000) {*(.text .rodata* .data .bss) }
}
修改后的链接文件:
/********************************************************************
*
* @ File Name : link.lds
* @ Date : 2012-03-24
* @ Author : gaofeilong <gaofeilonglcu@163.com>
*
* @ Description: link scripts, determin all section layout
*
* *****************************************************************/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.bootloader :
{
start.o(.text .rodata* .data)
init.o(.text .rodata* .data)
serial.o(.text .rodata* .data)
nand.o(.text .rodata* .data)
}
. = ALIGN(4);
.kernel 0x30000000 : AT(0x1000) {*(.text .rodata* .data .bss) }
. = ALIGN(4);
__bss_start = .;
.bss : {*(.bss) }
. = ALIGN(4);
__bss_end = .;
}
编译报警:warning: section `.kernel' type changed to PROGBITS,这是看到kernel段中也有bss信息,应该是和下边的bss段信息重叠了,删除kernel中的bss,最后的样子:
/********************************************************************
*
* @ File Name : link.lds
* @ Date : 2012-03-24
* @ Author : gaofeilong <gaofeilonglcu@163.com>
*
* @ Description: link scripts, determin all section layout
*
* *****************************************************************/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.bootloader :
{
start.o(.text .rodata* .data)
init.o(.text .rodata* .data)
serial.o(.text .rodata* .data)
nand.o(.text .rodata* .data)
}
. = ALIGN(4);
.kernel 0x30000000 : AT(0x1000) {*(.text .rodata* .data) }
.= ALIGN(4);
__bss_start = .;
.bss : {*(.bss) }
. = ALIGN(4);
__bss_end = .;
}
再编译,OK通过。
烧到板子上运行,结果正常,能够初始化链表头数组了。
相关文章推荐
- linux 内核分析之链表解析(list_head)
- Linux利用list_head结构实现双向链表
- linux内核源码“双向链表list_head”续
- Copy List with Random Pointer复制带有随机指针的链表
- 《LeetBook》leetcode题解(19):Remove Nth Node From End of List[E]——双指针解决链表倒数问题
- merge two sort list-leetcode 有序链表合并的二级指针简洁非递归解法
- 深入浅出linux内核源代码之双向链表list_head(上)
- Linked List - 单链表找中点 - 快慢指针
- 深入浅出linux内核源代码之双向链表list_head(上)
- 【LeetCode-面试算法经典-Java实现】【138-Copy List with Random Pointer(拷贝有随机指针的单链表)】
- list_head双向链表的删除问题
- list_head 双向循环链表的结构
- 20150203 【 内核链表 kernel_list.h 】 list_head 使用
- (Linux 内核)双向循环链表list_head
- 双向循环链表list_head
- LIST_HEAD_INIT分析
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序
- 深入浅出linux内核源代码之双向链表list_head(下)
- QT MSVC2013/ vs2013 C2440: “初始化”: 无法从“initializer-list”转换为“***” 错误
- #define LIST_HEAD_INIT(name) { &(name), &(name) } what?!!