www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - LDC 0.16.0 has been released!

reply Kai Nacke <kai redstar.de> writes:
Hi everyone!

On behalf of the LDC team I am proud to announce the final LDC 
0.16.0 release!
It is based on the 2.067.1 front-end and LLVM 3.1-3.7 (OS X: no 
support for 3.3).

The LDC team considers this the best LDC release of all times!

Big news is that the Win64 version of the compiler reaches 
production quality, thanks to the work from kinke!

This release has been checked to work on Linux/PPC64 and 
OpenSolaris (x86), too. There is still a major issue on FreeBSD 
(x86_64) (issue #1119).
Due to a library build problem with druntime/Phobos there is 
currently no MinGW32 version (issue #1121). This is currently 
under investigation but we are also looking for volunteers. If 
you need this platform please consider helping us!!!

Big thanks to everyone who provided feedback!

Most important changes are:

- Frontend is now at 2.067.1
- LLVM 3.7 is supported
- DMD-style coverage analysis is added
- ABI changes which fixes a lot of bugs in the Win64 compiler
- The ldc2 driver now only use slow -debuglib libraries if 
explicitly asked to

Be sure to read the change log at the GitHub release page which 
also has the package download links:
https://github.com/ldc-developers/ldc/releases/tag/v0.16.0

MD5 checksums for the release packages:

b8397cd1071315ad7612efc80c6844fc ldc-0.16.0-src.tar.gz
177a637431f6e5ee0ccebd5911d4baed ldc2-0.16.0-linux-x86.tar.gz
7ff847175bb442fd7682d748abb23072 ldc2-0.16.0-linux-x86.tar.xz
b233210beef30483de08fec53536aa1e ldc2-0.16.0-linux-x86_64.tar.gz
4cf2316d581560d694b753026e8185e5 ldc2-0.16.0-linux-x86_64.tar.xz
b6395ce58ef3803c53beae60bfc75176 ldc2-0.16.0-osx-x86_64.tar.gz
cf411c9309913dada376ee9d630d8d1b ldc2-0.16.0-osx-x86_64.tar.xz
89f18774ba0c5c804a9b86b1097e505d ldc2-0.16.0-win64-msvc.zip

Regarding the binaries:
The Linux binaries are built on Ubuntu 12.04 LTS with gcc 4.8.x 
and LLVM 3.7.0. They work on Ubuntu 12.04 LTS (or later) without 
installing additional software.

The OS X binaries are built with LLVM 3.6.2 on OS X 10.10.

The Win64 MSVC version is built with VS2015 using LLVM 3.7 in 
release mode. The distribution now contains a precompiled libcurl 
7.40.0 from http://d.darktech.org/libcurl.html. For any other 
VisualStudio version you need to rebuild the library.
You find the build script here: 
https://github.com/ldc-developers/ldc-scripts/blob/master/ldc2-win64/RELEASE.proj

Please be sure to report any bugs at 
https://github.com/ldc-developers/ldc/issues, and feel free to 
drop by at the digitalmars.D.ldc forums 
(http://forum.dlang.org/group/digitalmars.D.ldc) for any 
questions or comments.

Thanks to everybody involved in making this happen!

Regards,
Kai
Oct 22 2015
next sibling parent Daniel N <ufo orbiting.us> writes:
On Thursday, 22 October 2015 at 18:58:29 UTC, Kai Nacke wrote:
 Thanks to everybody involved in making this happen!

 Regards,
 Kai
Thanks and congratulations for this epic release!
Oct 22 2015
prev sibling next sibling parent reply kinke <noone nowhere.com> writes:
Uh, the release still contains the VS detection bug on Win64 etc. 
I think the current head of branch master would be ideal for 0.16.
Oct 22 2015
parent Kai Nacke <kai redstar.de> writes:
On Thursday, 22 October 2015 at 22:13:23 UTC, kinke wrote:
 Uh, the release still contains the VS detection bug on Win64 
 etc. I think the current head of branch master would be ideal 
 for 0.16.
I can create a .1 release if needed. Regards, Kai
Oct 24 2015
prev sibling next sibling parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
Congratulations and thanks to the LDC team!

Available on openSUSE:
http://download.opensuse.org/repositories/devel:/languages:/D/
Oct 24 2015
prev sibling parent reply guodemone <704975494 qq.com> writes:
sorry ,my english is poor!):

I want to build the x86 bootloader with Dlang,but how to build.

I have ucore os code(asm+C),I want ucore (asm+C) to (asm+D).

help me,thank you.

https://github.com/chyyuu, help me, ucore(asm+c) to (asm+D).
Oct 25 2015
parent reply David Nadlinger via digitalmars-d-ldc <digitalmars-d-ldc puremagic.com> writes:
Hi there,

On 25 Oct 2015, at 16:08, guodemone via digitalmars-d-ldc wrote:
 I want to build the x86 bootloader with Dlang,but how to build.

 I have ucore os code(asm+C),I want ucore (asm+C) to (asm+D).

 help me,thank you.
I'm afraid this question is a little too unspecific for us to be able to help you efficiently. Where exactly do you get stuck? You might want to have a look at the old https://github.com/xomboverlord/xomb project for inspiration (an exokernel written in D1), or Adam Ruppe's more recent experiments: http://arsdnet.net/dcode/minimal.zip Best, David
Oct 25 2015
next sibling parent reply guodemone <704975494 qq.com> writes:
thank you.

what your email? I have bootloader source send to you.

you look the source.
Oct 25 2015
next sibling parent guodemone <704975494 qq.com> writes:
I understand sent source to you,how
Oct 25 2015
prev sibling parent reply David Nadlinger via digitalmars-d-ldc <digitalmars-d-ldc puremagic.com> writes:
On 25 Oct 2015, at 16:19, guodemone via digitalmars-d-ldc wrote:
 thank you.

 what your email? I have bootloader source send to you.

 you look the source.
I'm afraid I don't quite have the time to spend on that right now. I would say your best bet is to work on the problem some more yourself until you get to the point where you can articulate a concrete question. — David
Oct 25 2015
parent reply guodemone <704975494 qq.com> writes:
#ifndef __BOOT_ASM_H__
#define __BOOT_ASM_H__

/* Assembler macros to create x86 segments */

/* Normal segment */
#define SEG_NULLASM												\
	.word 0, 0;													\
	.byte 0, 0, 0, 0

#define SEG_ASM(type,base,lim)									\
	.word (((lim) >> 12) & 0xffff), ((base) & 0xffff);			\
	.byte (((base) >> 16) & 0xff), (0x90 | (type)),				\
		(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)


/* Application segment type bits */
#define STA_X		0x8		
#define STA_E		0x4		
#define STA_C		0x4		
#define STA_W		0x2		
#define STA_R		0x2		
#define STA_A		0x1		

#endif /* !__BOOT_ASM_H__ */

*****************************************

#include <asm.h>

# Start the CPU: switch to 32-bit protected mode, jump into C.
# The BIOS loads this code from the first sector of the hard disk 
into
# memory at physical address 0x7c00 and starts executing in real 
mode
# with %cs=0 %ip=7c00.

.set PROT_MODE_CSEG,		0x8						# kernel code segment selector
.set PROT_MODE_DSEG,		0x10					# kernel data segment selector
.set CR0_PE_ON,				0x1						# protected mode enable flag

.globl start
start:
.code16												# Assemble for 16-bit mode
	cli
	cld

	# Set up the important data segment registers (DS, ES, SS).
	xorw %ax, %ax									# Segment number zero
	movw %ax, %ds									# -> Data Segment
	movw %ax, %es									# -> Extra Segment
	movw %ax, %ss									# -> Stack Segment

seta20.1:
	inb $0x64, %al									# Wait for not busy
	testb $0x2, %al
	jnz seta20.1


	movb $0xd1, %al									# 0xd1 -> port 0x64
	outb %al, $0x64

seta20.2:
	inb $0x64, %al									# Wait for not busy
	testb $0x2, %al
	jnz seta20.2

	movb $0xdf, %al									# 0xdf -> port 0x60
	outb %al, $0x60

	lgdt gdtdesc

	movl %cr0, %eax
	orl $CR0_PE_ON, %eax
	movl %eax, %cr0

	ljmp $PROT_MODE_CSEG, $protcseg

.code32												# Assemble for 32-bit mode
protcseg:
	movw $PROT_MODE_DSEG, %ax						
	movw %ax, %ds									# -> DS: Data Segment
	movw %ax, %es									# -> ES: Extra Segment
	movw %ax, %fs									# -> FS
	movw %ax, %gs									# -> GS
	movw %ax, %ss									# -> SS: Stack Segment

	movl $0x0, %ebp
	movl $start, %esp
	call bootmain
spin:
	jmp spin

.p2align 2

gdt:
	SEG_NULLASM
	SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)
	SEG_ASM(STA_W, 0x0, 0xffffffff)

gdtdesc:
	.word 0x17
	.long gdt

****************************************



module bootmain;



import types;

import x86;





const COM1 = 0x3F8;

const CRTPORT = 0x3D4;

const LPTPORT = 0x378;

const COM_TX = 0;

const COM_LSR = 5;

const COM_LSR_TXRDY = 20;



extern (C){

  uint8_t  inb(uint16_t port);

  void outb(uint16_t port, uint8_t data);

  uint16_t *crt;		// CGA memory

}



static this(){

      uint16_t *crt = cast(uint16_t *)0xB8000;

}



/* stupid I/O delay routine necessitated by historical PC design 
flaws */

static void

delay() {

	inb(0x84);

	inb(0x84);

	inb(0x84);

	inb(0x84);

}



/* lpt_putc - copy console output to parallel port */

static void

lpt_putc(int c) {

	int i;

	for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {

		delay();

	}

	outb(LPTPORT + 0, cast(uint8_t)c);

	outb(LPTPORT + 2, 0x08 | 0x04 | 0x01);

	outb(LPTPORT + 2, 0x08);

}



/* cga_putc - print character to console */

static void

cga_putc(int c) {

	int pos;



	// cursor position: col + 80*row.

	outb(CRTPORT, 14);

	pos = inb(CRTPORT + 1) << 8;

	outb(CRTPORT, 15);

	pos |= inb(CRTPORT + 1);



	if (c == '\n') {

		pos += 80 - pos % 80;

	}

	else {

		crt[pos ++] = (c & 0xff) | 0x0700;

	}



	outb(CRTPORT, 14);

	outb(CRTPORT + 1, cast(uint8_t)(pos >> 8));

	outb(CRTPORT, 15);

	outb(CRTPORT + 1, cast(uint8_t)pos);

}



/* serial_putc - copy console output to serial port */

static void

serial_putc(int c) {

     int i;

	for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; 
i ++) {

		delay();

	}

	outb(COM1 + COM_TX, cast(uint8_t)c);

}



