一开始都要先设置hdr的两个成员,在针对不同的参数类型(flag),去填写其他参数
struct tag_header { unsigned int size; unsigned int tag; };
struct tag { struct tag_header hdr; union { struct tag_core core; struct tag_mem32 mem; struct tag_cmdline cmdline; } u; };
struct tag_core { unsigned int flags; /* bit 0 = read-only */ unsigned int pagesize; unsigned int rootdev; };
void setup_start_tag() { params = (struct tag*)ATAGS_START_ADDR; params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size(tag_core); params->u.core.flags = 0; params->u.core.pagesize = 4096; params->u.core.rootdev = 0; params = tag_next(params); }
struct tag_mem32 { unsigned int size; unsigned int start; /* physical start address */ };
void setup_memory_tags() { params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size(tag_mem32); params->u.mem.start = SDRAM_START_ADDR; params->u.mem.size = SDRAM_SIZE; params = tag_next(params); }
struct tag_cmdline { char cmdline[1]; /* this is the minimum size */ };
void setup_commandline_tag() { params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof (struct tag_header) + strlen(cmdline) + 1 + 3) >> 2; strcpy(params->u.cmdline.cmdline, cmdline); params = tag_next(params); }
void setup_end_tag() { params->hdr.tag = ATAG_NONE; params->hdr.size = 0; }
kernel_entry(0,2520,ATAGS_START_ADDR);
void boot_linux() { /*1.传递内核起始地址*/ kernel_entry = (void (*)(int, int, uint))LINUX_START_ADDR; /*2.设置核心参数*/ setup_start_tag(); /*3.设置内存参数*/ setup_memory_tags(); /*4.设置命令行参数*/ setup_commandline_tag(); /*5.写入参数结束标志*/ setup_end_tag(); /*6.传入机器码启动内核*/ kernel_entry(0,2520,ATAGS_START_ADDR); //用的mini6410的ID====2250。mini2440的ID是1999。tiny6410原本是2251,但是我的zImage是mini6410的内核文件。 }
//#define unsigned int unsigned int; struct tag_header { unsigned int size; unsigned int tag; }; struct tag_core { unsigned int flags; /* bit 0 = read-only */ unsigned int pagesize; unsigned int rootdev; }; struct tag_mem32 { unsigned int size; unsigned int start; /* physical start address */ }; struct tag_cmdline { char cmdline[1]; /* this is the minimum size */ }; struct tag { struct tag_header hdr; union { struct tag_core core; struct tag_mem32 mem; struct tag_cmdline cmdline; } u; };
#include "string.h" #include "atag.h" #include "common.h" #define uint unsigned int #define LINUX_START_ADDR 0x51000000 #define ATAGS_START_ADDR 0x50000100 #define SDRAM_START_ADDR 0x50000000 #define SDRAM_SIZE 0x0FF00000 #define ATAG_NONE 0x00000000 #define ATAG_CORE 0x54410001 #define ATAG_MEM 0x54410002 #define ATAG_CMDLINE 0x54410009 #define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) #define tag_next(t) ((struct tag *)((unsigned int *)(t) + (t)->hdr.size)) const char* cmdline = "console=ttySAC0,115200 init=/init root=/dev/nfs rw nfsroot=192.168.1.112:/NFS/rootfs_qtopia_qt4 ip=192.168.1.30:192.168.1.112:192.168.1.1:255.255.255.0:XiaoJunjun:eth0:off"; //const char* cmdline = "console=ttySAC0,115200 init=/init"; void (*kernel_entry)(int, int, uint); struct tag* params = NULL; void setup_start_tag() { params = (struct tag*)ATAGS_START_ADDR; params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size(tag_core); params->u.core.flags = 0; params->u.core.pagesize = 4096; params->u.core.rootdev = 0; params = tag_next(params); } void setup_memory_tags() { params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size(tag_mem32); params->u.mem.start = SDRAM_START_ADDR; params->u.mem.size = SDRAM_SIZE; params = tag_next(params); } void setup_commandline_tag() { params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof (struct tag_header) + strlen(cmdline) + 1 + 3) >> 2; strcpy(params->u.cmdline.cmdline, cmdline); params = tag_next(params); } void setup_end_tag() { params->hdr.tag = ATAG_NONE; params->hdr.size = 0; } void boot_linux() { /*1.传递内核起始地址*/ kernel_entry = (void (*)(int, int, uint))LINUX_START_ADDR; /*2.设置核心参数*/ setup_start_tag(); /*3.设置内存参数*/ setup_memory_tags(); /*4.设置命令行参数*/ setup_commandline_tag(); /*5.写入参数结束标志*/ setup_end_tag(); /*6.传入机器码启动内核*/ kernel_entry(0,2520,ATAGS_START_ADDR); //用的mini6410的ID====2250。mini2440的ID是1999。tiny6410原本是2251,但是我的zImage是mini6410的内核文件。 }
/**************************** @File:main.c @ @Tiny6410裸机下学期代码 @网卡测试文件 @Author:小君君 @****************************/ #include "common.h" int main(void) { int num = 1000; led_init();//LED的GPIO初始化 button_init();//按键初始化 led_on();//点亮4颗LED uart_init();//串口初始化 putchar('a'); putchar('\r'); putchar('\n'); putchar('b'); putchar('\r'); putchar('\n'); dma_init();//DMA初始化 dma_start();//启动DMA发送数据到串口 uart_init();//串口再次初始化,使得串口恢复中断或者轮询模式 lcd_init(); lcd_clear_screen(0xFFFFFF); dm9000_init(); //dm9000_arp(); while(1){ printf("=================================================\n\r"); printf("===================JUN-BOOT======================\n\r"); printf("0.Send the ARP to get yhe host's MAC address\n\r"); printf("1.Download the linux kernel from tftp\n\r"); printf("2.Boot linux OS from SDRAM\n\r"); printf("3.Junjun is a houmorous\n\r"); printf("=================================================\n\r"); printf("===================LCD_TEST======================\n\r"); printf("4.清屏\n\r"); printf("5.画横线\n\r"); printf("6.画竖线\n\r"); printf("7.画十字架\n\r"); printf("8.画同心圆\n\r"); printf("9.AD转换\n\r"); printf("10.Send the ARP to get yhe host's MAC address\n\r"); printf("11.Download the linux kernel from tftp\n\r"); printf("12.Boot linux OS from SDRAM\n\r"); printf(" \n\r"); printf("请输入0-12任意一个数字:\n\r"); scanf("%d",&num); switch(num){ case 0: printf("请支持成都国嵌\n\r"); break; case 1: printf("国嵌学院=====打造你的嵌入式人生\n\r"); break; case 2: printf("学ARM,学Linux,学C++,学安卓,学嵌入式,就到成都国嵌学院\n\r"); break; case 3: printf("只要你肯努力,你的明天就会等你!!\n\r"); break; case 4: lcd_clear_screen(0x000000); break; case 5: lcd_clear_screen(0x000000); lcd_draw_hline(HEIGHT/2, 100, WIDTHEIGHT-100, 0xff0000); break; case 6: lcd_clear_screen(0x000000); lcd_draw_vline(WIDTHEIGHT/2, 50, HEIGHT-50, 0xff0000); break; case 7: lcd_clear_screen(0x000000); lcd_draw_cross(HEIGHT/2, WIDTHEIGHT/2, 20, 0x777777); break; case 8: lcd_clear_screen(0x000000); lcd_draw_circle(); break; case 9: read_adc(0); break; case 10: arp_request(); break; case 11: tftp_request("zImage");//一定要放对位置,而且文件名要一致 break; case 12: boot_linux(); break; default: printf("只要你肯努力,你的明天就会等你!!\n\r"); break; } } return 0; }