在对硬盘进行读写操作时,第一件要做的事就是对硬盘进行分区工作,也就是向MBR(硬盘的第一个扇区)里的分区表中写入每个分区的起始扇区号等信息,有关MBR的结构可以参考...
Offset 字节偏移值 |
Size (bytes) 字节大小 |
Description 描述 |
---|---|---|
0 |
436 (to 446, if you need a little extra) 436字节(如果不需要下面10字节的disk ID字段的话则可以扩充到446字节) |
MBR Bootstrap (flat binary executable code) MBR引导程序(二进制可执行代码) |
0x1b4 | 10字节 |
Optional "unique" disk ID 可选的唯一的磁盘ID |
0x1be | 64字节(下面4个分区表项的总字节大小) |
MBR Partition Table, with 4 entries (below) MBR分区表,包含4个分区表项目 |
0x1be | 16字节 |
First partition table entry 第一个分区表项 |
0x1ce | 16字节 |
Second partition table entry 第二个分区表项 |
0x1de | 16字节 |
Third partition table entry 第三个分区表项 |
0x1ee | 16字节 |
Fourth partition table entry 第四个分区表项 |
0x1fe | 2 |
(0x55, 0xAA) "Valid bootsector" signature bytes 一般是0x55, 0xAA的两个字节,用于表示该扇区是有效的启动扇区 |
Element (offset) 字段的字节偏移值 |
Size 字节大小 |
Description 描述 |
---|---|---|
0 | 1个字节 |
Boot indicator bit flag: 0 = no, 0x80 = bootable (or "active") 启动引导位,0表示普通的非引导分区,0x80则表示该分区是可引导分区,也就是该分区里包含启动引导相关的代码 |
1 | 1个字节 |
Starting head 起始磁头号 |
2 |
6 bits 6个二进制位 |
Starting sector (Bits 6-7 are the upper two bits for the Starting Cylinder field.) 起始扇区号(该字段所在字节的低6位表示起始扇区号,位6和位7则用于下面的起始柱面号) |
3 |
10 bits 10个二进制位 |
Starting Cylinder 起始柱面号 |
4 | 1个字节 |
System ID 系统ID值,用于标识分区所使用的文件系统 |
5 | 1个字节 |
Ending Head 结束磁头号 |
6 |
6 bits 6个二进制位 |
Ending Sector (Bits 6-7 are the upper two bits for the ending cylinder field) 结束扇区号(同样的,所在字节的低6位表示扇区号,位6和位7则用于下面的柱面号) |
7 |
10 bits 10个二进制位 |
Ending Cylinder 结束柱面号 |
8 |
dword 4个字节 |
Relative Sector (to start of partition -- also equals the partition's starting LBA value) 该分区的起始扇区的lba(逻辑块地址) |
12 |
dword 4个字节 |
Total Sectors in partition 该分区拥有的总扇区数 |
ID Name
0x00 Empty
0x01 DOS 12-bit FAT
0x02 XENIX root
0x03 XENIX /usr
0x04 DOS 3.0+ 16-bit FAT (up to 32M)
0x05 DOS 3.3+ Extended Partition
0x06 DOS 3.31+ 16-bit FAT (over 32M)
0x07 OS/2 IFS (e.g., HPFS)
0x07 Windows NT NTFS
0x07 exFAT
0x07 Advanced Unix
0x07 QNX2.x pre-1988 (see below under IDs 4d-4f)
0x08 OS/2 (v1.0-1.3 only)
0x08 AIX boot partition
0x08 SplitDrive
0x08 Commodore DOS
0x08 DELL partition spanning multiple drives
0x08 QNX 1.x and 2.x ("qny")
0x09 AIX data partition
0x09 Coherent filesystem
0x09 QNX 1.x and 2.x ("qnz")
0x0a OS/2 Boot Manager
0x0a Coherent swap partition
0x0a OPUS
0x0b WIN95 OSR2 FAT32
0x0c WIN95 OSR2 FAT32, LBA-mapped
0x0d SILICON SAFE
0x0e WIN95: DOS 16-bit FAT, LBA-mapped
0x0f WIN95: Extended partition, LBA-mapped
0x10 OPUS
0x11 Hidden DOS 12-bit FAT
0x11 Leading Edge DOS 3.x logically sectored FAT
0x12 Configuration/diagnostics partition
0x14 Hidden DOS 16-bit FAT <32M
0x14 AST DOS with logically sectored FAT
0x16 Hidden DOS 16-bit FAT >=32M
0x17 Hidden IFS (e.g., HPFS)
0x18 AST SmartSleep Partition
0x19 Unused
0x1b Hidden WIN95 OSR2 FAT32
0x1c Hidden WIN95 OSR2 FAT32, LBA-mapped
0x1e Hidden WIN95 16-bit FAT, LBA-mapped
0x20 Unused
0x21 Reserved
0x21 Unused
0x22 Unused
0x23 Reserved
0x24 NEC DOS 3.x
0x26 Reserved
0x27 PQservice
0x27 Windows RE hidden partition
0x27 MirOS partition
0x27 RouterBOOT kernel partition
.............................................
|
/* fdisk -- 磁盘分区工具 */ ....................................................... int main(VOID * task, int argc, char * argv[]) { ....................................................... FDISK_PARAM param = {0}; /* 通过parse_param函数,将用户的参数设置到param结构体变量中, 例如,start参数的值会被设置到param.start成员, num参数的值会被设置到param.num成员 */ if(parse_param(¶m, argc, argv) == -1) return -1; UINT8 *buffer = (UINT8 *)syscall_umalloc(ATA_SECTOR_SIZE+5); UINT32 ide_index = param.hd; UINT32 lba = 0; // MBR IDE_DEVICE * ide_devices = (IDE_DEVICE *)syscall_ata_get_ide_info(); ....................................................... /* 通过syscall_ide_ata_access系统调用来读取0号扇区(MBR)的 数据到buffer缓冲里,lba(逻辑块地址)在之前 已经被设置为了0 */ SINT32 ata_ret = syscall_ide_ata_access(0, ide_index, lba, 1, buffer); // read MBR ....................................................... MBR_PT * partition = (MBR_PT *)(buffer + MBR_PT_START); /* 通过用户设置的pt参数来定位到buffer缓冲中 的指定分区 */ partition += (param.pt - 1); /* 将不需要的flag(分区引导标志)字段设置为0, 以及将不需要的head(起始磁头号),sec_cyl(起始柱面号)等 设置为0xff(二进制位的值全部设置为1,以表示无效的值), fs_type即文件系统类型字段设置为用户type参数所指定的值, startLBA即起始逻辑块地址字段设置为用户start参数所指定 的值,secNum即分区拥有的总扇区数字段设置为用户num参数 所指定的值。 */ partition->flag = 0; partition->head = partition->end_head = (param.num !=0) ? 0xff : 0; partition->sec_cyl = partition->end_sec_cyl = (param.num !=0) ? 0xffff : 0; partition->fs_type = param.type; partition->startLBA = param.start; partition->secNum = param.num; /* 对用户设置的起始扇区号进行必要的调整,让其按照2个扇区 进行对齐,因为zenglOX里使用的逻辑块都是2个磁盘扇区的大小 */ partition->startLBA = (partition->startLBA % 2 == 0) ? partition->startLBA : (partition->startLBA + 1); partition->secNum = (partition->secNum % 2 == 0) ? partition->secNum : (partition->secNum + 1); /* 对用户设置的参数进行必要的检测,不符合要求的设置则返回错误信息。 */ if(partition->secNum != 0 && partition->startLBA == 0) partition->startLBA = 2; if(partition->secNum != 0 && (partition->startLBA + partition->secNum - 1) > ide_devices[ide_index].Size) { syscall_monitor_write("your startLBA + secNum out of range, ide_index ["); syscall_monitor_write_dec(ide_index); syscall_monitor_write("] Last LBA is "); syscall_monitor_write_dec(ide_devices[ide_index].Size); syscall_monitor_put('\n'); syscall_ufree(buffer); return -1; } if(check_partition(partition, (MBR_PT *)(buffer + MBR_PT_START)) == -1) { syscall_ufree(buffer); return -1; } /* 最后通过syscall_ide_ata_access系统调用将buffer缓冲区里设置过 的分区表信息写入到硬盘的MBR里。 */ ata_ret = syscall_ide_ata_access(1, ide_index, lba, 1, buffer); if(ata_ret == -1) { syscall_monitor_write("\nata write sector failed for ide index ["); syscall_monitor_write_dec(ide_index); syscall_monitor_write("]\n"); syscall_ufree(buffer); return -1; } else syscall_monitor_write("\nfdisk write MBR success , you can use \"fdisk -l ide_index\" to see it! \n"); syscall_ufree(buffer); return 0; ....................................................... } |
/* fdisk -- 磁盘分区工具 */ ....................................................... int main(VOID * task, int argc, char * argv[]) { ....................................................... if(strcmp(argv[1],"-l")==0) { UINT32 ide_index = strToUInt(argv[2]); UINT32 lba = 0; // MBR UINT8 * buffer = (UINT8 *)syscall_umalloc(ATA_SECTOR_SIZE+5); IDE_DEVICE * ide_devices = (IDE_DEVICE *)syscall_ata_get_ide_info(); ....................................................... /* 通过syscall_ide_ata_access系统调用来读取0号扇区(MBR)的 数据到buffer缓冲里,lba(逻辑块地址)在之前 已经被设置为了0 */ SINT32 ata_ret = syscall_ide_ata_access(0, ide_index, lba, 1, buffer); // read MBR ....................................................... /* 将buffer(即MBR缓冲)里的分区表的起始位置赋值给partition指针变量 */ MBR_PT * partition = (MBR_PT *)(buffer + MBR_PT_START); SINT32 i; /* 通过for循环,将4个分区表的信息给依次显示出来 */ for(i=0;i < 4;i++,partition++) { syscall_monitor_write("["); syscall_monitor_write_dec(i+1); syscall_monitor_write("] start LBA: "); syscall_monitor_write_dec(partition->startLBA); syscall_monitor_write(" Total Sectors: "); syscall_monitor_write_dec(partition->secNum); if(partition->secNum != 0) { syscall_monitor_write(" ["); /* 通过分区的总扇区数来计算出分区的尺寸大小, 并根据尺寸大小来设置具体的单位,比如MB, KB以及Byte */ if(partition->secNum * 512 / 1024 / 1024 != 0) { syscall_monitor_write_dec(partition->secNum * 512 / 1024 / 1024); syscall_monitor_write("MB]"); } else if(partition->secNum * 512 / 1024 != 0) { syscall_monitor_write_dec(partition->secNum * 512 / 1024); syscall_monitor_write("KB]"); } else { syscall_monitor_write_dec(partition->secNum * 512); syscall_monitor_write("Byte]"); } } syscall_monitor_write(" filesystem: "); /* 根据分区表的System ID字段即下面的 partition->fs_type成员的值来判断分区所设置 的文件系统类型,zenglfs文件系统的类型值为0x23, 即下面MBR_FS_TYPE_ZENGLFS宏所对应的值。如果fs_type 类型值为MBR_FS_TYPE_EMPTY即0的话,就说明该分区表是 empty(空的)。其他的文件系统类型值,目前统一显示为other, 以表示zenglOX目前不能识别和处理的分区类型。 */ switch(partition->fs_type) { case MBR_FS_TYPE_ZENGLFS: syscall_monitor_write(" zenglfs"); break; case MBR_FS_TYPE_EMPTY: syscall_monitor_write(" empty"); break; default: syscall_monitor_write(" other"); break; } syscall_monitor_write("\n"); } syscall_ufree(buffer); return 0; } ....................................................... } |
/*zlox_zenglfs.h -- the zenglfs header*/ .............................................. #define ZLOX_ZLFS_SUPER_BLOCK_SIGN 0x53464c5a // ZLFS .............................................. typedef struct _ZLOX_ZLFS_SUPER_BLOCK { ZLOX_UINT32 sign; ZLOX_UINT32 startLBA; ZLOX_UINT32 TotalBlock; ZLOX_UINT32 TotalInode; ZLOX_UINT32 GroupAddr; ZLOX_UINT32 GroupCount; ZLOX_UINT32 GroupBlocks; ZLOX_UINT32 BlockBitMapBlockAddr; ZLOX_UINT32 BlockMapBlocks; ZLOX_UINT32 InodeBitMapBlockAddr; ZLOX_UINT32 InodeMapBlocks; ZLOX_UINT32 InodeTableBlockAddr; ZLOX_UINT32 allocBlocks; ZLOX_UINT32 allocInodes; } ZLOX_ZLFS_SUPER_BLOCK; .............................................. |
/*zlox_zenglfs.h -- the zenglfs header*/
..............................................
typedef struct _ZLOX_GROUP_INFO
{
ZLOX_UINT32 allocBlocks;
ZLOX_UINT32 allocInodes;
} ZLOX_GROUP_INFO;
|
#define ZLOX_ZLFS_INODE_TYPE_DIRECTORY 0x4000 #define ZLOX_ZLFS_INODE_TYPE_REGULAR 0x8000 ............................................ struct _ZLOX_INODE_DATA { ZLOX_UINT16 type; ZLOX_UINT32 size; ZLOX_UINT32 totalblk; ZLOX_UINT32 dirent_block; ZLOX_UINT32 dirent_idx; ZLOX_UINT32 dir_inode; ZLOX_UINT32 dir_item_num; ZLOX_UINT32 blockAddr[12]; ZLOX_UINT32 SinglyBlockAddr; ZLOX_UINT32 DoublyBlockAddr; ZLOX_UINT32 TriplyBlockAddr; ZLOX_UINT8 reserve[42]; } __attribute__((packed)); typedef struct _ZLOX_INODE_DATA ZLOX_INODE_DATA; |
struct _ZLOX_ZLFS_DIR_ENTRY { ZLOX_UINT32 inode; ZLOX_UINT16 type; ZLOX_UINT8 namelength; ZLOX_CHAR name[57]; } __attribute__((packed)); typedef struct _ZLOX_ZLFS_DIR_ENTRY ZLOX_ZLFS_DIR_ENTRY; |
/* format -- 磁盘格式化工具 */ .................................................. int main(VOID * task, int argc, char * argv[]) { .................................................. FORMAT_PARAM param = {0}; /* 先通过parse_param函数将用户输入的参数设置到 param结构体变量。 */ if(parse_param(¶m, argc, argv) == -1) return -1; UINT8 *buffer = (UINT8 *)syscall_umalloc(ATA_SECTOR_SIZE * 2); UINT32 ide_index = param.hd; UINT32 lba = 0; // MBR IDE_DEVICE * ide_devices = (IDE_DEVICE *)syscall_ata_get_ide_info(); .................................................. /* 将lba对应的0号扇区即MBR里的数据读取到buffer缓冲 */ SINT32 ata_ret = syscall_ide_ata_access(IDE_ATA_READ, ide_index, lba, 1, buffer); // read MBR .................................................. MBR_PT * partition_ptr = (MBR_PT *)(buffer + MBR_PT_START); partition_ptr += (param.pt - 1); MBR_PT partition = (*partition_ptr); /* 因为要为inode array节点数组预留一段空间,每个 节点占用128字节,而节点数组是1024的倍数(一个节点位图为128 字节即1024个二进制位,每个二进制代表一个文件节点的占用情况), 因此节点数组最少需要预留1024 * 128 = 131072即128K字节的空间, 在节点数组前还有5个部分如super block部分, 每个部分按最小1K即一个逻辑块来算, 那么,就需要128K + 5K = 133K,此外,文件节点还需要一些空间来存储 内容数据,因此最小的分区大小至少要200K以上。 而下面的450个扇区的尺寸为450 * 512 = 230400即225K字节的大小, 符合要求,所以,目前就以450个扇区作为最小的可供格式化的分区扇区数。 */ if(partition.secNum < 450) { syscall_monitor_write("this partition is too small , must at least have 450 sectors \n"); syscall_ufree(buffer); return -1; } else if(partition.fs_type != MBR_FS_TYPE_ZENGLFS) { syscall_monitor_write("this partition is not zenglfs \n"); syscall_ufree(buffer); return -1; } /* partition.startLBA + 2就可以跳过分区的Reserved预留块,而 定位到super block超级块 */ lba = partition.startLBA + 2; /*将超级块的内容读取出来,因为一个逻辑块是2个扇区的大小,因此, 下面就一次读取了2个扇区的数据*/ syscall_ide_ata_access(IDE_ATA_READ, ide_index, lba, 2, buffer); // read superblock SUPER_BLOCK * superblock_ptr = (SUPER_BLOCK *)buffer; /*下面对超级块的各个字段依次进行设置*/ superblock_ptr->sign = SUPER_BLOCK_SIGN; superblock_ptr->startLBA = partition.startLBA; superblock_ptr->TotalBlock = partition.secNum / 2; UINT32 group = superblock_ptr->TotalBlock / (1024 * 8) + ((superblock_ptr->TotalBlock % (1024 * 8) != 0) ? 1 : 0); superblock_ptr->TotalInode = group * 128 * 8; superblock_ptr->GroupAddr = 2; superblock_ptr->GroupCount = group; superblock_ptr->GroupBlocks = (group / 128) + ((group % 128 !=0) ? 1 : 0); superblock_ptr->BlockBitMapBlockAddr = superblock_ptr->GroupAddr + superblock_ptr->GroupBlocks; superblock_ptr->BlockMapBlocks = group; superblock_ptr->InodeBitMapBlockAddr = superblock_ptr->BlockBitMapBlockAddr + group; superblock_ptr->InodeMapBlocks = (group / 8) + ((group % 8 !=0) ? 1 : 0); superblock_ptr->InodeTableBlockAddr = superblock_ptr->InodeBitMapBlockAddr + (group / 8) + ((group % 8 !=0) ? 1 : 0); superblock_ptr->allocBlocks = 2 + superblock_ptr->GroupBlocks + superblock_ptr->BlockMapBlocks + superblock_ptr->InodeMapBlocks + group * 128; superblock_ptr->allocInodes = 1; syscall_ide_ata_access(IDE_ATA_WRITE, ide_index, lba, 2, buffer); SUPER_BLOCK superblock = (*superblock_ptr); UINT32 i,j,t = superblock.allocBlocks, gsz = (1024 / sizeof(GROUP_INFO)); GROUP_INFO * groupinfo; BOOL needClear = FALSE; memset(buffer, 0, ATA_SECTOR_SIZE * 2); /*设置group数组里的各个group信息*/ for(i = 0;i < superblock.GroupBlocks;i++) { lba = (superblock.GroupAddr + i) * 2 + superblock.startLBA; groupinfo = (GROUP_INFO *)buffer; if(i == 0) { groupinfo->allocInodes = 1; needClear = TRUE; } if(t != 0) { for(j=0;t != 0 && j < gsz;j++,groupinfo++) { if(t >= 8192) { groupinfo->allocBlocks = 8192; t -= 8192; } else if(t < 8192) { groupinfo->allocBlocks = t; t = 0; } } needClear = TRUE; } syscall_ide_ata_access(IDE_ATA_WRITE, ide_index, lba, 2, buffer); if(needClear == TRUE) { memset(buffer, 0, ATA_SECTOR_SIZE * 2); needClear = FALSE; } } t = superblock.allocBlocks; /*因为super block等需要占用一些逻辑块,因此将逻辑块位图中 对应的二进制位设置为占用状态*/ for(i = 0;i < superblock.BlockMapBlocks;i++) { lba = (superblock.BlockBitMapBlockAddr + i) * 2 + superblock.startLBA; if(t >= 8192) { memset(buffer, 0xff, ATA_SECTOR_SIZE * 2); t -= 8192; needClear = TRUE; } else if(t > 0 && t < 8192) { for(j = 0;j < t;j++) set_bitmap((UINT32 *)buffer, j); t = 0; needClear = TRUE; } syscall_ide_ata_access(IDE_ATA_WRITE, ide_index, lba, 2, buffer); if(needClear == TRUE) { memset(buffer, 0, ATA_SECTOR_SIZE * 2); needClear = FALSE; } } /*format在格式化时会设置一个root根目录的文件节点,因此, 下面将文件节点位图中对应的二进制位设置为占用状态*/ for(i = 0;i < superblock.InodeMapBlocks;i++) { lba = (superblock.InodeBitMapBlockAddr + i) * 2 + superblock.startLBA; if(i == 0) { set_bitmap((UINT32 *)buffer, 0); needClear = TRUE; } syscall_ide_ata_access(IDE_ATA_WRITE, ide_index, lba, 2, buffer); if(needClear == TRUE) { memset(buffer, 0, ATA_SECTOR_SIZE * 2); needClear = FALSE; } } INODE_DATA * root_inode = (INODE_DATA *)buffer; /*设置root根目录的文件节点,其实就是简单的将该文件节点 的类型设置为目录类型,至于文件节点的内容则只有在使用过程 中才会进行分配*/ root_inode->type = INODE_TYPE_DIRECTORY; lba = superblock.InodeTableBlockAddr * 2 + superblock.startLBA; syscall_ide_ata_access(IDE_ATA_WRITE, ide_index, lba, 2, buffer); // write root inode syscall_ufree(buffer); syscall_monitor_write("\nformat success , you can use \"format -l ide_index ptnum\" to see it! \n"); return 0; .................................................. } |
// mount.c -- 挂载文件系统的程式 #include "common.h" #include "syscall.h" /* mount工具可以加载cdrom到iso目录,也可以将硬盘里格式化过的zenglfs分区给加载到hd目录, 当使用mount iso命令时,会通过syscall_mount_iso()系统调用将cdrom加载到iso目录 当使用类似 mount hd 0 1 命令时,则可以将0号IDE硬盘的1号分区给加载到hd目录 iso和hd是内核固定设置好的目录,目前不可以加载到其他的目录名上 */ int main(VOID * task, int argc, char * argv[]) { UNUSED(task); if(argc == 2 && strcmp(argv[1],"iso")==0) { int ret = syscall_mount_iso(); if(ret != 0) syscall_monitor_write("mount iso to [iso] success! you can use \"ls iso\" to see " "the contents of iso directory"); else syscall_monitor_write("mount iso failed..."); } else if(argc == 4 && strcmp(argv[1],"hd")==0) { UINT32 ide_index = strToUInt(argv[2]); UINT32 pt = strToUInt(argv[3]); int ret = syscall_mount_zenglfs(ide_index, pt); if(ret != 0) syscall_monitor_write("mount to [hd] success! you can use \"ls hd\" to see " "the contents of hd directory"); } else syscall_monitor_write("usage: mount [iso][hd ide_index pt]"); return 0; } |
// 挂载硬盘分区到hd目录下
ZLOX_FS_NODE * zlox_mount_zenglfs(ZLOX_UINT32 ide_index, ZLOX_UINT32 pt)
{
........................................................
zenglfs_root = (ZLOX_FS_NODE *)zlox_kmalloc(sizeof(ZLOX_FS_NODE));
zlox_memset((ZLOX_UINT8 *)zenglfs_root, 0 , sizeof(ZLOX_FS_NODE));
zlox_strcpy(zenglfs_root->name, "hd");
zenglfs_root->mask = zenglfs_root->uid = zenglfs_root->gid = zenglfs_root->length = 0;
zenglfs_root->inode = 1;
zenglfs_root->flags = ZLOX_FS_DIRECTORY;
zenglfs_root->read = 0;
zenglfs_root->write = 0;
zenglfs_root->open = 0;
zenglfs_root->close = 0;
zenglfs_root->readdir = &zlox_zenglfs_readdir;
zenglfs_root->writedir = &zlox_zenglfs_writedir;
zenglfs_root->finddir = &zlox_zenglfs_finddir;
zenglfs_root->ptr = 0;
zenglfs_root->impl = 0;
zenglfs_ide_index = ide_index;
zlox_kfree(buffer);
return zenglfs_root;
}
|
// zlox_keyboard.c implement interrupt and functions of keyboard
..................................................
static ZLOX_VOID zlox_keyboard_callback(/*ZLOX_ISR_REGISTERS * regs*/)
{
ZLOX_UINT32 key = zlox_inb(0x60);
ZLOX_UINT32 key_ascii = 0;
ZLOX_UINT32 key_code = 0;
ZLOX_UINT32 scanMaxNum = sizeof(scanToAscii_table) / (8 * 4);
if(press_key == 0xE0)
{
switch(key)
{
case 0x48:
key_code = ZLOX_MKK_CURSOR_UP_PRESS;
break;
case 0x50:
key_code = ZLOX_MKK_CURSOR_DOWN_PRESS;
break;
case 0x4B:
key_code = ZLOX_MKK_CURSOR_LEFT_PRESS;
break;
case 0x4D:
key_code = ZLOX_MKK_CURSOR_RIGHT_PRESS;
break;
default:
key_code = 0;
break;
}
press_key = 0;
}
else if(key == 0xE0)
{
press_key = key;
}
..................................................
if(key_code != 0)
{
ZLOX_TASK_MSG ascii_msg = {0};
ascii_msg.type = ZLOX_MT_KEYBOARD;
ascii_msg.keyboard.type = ZLOX_MKT_KEY;
ascii_msg.keyboard.key = key_code;
zlox_send_tskmsg(input_focus_task,&ascii_msg);
}
..................................................
}
|
// shell.c -- 命令行程式
...................................................
char input_for_up[MAX_INPUT]={0};
char input_for_down[MAX_INPUT]={0};
...................................................
int main(VOID * task, int argc, char * argv[])
{
...................................................
switch(msg.keyboard.key)
{
case MKK_CURSOR_UP_PRESS:
if(strlen(input_for_up) == 0)
break;
strcpy(input_for_down, input);
replace_input(input,input_for_up,&count);
isinUp = TRUE;
break;
case MKK_CURSOR_DOWN_PRESS:
if(isinUp == TRUE)
{
replace_input(input,input_for_down,&count);
isinUp = FALSE;
}
break;
default:
break;
}
continue;
...................................................
}
|