/* cons_putc - print a single character to console*/

static void

cons_putc(int c) {

	lpt_putc(c);

	cga_putc(c);

	serial_putc(c);

}



/* cons_puts - print a string to console */

static void

cons_puts(const char *str) {

	int i;

	for (i = 0; *str != '\0'; i ++) {

		cons_putc(str[i]);

	}

}



/* bootmain - the entry of bootloader */

static void

bootmain() {

	cons_puts("This is a bootloader: Hello world!!");



	/* do nothing */

	while (true){}

}

****************************



module types;



extern (C):

alias int BOOL;



alias char int8_t;

//C     typedef unsigned char uint8_t;

alias ubyte uint8_t;

//C     typedef short int16_t;

alias short int16_t;

//C     typedef unsigned short uint16_t;

alias ushort uint16_t;

//C     typedef int int32_t;

alias int int32_t;

//C     typedef unsigned int uint32_t;

alias uint uint32_t;

//C     typedef long long int64_t;

alias long int64_t;

//C     typedef unsigned long long uint64_t;

alias ulong uint64_t;



********************************



module x86;



import types;



  extern (C){

  uint8_t  inb(uint16_t port);

  void outb(uint16_t port, uint8_t data);

  }



extern (C) uint8_t inb(uint16_t port) {

	uint8_t data;

	asm

	{

	    mov DX,port;

	    in  AL,DX;

		mov data,AL;

	}

	return data;

}



extern (C) void outb(uint16_t port, uint8_t data) {

	asm

	{

	    mov DX,port;

		mov AL,data;

		out DX,AL;

	}

}



*****************************


bootasm:bootasm.S asm.h
	rm obj\*.o -rf
	gcc -I. -fno-builtin -Wall -ggdb -m16 -nostdinc 
-fno-stack-protector -Os -nostdinc -c bootasm.S -o obj/bootasm.o
bootmain:bootmain.d types.d x86.d
	ldc2 -L=Os -c $^ -odobj
all:bootasm bootmain


******************************

bootblock:bootasm.o bootmain.o x86.o types.o
	ld -m elf_i386 -N -e start -Ttext 0x7C00 $^ -o bootblock.o
	objdump -S bootblock.o > bootblock.asm
	objcopy -S -O binary bootblock.o bootblock.out
	rm bootblock -f
	./writeHDD bootblock.out bootblock
	dd if=/dev/zero of=ucore.img count=10000
	dd if=bootblock of=ucore.img conv=notrunc
Oct 25 2015
parent reply guodemone <704975494 qq.com> writes:
ld -m elf_i386 -N -e start -Ttext 0x7C00 bootasm.o bootmain.o 
x86.o types.o -o bootblock.o
bootasm.o:在函数‘protcseg’中:
/home/glg/桌面/bootloader_D/bootasm.S:60:对‘bootmain’未定义的引用
bootmain.o:在函数‘ldc.dso_ctor.8bootmain’中:
bootmain.d:(.text.ldc.dso_ctor.8bootmain[ldc.dso_ctor.8bootmain]+0x4d):对‘_d_dso_registry’未定义的引用
bootmain.o:在函数‘ldc.dso_dtor’中:
bootmain.d:(.text.ldc.dso_dtor[ldc.dso_dtor]+0x4d):对‘_d_dso_registry’未定义的引用
x86.o:在函数‘ldc.dso_ctor.3x86’中:
x86.d:(.text.ldc.dso_ctor.3x86[ldc.dso_ctor.3x86]+0x4d):对‘_d_dso_registry’未定义的引用
types.o:在函数‘ldc.dso_ctor.5types’中:
types.d:(.text.ldc.dso_ctor.5types[ldc.dso_ctor.5types]+0x4d):对‘_d_dso_registry’未定义的引用
makefile:2: recipe for target 'bootblock' failed
make: *** [bootblock] Error 1
Oct 25 2015
next sibling parent guodemone <704975494 qq.com> writes:
I need excample bootloader(asm+D).
(dmd,gdc,ldc build flag)
(linker flag)
to now,D no have bootloader(asm+D).
Oct 25 2015
prev sibling parent reply Kagamin <spam here.lot> writes:
It's a missing function _d_dso_registry. Not sure if you need it 
or not, but you can stub it:
extern(C) void _d_dso_registry(void* data) { }

Also don't use static constructors yet. They are invoked during 
initialization of modules, which you probably don't run.
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
How build .bin?

eg.

ldc -c bootmain.d of bin
Oct 26 2015
parent reply Kagamin <spam here.lot> writes:
You mean a CD image with your loader in MBR?
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
file asm.h

/*
是bootasm.S汇编文件所需要的头文件,主要是一些与X86保护模式的段访问方式相关的宏定义
*/

#ifndef __BOOT_ASM_H__
#define __BOOT_ASM_H__

/* Assembler macros to create x86 segments */

/* Normal segment */
#define SEG_NULLASM												\
	.word 0, 0;													\
	.byte 0, 0, 0, 0

#define SEG_ASM(type,base,lim)									\
	.word (((lim) >> 12) & 0xffff), ((base) & 0xffff);			\
	.byte (((base) >> 16) & 0xff), (0x90 | (type)),				\
		(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)


/* Application segment type bits */
#define STA_X		0x8		// 可执行
#define STA_E		0x4		// 向下扩展段(非可执行段)
#define STA_C		0x4		// 一致性代码段(只执行)
#define STA_W		0x2		// 段可写(非可执行段)
#define STA_R		0x2		// 段可读 (可执行段)
#define STA_A		0x1		// 可访问

#endif /* !__BOOT_ASM_H__ */

**********************************************************
file bootasm.S

# 定义并实现了bootloader最先执行的函数start,此函数进行了一定的初始化,完成了
# 从实模式到保护模式的转换,并调用bootmain.c中的bootmain函数

#include <asm.h>

# Start the CPU: switch to 32-bit protected mode, jump into C.
# The BIOS loads this code from the first sector of the hard disk 
into
# memory at physical address 0x7c00 and starts executing in real 
mode
# with %cs=0 %ip=7c00.

# gdt 全局描述符表内的数组索引
.set PROT_MODE_CSEG,		0x8						# kernel code segment selector
.set PROT_MODE_DSEG,		0x10					# kernel data segment selector
.set CR0_PE_ON,				0x1						# protected mode enable flag

.globl start
start:
.code16												# Assemble for 16-bit mode
	cli												# 禁用中断
	cld												# 字符串操作设定为递增 si++ di++
,cld的作用是将direct flag标志位清零

	# Set up the important data segment registers (DS, ES, SS).
	xorw %ax, %ax									# Segment number zero
	movw %ax, %ds									# -> Data Segment
	movw %ax, %es									# -> Extra Segment
	movw %ax, %ss									# -> Stack Segment

	# A20地址线控制打开工作
	# Enable A20:
	# 为了向后兼容早期的PC机,让物理地址线20接低电平
	# 如果A20是关闭的,16bit的寻址范围2^20是1M,如果是打开的,那么就是2^21次方,
	# 但是寻址还是FFFFh:FFFFh=FFFF0h+FFFFh=10FFEFh=1M+64K-16Bytes
seta20.1:
	inb $0x64, %al									# Wait for not busy
	testb $0x2, %al
	jnz seta20.1      #测试 bit 1
是不是为0,如果不是跳回去继续执行

	# 对于键盘的8042控制芯片 0x64是命令端口 0xd1 代表写命令
	movb $0xd1, %al									# 0xd1 -> port 0x64
	outb %al, $0x64

seta20.2:
	inb $0x64, %al									# Wait for not busy
	testb $0x2, %al
	jnz seta20.2

	# 设置写命令后 给0x60端口
发送命令数据0xdf就是打开A20地址线,0xdd就是关闭
	movb $0xdf, %al									# 0xdf -> port 0x60
	outb %al, $0x60

	# 转入保护模式,这里需要指定一个临时的GDT,来翻译逻辑地址。
	# 这里使用的GDT通过gdtdesc段定义,它翻译得到的物理地址和虚拟地址相同,
	# 所以转换过程中内存映射不会改变
	lgdt gdtdesc									#
启动保护模式前建立好的段描述符合段描述符表
	
	# 打开保护模式标志位,相当于按下了保护模式的开关。
	# cr0寄存器的第0位就是这个开关,通过CR0_PE_ON或cr0寄存器,将第0位置1
	movl %cr0, %eax
	orl $CR0_PE_ON, %eax
	movl %eax, %cr0

	# 由于上面的代码已经打开了保护模式了,所以这里要使用逻辑地址,
	# 而不是之前实模式的地址了。这里用到了PROT_MODE_CSEG,
	# 他的值是0x8。根据段选择子的格式定义,0x8就翻译成:
  #      INDEX         TI     CPL
  #      0000 0000 0000 1          00      0
     # INDEX代表GDT中的索引,TI代表使用GDTR中的GDT,
CPL代表处于特权级。
	# PROT_MODE_CSEG选择子选择了GDT中的第1个段描述符。
	# 这里使用的gdt就是变量gdt,下面可以看到gdt的第1个段描述符的基地址是0x0000,
	# 所以经过映射后和转换前的内存映射的物理地址一样。
000:7C00=0x00007C00 0000:protcseg 
都是相对于物理内存0000基址的
	ljmp $PROT_MODE_CSEG, $protcseg

.code32												# Assemble for 32-bit mode
protcseg:
	# 重新初始化各个段寄存器。也就是采用平坦式内存方式,
	# 代码段同其它段都采用一个内存空间
	movw $PROT_MODE_DSEG, %ax						#
自定义数据段选择子,因为段选择子是16位的
	movw %ax, %ds									# -> DS: Data Segment
	movw %ax, %es									# -> ES: Extra Segment
	movw %ax, %fs									# -> FS
	movw %ax, %gs									# -> GS
	movw %ax, %ss									# -> SS: Stack Segment

	# 栈顶设定在start处,也就是地址0x7c00处,        # 低地址
0x0000    ^  此地址为栈基址 
0000
	# call函数将返回地址入栈,将控制权交给bootmain   #            
    /|\
	movl $0x0, %ebp                                  #               
    |
	movl $start, %esp                                #               
    |
	call bootmain                                    # 地址   0x7C00   
  |  栈顶指针

	# bootmain 如果返回,就会在此处死循环,但是目前的bootmain的函数不会返回了,因为他内部就会死循环
spin:
	jmp spin

# 注意以下数据结构
# Bootstrap GDT
.p2align 2											# 调整为4字节对齐
# 3个段描述符,每个段描述符占8字节,共24字节
# gdtdesc指出了全局描述符表(可以看成是段描述符组成的一个数组)的起始位置在gdt符号处,
# 而gdt符号处放置了三个段描述符的信息

# 第一个是NULL段描述符,没有意义,表示全局描述符表的开始
# 紧接着是代码段描述符(位于全局描述符表的0x8处的位置),具有可读(STA_R)和可执行(STA_X)的属性,
#   并且段起始地址为0,段大小为4GB;
# 接下来是数据段描述符(位于全局描述符表的0x10处的位置),具有可读(STA_R)和可写(STA_W)的属性,
#   并且段起始地址为0,段大小为4GB。
gdt:
	SEG_NULLASM										# null seg NULL段
	SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)			# code seg for 
bootloader and kernel CODE段
	SEG_ASM(STA_W, 0x0, 0xffffffff)					# data seg for bootloader 
and kernel DATA段

gdtdesc:
	.word 0x17										# sizeof(gdt) - 1 类似于数组
数组是0开始的,所以数组长度就要减1
	.long gdt										# address gdt

*****************************************************************************
file bootmain.c

/*
定义并实现了bootmain函数实现了通过屏幕、串口和并口显示字符串
*/

//#include <types.h>
//#include <x86.h>

#define COM1			0x3F8
#define CRTPORT			0x3D4
#define LPTPORT			0x378
#define COM_TX			0			// Out: Transmit buffer (DLAB=0)
#define COM_LSR			5			// In:  Line Status Register
#define COM_LSR_TXRDY	20			// Transmit buffer avail

static uint16_t *crt = (uint16_t *) 0xB8000;		// CGA memory

/* stupid I/O delay routine necessitated by historical PC design 
flaws */
static void
delay(void) {
	inb(0x84);
	inb(0x84);
	inb(0x84);
	inb(0x84);
}

/*
考虑到简单性,在proj1中没有对并口设备进行初始化,通过并口进行输出的过程也很简单:
第一步:执行inb指令读取并口的I/O地址(LPTPORT +
1)的值,如果发现发现读出的值代表并口忙,
则空转一小会再读;
如果发现发现读出的值代表并口空闲,则执行outb指令把字符写到并口
I/O地址(LPTPORT ),
这样就完成了一个字符的并口输出。
*/
/* lpt_putc - copy console output to parallel port */
static void
lpt_putc(int c) {
	int i;
	for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
		delay();
	}
	outb(LPTPORT + 0, c);
	outb(LPTPORT + 2, 0x08 | 0x04 | 0x01);
	outb(LPTPORT + 2, 0x08);
}

/*
通过CGA显示控制器进行输出的过程也很简单:首先通过in/out指令获取当前光标位置;
然后根据得到的位置计算出显存的地址,直接通过访存指令写内存来完成字符的输出;
最后通过in/out指令更新当前光标位置。
*/
/* cga_putc - print character to console */
static void
cga_putc(int c) {
	int pos;

	// cursor position: col + 80*row.
	outb(CRTPORT, 14);
	pos = inb(CRTPORT + 1) << 8;
	outb(CRTPORT, 15);
	pos |= inb(CRTPORT + 1);

	if (c == '\n') {
		pos += 80 - pos % 80;
	}
	else {
		crt[pos ++] = (c & 0xff) | 0x0700;
	}

	outb(CRTPORT, 14);
	outb(CRTPORT + 1, pos >> 8);
	outb(CRTPORT, 15);
	outb(CRTPORT + 1, pos);
}

/*
通过串口进行输出的过程也很简单:第一步:执行inb指令读取串
的I/O地址(COM1 + COM_LSR)的值,
如果发现发现读出的值代表串口忙,则空转一小会(0x84是什么地址???);
如果发现发现读出的值代表串口空闲,则执行outb指令把字符写到串
的I/O地址(COM1 + COM_TX),
这样就完成了一个字符的串口输出。
*/
/* serial_putc - copy console output to serial port */
static void
serial_putc(int c) {
     int i;
	for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; 
i ++) {
		delay();
	}
	outb(COM1 + COM_TX, c);
}

/* 显示字符的函数接口*/
/* 一个cons_putc函数接口,完成字符的输出*/
/* cons_putc - print a single character to console*/
static void
cons_putc(int c) {
	lpt_putc(c);
	cga_putc(c);
	serial_putc(c);
}

/* 提供了一个cons_puts函数接口:完成字符串的输出*/
/* cons_puts - print a string to console */
static void
cons_puts(const char *str) {
	int i;
	for (i = 0; *str != '\0'; i ++) {
		cons_putc(*str ++);
	}
}

/* bootmain - the entry of bootloader */
void
bootmain(void) {
	cons_puts("This is a bootloader: Hello world!!");

	/* do nothing */
	while (1);
}

***************************************************
These codes(asm.h bootasm.S bootmain.c) trans to (asm.h bootasm.S 
bootmain.d).

ldc -c asm.h bootasm.S bootmain.d

ld bootasm.o bootmain.o of outbin.o
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
bootloader of [asm+D] version
Oct 26 2015
next sibling parent reply Kagamin <spam here.lot> writes:
In C version you compile bootmain.c to object file bootmain.o, in 
d version you again get bootmain.o, after that you do the same as 
in C version.
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
wrong,Unable to link
Oct 26 2015
parent guodemone <704975494 qq.com> writes:
I want (asm.h bootasm.S bootmain.c) trans to (asm.h bootasm.S 
bootmanin.d)
Oct 26 2015
prev sibling parent reply kinke <noone nowhere.com> writes:
Guys, please *stop* hijacking this thread. It's supposed to be 
about the new release, and not about someone's project incl. code 
spam.
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
I know,but I need.
I want to new build OS with D.
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
sorry ,My englishi is poot.
My mean is good to D.
chinese people is Clever,But the language barrier,Which explains 
the significance of the error。
Oct 26 2015
parent reply guodemone <704975494 qq.com> writes:
google's tanslate into china,china to english.My idea was not to 
express
Oct 26 2015
parent guodemone <704975494 qq.com> writes:
Because,My poor(with English)。
I'd love to learn sign language,
Oct 26 2015
prev sibling next sibling parent guodemone <704975494 qq.com> writes:
On Sunday, 25 October 2015 at 15:14:32 UTC, David Nadlinger wrote:
 Hi there,

 On 25 Oct 2015, at 16:08, guodemone via digitalmars-d-ldc wrote:
 I want to build the x86 bootloader with Dlang,but how to build.

 I have ucore os code(asm+C),I want ucore (asm+C) to (asm+D).

 help me,thank you.
I'm afraid this question is a little too unspecific for us to be able to help you efficiently. Where exactly do you get stuck? You might want to have a look at the old https://github.com/xomboverlord/xomb project for inspiration (an exokernel written in D1), or Adam Ruppe's more recent experiments: http://arsdnet.net/dcode/minimal.zip Best, David
minimal this OS, I use cdrom to pack it up and running after TSS error, do not know how to solve.
Nov 08 2015
prev sibling parent guodemone <704975494 qq.com> writes:
On Sunday, 25 October 2015 at 15:14:32 UTC, David Nadlinger wrote:
 Hi there,

 On 25 Oct 2015, at 16:08, guodemone via digitalmars-d-ldc wrote:
 I want to build the x86 bootloader with Dlang,but how to build.

 I have ucore os code(asm+C),I want ucore (asm+C) to (asm+D).

 help me,thank you.
I'm afraid this question is a little too unspecific for us to be able to help you efficiently. Where exactly do you get stuck? You might want to have a look at the old https://github.com/xomboverlord/xomb project for inspiration (an exokernel written in D1), or Adam Ruppe's more recent experiments: http://arsdnet.net/dcode/minimal.zip Best, David
I holp build OS,Dlang give me my help.but,error jmp to it,no body help me. 我的英语实在不好[my english is poor] 我想知道的答案,没有办法得到解答【I want to know the answer, there is no way to get answers】
Nov 09 2015